fix(state): the deferred FTS rebuild retry is quarantined by the same rule as the checkpoints

retry_deferred_fts_recovery gated only on _db_corrupt ("mirrors _try_wal_checkpoint /
close") — after this PR it no longer mirrored them: on a replaced/lost-generation handle
the periodic housekeeping tick still ran FTS DDL/DML + commit, the same split-brain write
class as the #105670 checkpoint. One SessionDB._quarantine_reason() now decides for the
periodic checkpoint, close(), and the FTS retry, with the halt path's precedence
(replaced before generation loss) and the operator wording in one place.

Test: the periodic-checkpoint case folds into the close test (same setup), which now
also proves the FTS retry returns False without touching the file; the mutation with
main's schema sibling swapped in returns True (a rebuild ran).
This commit is contained in:
kshitijk4poor
2026-09-09 11:46:37 +05:30
committed by kshitij
parent ae94e349ac
commit f290946e4e
3 changed files with 27 additions and 44 deletions

View File

@@ -503,9 +503,10 @@ class SessionSchemaMixin:
"""
if not self._fts_stale:
return False
if getattr(self, "_db_corrupt", False):
# Quarantined: never run FTS DDL/DML against a damaged image (mirrors _try_wal_checkpoint /
# close). Reset the backoff so a future un-quarantine starts from the default interval.
if self._quarantine_reason() is not None:
# Quarantined: never run FTS DDL/DML against a damaged image or a stale/replaced generation
# (mirrors _try_wal_checkpoint / close). Reset the backoff so a future un-quarantine starts
# from the default interval.
self._fts_stale_retry_after = 0.0
self._fts_stale_retry_interval = 0.0
return False