Versions of sqlite 3.7.0 and newer store the size of the database image in the database file header. Earlier versions do not. When a new version writes to the db, it updates the database size field and sets a flag in the header to indicate that the last version to write the db updated the db size field. An earlier version does not update the db size field, but does clear the flag.
If the flag is set, SQLite trusts the db size field in the header. So if it is set incorrectly, the database is considered corrupt.
The current problem comes about as follows:
<ol>
<li>A 'new' version of sqlite writes to the database file, setting the db size field.
<li>An 'old' version of sqlite writes the db and changes the file size. This means the db size field is now invalid, but the flag is cleared so the db is not corrupt.
<li>A 'new' version of sqlite does a backup of the db. In the backup, the db size field remains unchanged, but the "written by a new version" flag is set. So the backup is now corrupted.
</ol>
Note: The "flag" mentioned above is not actually a flag, it is a second copy of the change counter that is only updated by post-3.7.0 versions of sqlite. The flag is considered set if that second copy matches the first.
|