feat(sessions): hermes sessions set-journal-mode delete|wal converts an existing WAL store offline (#100896)
`database.journal_mode: delete` can never self-apply to a store that is already WAL: apply_wal_with_fallback deliberately never live-downgrades (#68545 — other gateway/cron/worker connections may hold uncheckpointed WAL commits), so operators applying the containment for the multi-writer corruption class saw one ERROR per process forever and the only escape hatch was an undocumented hand-run PRAGMA on the file. The new pre-DB `sessions set-journal-mode` verb is the sanctioned offline path: it refuses while ANY foreign process holds the file or a sidecar (the same foreign_state_db_holders scan doctor/repair admission uses, naming each PID), flips through _set_journal_mode_no_wait (busy_timeout=0, so an opener appearing mid-way makes SQLite refuse instead of racing it), verifies header bytes 18/19, and reminds the operator when config.yaml disagrees. `--db PATH` covers kanban.db / cron stores that log the same ERROR. The never-live-downgrade invariant is untouched; the ERROR, doctor hints and docs now name the command instead of the raw PRAGMA.
This commit is contained in:
@@ -971,9 +971,15 @@ def _cmd_repair_profiles(args):
|
||||
return cmd_repair_profiles(args)
|
||||
|
||||
|
||||
def _cmd_set_journal_mode(args):
|
||||
from hermes_cli.sessions_cmd_journal_mode import cmd_set_journal_mode
|
||||
return cmd_set_journal_mode(args)
|
||||
|
||||
|
||||
_PRE_DB_HANDLERS = {
|
||||
"repair": _cmd_repair, "recover": _cmd_recover, "import": _cmd_import,
|
||||
"repair-profiles": _cmd_repair_profiles, # opens every profile's store itself
|
||||
"set-journal-mode": _cmd_set_journal_mode, # offline: must not open the store it converts
|
||||
}
|
||||
_OBSERVATIONAL_DB_ACTIONS = frozenset({"list", "stats", "pinned"})
|
||||
_DB_HANDLERS = {
|
||||
|
||||
Reference in New Issue
Block a user