fix(store): checkpoint WAL on close and startup to prevent orphan accumulation (#387)

Add WAL checkpoint on store close and after WAL-mode enable at startup.
This ensures graceful shutdown leaves a clean WAL, and crash recovery
merges stale WAL on next open. Both use PASSIVE mode (non-blocking,
no ftruncate). Best-effort — silently skip if concurrent reader holds
a lock.

Fixes #277

Co-authored-by: HC Cheng <hz.chang@pm.me>
This commit is contained in:
jjserenity
2026-05-30 17:54:52 +02:00
committed by GitHub
co-authored by HC Cheng
parent a5a3d1d60a
commit a6ad4011ed
+10
View File
@@ -340,6 +340,10 @@ static int configure_pragmas(cbm_store_t *s, bool in_memory) {
if (rc != CBM_STORE_OK) {
return rc;
}
/* Recover stale WAL from previous crash (best-effort).
* PASSIVE never blocks readers and never ftruncates.
* May fail with SQLITE_BUSY if another process holds a lock. */
(void)sqlite3_exec(s->db, "PRAGMA wal_checkpoint(PASSIVE)", NULL, NULL, NULL);
rc = exec_sql(s, "PRAGMA synchronous = NORMAL;");
if (rc != CBM_STORE_OK) {
return rc;
@@ -729,6 +733,12 @@ void cbm_store_close(cbm_store_t *s) {
return;
}
/* Checkpoint WAL before close to prevent orphan WAL accumulation.
* Best-effort — silently skips if concurrent reader holds a lock. */
if (s->db && s->db_path) {
(void)sqlite3_wal_checkpoint_v2(s->db, NULL, SQLITE_CHECKPOINT_PASSIVE, NULL, NULL);
}
/* Finalize all cached statements */
finalize_stmt(&s->stmt_upsert_node);
finalize_stmt(&s->stmt_find_node_by_id);