What guarantees SQLite provides for recovery after an interrupted schema upgrade?
0 reputation · 13 Aug 2022, 02:02 UTC
0 reputation · 13 Aug 2022, 02:02 UTC
Goal: ensure that a SQLite database can be returned to a consistent, usable state after a process crashes while a schema‑changing statement (e.g., ALTER TABLE, CREATE INDEX) is being committed.
SQLite relies on its rollback journal or Write‑Ahead Log (WAL) to undo partial writes, and the PRAGMA integrity_check procedure can verify B‑tree and index consistency after a disruptive event. However, it is unclear whether these mechanisms guarantee a full rollback of DDL changes, whether integrity_check can detect all corruptions without shutting down the database, and whether a concurrent VACUUM INTO operation can safely produce a clean copy while the journal or WAL files remain present.
Does the rollback journal/WAL guarantee that a partially applied ALTER TABLE is fully rolled back after a crash? Can PRAGMA integrity_check reliably detect corruption caused by an interrupted upgrade without requiring a shutdown? Is it safe to run VACUUM INTO on the main database file while the -wal and -shm files are present to obtain a clean copy for recovery?
SQLite's rollback journal and Write-Ahead Log (WAL) guarantee atomicity for a transaction, not for an entire upgrade script. A single ALTER TABLE or CREATE INDEX is wrapped in an implicit transaction if you do not issue BEGIN, so a crash during that statement rolls it back completely. If your upgrade consists of multiple schema statements without one explicit BEGIN...COMMIT block, each statement commits independently, and a crash can leave the database partially upgraded.
PRAGMA integrity_check;
PRAGMA wal_checkpoint(TRUNCATE);
VACUUM INTO '/path/to/recovery.db';
Run PRAGMA integrity_check on recovery.db and confirm it also returns ok before replacing the original.
Was the schema upgrade executed as a single explicit transaction, or as multiple autocommitted statements? This changes whether partial DDL can remain after a crash and whether a full restore is required.
Assumptions: standard SQLite 3.x, default rollback journal or WAL mode, no custom VFS, and VACUUM INTO available (SQLite 3.27.0 or later). Behavior on a corrupted filesystem or with hardware write reordering is outside SQLite's guarantees.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.