View Ticket
Make sure the change-counter and SQLite-version fields of the header are set correctly even after vacuuming. This is a backport of changes [0be92a7576] and [04fa1e1690] to address ticket [5d863f876ee]. (check-in: 442be135 user: drh tags: branch-3.7.4)
14:33 Fixed ticket [5d863f87]: DB corruption following rollback-WAL-VACUUM-rollback plus 1 other change (artifact: df996354 user: drh)
18:36 Ticket [5d863f87]: 3 changes (artifact: 97c044e2 user: drh)
Make sure the change-counter and SQLite-version fields of the header are set correctly even when doing a VACUUM with locking_mode=EXCLUSIVE. Ticket [5d863f876ee9561b]. (check-in: 04fa1e16 user: drh tags: trunk)
Make sure the change counter and SQLite version numbers in the header are set correctly, even when running in WAL mode and when VACUUMing in WAL mode. Ticket [5d863f876ee9561b9]. (check-in: 0be92a75 user: drh tags: trunk)
Fix the change-counter increment for WAL pages so that it works even when invoked from xStress. Ticket [5d863f876ee9561b95e2]. (Closed-Leaf check-in: 228e7c34 user: drh tags: bug-5d863f87)
Increment the change counter and update the SQLite version number whenever page 1 is added to the WAL. Ticket [5d863f876ee9561b9] (check-in: c1e0d09c user: drh tags: bug-5d863f87)
Add a test case demonstrating the problem described by ticket [5d863f876e]. (check-in: af54963f user: dan tags: trunk)
16:42 New ticket [5d863f87] DB corruption following rollback-WAL-VACUUM-rollback. (artifact: bb4c01f9 user: drh)

Ticket Hash: 5d863f876ee9561b95e279b3381450514b6da668
Title: DB corruption following rollback-WAL-VACUUM-rollback
Status: Fixed Type: Code_Defect
Severity: Critical Priority: Immediate
Subsystem: Unknown Resolution: Fixed
Last Modified: 2011-01-27 14:33:00
Version Found In: 3.7.4
An obscure method for corrupting databases has been discovered, involving transitions between rollback journaling modes and WAL mode, with a VACUUM thrown in the middle. The crux of the problem is that the change-counter field at offset 24 in the database file was being reset to zero by the sequence of commands:
    PRAGMA journal_mode=WAL;
    PRAGMA journal_mode=DELETE;

The change-counter is used by database connections in rollback mode to detect when other database connections have modified the database, so that they can reset their caches. (Other mechanisms are used in WAL mode.)

So if the change counter is initially zero (perhaps due to having previously run the command sequence shown above) and two database connections are hooked to the database in rollback mode and one connection modifies the database and then does the sequence of commands above, the other database connection will not notice the change and will hence perform subsequent operations using a stale cache. This can lead to database corruption.

This malfunction was discovered during testing and has not been observed in the wild.