View Ticket
Backport the [65b8636ac6e5] fix for ticket [51ae9cad317a1] to version 3.7.0. (check-in: dec70c63 user: drh tags: branch-3.7.0)
11:40 Ticket [51ae9cad] Database corruption by alternating writes from 3.7.0 and 3.6.23 status still Fixed with 1 other change (artifact: 19099f9f user: dan)
11:39 Fixed ticket [51ae9cad]. (artifact: 26a33213 user: dan)
11:39 Ticket [51ae9cad]: 3 changes (artifact: 93da284a user: dan)
When opening a write-transaction on a database file that has been appended to or truncated by a pre-3.7.0 client, update the database-size field in the database header. Fix for [51ae9cad31]. (check-in: 65b8636a user: dan tags: trunk)
11:30 New ticket [51ae9cad] Database corruption by alternating writes from 3.7.0 and 3.6.23. (artifact: 254d411d user: drh)

Ticket Hash: 51ae9cad317a1b609735f99c88168bbf3661feb7
Title: Database corruption by alternating writes from 3.7.0 and 3.6.23
Status: Fixed Type: Code_Defect
Severity: Critical Priority: Immediate
Subsystem: B-Tree Resolution: Fixed
Last Modified: 2010-08-04 11:40:07
Version Found In: 3.7.0
If the same database file is alternately written by SQLite version 3.7.0 and version (or earlier), database corruption can occur. The failure scenario is this:
  1. The database is created and initially populated using version 3.7.0.
  2. Version adds content, causing the size of the database to increase.
  3. Version 3.7.0 updates the database without increasing its size

The corrupt is that the in-header-size field at offset 28 into the header ends up being set incorrectly. This field was always zero for SQLite versions and earlier; it was introduced for the first time in version 3.7.0. Version 3.7.0 knows to only use the in-header-size if the change-counter at offset 24 matches the change-counter-copy at offset 92. And so normally, and 3.7.0 can interact without problems. Step 2 in the failure scenario above causes the in-header-size field to be set incorrectly (because changes the size of the database but does not update the in-header-size field). The database is still valid after step 2, though, since the change-counter-copy at offset 92 no longer matches the change-counter at offset 28. However, step 3 updates both the change-counter and change-counter-copy without correcting the in-header-size, resulting in database corruption.

dan added on 2010-08-04 11:39:07:
Fixed by commit [65b8636ac6].