July 6, 2026·4 min read·engineeringrqlitecdcreliability

rqlite 10.2.7 keeps the oldest pending CDC event after restart

A CDC restart fix gives rqlite 10.2.7 a concrete reliability story. The maintenance release also repairs identifier handling and closes resources on error paths.

The oldest event in a persistent queue is not necessarily an event already delivered. rqlite 10.2.7 fixes a restart path that initialized its CDC high-water mark to the first queued key. The sending loop skipped events at or below that mark, so the first pending event could disappear from delivery after restart.

The 10.2.7 release was published July 6. Its tagged changelog dates the version July 5 and lists database handling, resource lifecycle and shutdown repairs. The CDC change in pull request #2713 merged July 6 shortly before publication, adding a specific example of why a routine maintenance release matters.

The database can preserve its state while a downstream consumer misses a change notification. That is why this fix deserves attention separately from claims about replicated database availability. It concerns what the CDC service delivers when it resumes from its persistent queue.

The restart boundary was off by one

The patch reads the queue's first key and subtracts one when the value is greater than zero before storing the initial high-water mark. The accompanying comment says queued events should be assumed unsent to preserve the at-least-once guarantee. An update from another cluster node may subsequently advance the mark and prune the queue.

This change makes the meaning of the mark consistent with the sending loop. The loop skips events whose index is less than or equal to the recorded watermark. Initializing that watermark immediately before the oldest pending key allows the oldest event to be considered for delivery.

The regression test makes the scenario concrete. It preloads the persistent FIFO with undelivered events at indices 5, 6 and 7, then starts a fresh service over the same queue and makes it leader. The test requires every seeded index to reach the webhook, including index 5.

That test checks the missing event directly. It does not claim that every restart will produce no duplicate deliveries, nor should an at-least-once contract be read as such a claim. The repaired initialization favors preserving an event whose delivery has not been established. It removes the documented skip of the oldest queued event.

I value rqlite's limited operational demands and its explicit treatment of consistency. CDC introduces another promise alongside database reads and writes. A persisted event queue is useful only if restart logic interprets its position consistently with the delivery loop, which is the precise relationship this patch repairs.

Database metadata handling gets a concrete correction

The database-layer changes include pull request #2706. It corrects double-quote escaping in ColumnNames and TableColumnTypes. The old replacement inserted backslashes before doubled quotes, while the new code doubles the quotes themselves when constructing quoted SQL identifiers.

Tests add table names that contain quotes and verify that metadata lookup still works. One test creates a table whose name includes a quoted word, then passes its actual name to ColumnNames. Another checks declared column types for a similarly quoted table name. These cases exercise schema handling that ordinary identifier names would not expose.

The same patch changes the SQLite-file header read to io.ReadFull for the expected 16 bytes. That makes the operation require the complete header buffer. It is a small example of the broader maintenance theme, making the code's actual success condition match the data it needs.

Resource cleanup includes failures during setup

Pull request #2707 adds cleanup of database handles if OpenWithDriver returns an error after opening them. Successful construction transfers those resources to the returned database object. Failed construction now closes handles that otherwise had no successfully constructed owner.

The patch also closes a connection used for extension validation and ensures a database opened for checkpoint removal is closed. In extension file copying, it returns the destination close error. A completed copy operation can therefore report a failure that occurs while closing the output, instead of unconditionally returning success after copying bytes.

These are local lifecycle repairs. The changelog does not report measured reductions in memory use or a named production incident, so there is no basis for assigning those outcomes to the release. The source establishes improved ownership and error reporting on identifiable paths.

Maintenance work changes failure behavior

Another entry avoids running snapshot CRC checks twice when fast restart is explicitly disabled. The patch adds a verification method that caches the verification state and uses it during store opening. That preserves the integrity check while avoiding the repeated work identified by the release note.

The HTTP changes include SQL rewriting control, and the CDC patch also makes retry waiting responsive to shutdown. These repairs concern what happens around ordinary requests and background delivery when conditions change. They are useful details in a release whose headline contains no new database capability.

My interest in this update is the precision of the fixes. The CDC test asks whether the oldest pending event survives restart. The metadata tests ask whether quoted table names can be inspected. Those are concrete behaviors that users can depend on, and 10.2.7 repairs them without asking the application to adopt a new interface.