SQLite
View Ticket
Not logged in
Ticket UUID: 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
Description:
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:

<pre>
    PRAGMA journal_mode=WAL;
    VACUUM;
    PRAGMA journal_mode=DELETE;
</pre>

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.