fix(state): VACUUM is gated by the same quarantine rule as the checkpoints

Follow-up to #106315. vacuum() ran PRAGMA wal_checkpoint + VACUUM + wal_checkpoint(TRUNCATE) on
self._conn with no quarantine check; the only guard it inherited (optimize_fts raising
DeletedWalGenerationError) was swallowed by its own try/except and the rewrite proceeded on the
split-brain handle. Mutation on main: vacuum() returned 2 and rewrote pages after the write stop.
This commit is contained in:
kshitijk4poor
2026-09-09 13:01:10 +05:30
committed by kshitij
parent b530a482d8
commit bb2c961e9a
2 changed files with 12 additions and 3 deletions

View File

@@ -336,7 +336,14 @@ class SessionMaintenanceMixin:
"""VACUUM to reclaim space after large deletes (SQLite never shrinks on its own).
Takes an exclusive lock — callers must ensure no other writers are active. FTS5
segments are merged first (:meth:`optimize_fts`) so their pages are reclaimed too;
returns the number of FTS indexes optimized (0 on merge failure / no FTS)."""
returns the number of FTS indexes optimized (0 on merge failure / no FTS). A quarantined
handle (corrupt image, replaced file, lost WAL generation) never checkpoints or rewrites
pages: the halt raised by ``optimize_fts`` would otherwise be swallowed below and the
VACUUM would proceed on the split-brain handle (#105670)."""
quarantine_reason = self._quarantine_reason()
if quarantine_reason is not None:
logger.warning("Skipping VACUUM for %s: this handle observed %s.", self.db_path, quarantine_reason)
return 0
optimized = 0
try:
optimized = self.optimize_fts() # manages its own lock