-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
-C Do\snot\sraise\san\sSQLITE_CORRUPT\serror\sin\sRecoverymode\sif\sthe\sdatabase\ssize\nin\sthe\sheader\sis\slarger\sthan\sthe\sphysical\sfile\ssize.\s\sThis\sis\sa\scherrypick\nof\scheckin\s[114640d920e16c8]
-D 2011-02-20T03:27:52.324
+C Make\ssure\sthe\schange-counter\sand\sSQLite-version\sfields\sof\sthe\sheader\sare\nset\scorrectly\seven\safter\svacuuming.\s\sThis\sis\sa\sbackport\sof\schanges\n[0be92a7576]\sand\s[04fa1e1690]\sto\saddress\sticket\s[5de63f876cc].
+D 2011-02-20T03:32:54.731
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 4547616ad2286053af6ccccefa242dc925e49bf0
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
F src/os_unix.c 0240c5b547b4cf585c8cac351a95c3e85ce00772
F src/os_win.c 2f90f7bdec714fad51cd31b4ecad3cc1b4bb5aad
-F src/pager.c c0aca5c733c15a16fe158c3215d857841a4e5381
+F src/pager.c 5b2210b4307c626a3b3ed7312161ec533958c094
F src/pager.h 0ea59db2a33bc6c2c02cae34de33367e1effdf76
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa
F test/eqp.test 69670e7919030f21de29fb99bf1d68f97aedcbdb
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
F test/exclusive.test 53e1841b422e554cecf0160f937c473d6d0e3062
-F test/exclusive2.test 76e63c05349cb70d09d60b99d2ae625525ff5155
+F test/exclusive2.test c2f2b2242dc436a12df8dd531e06843053bd3b9a
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/expr.test 620a636cf7b7d4e5834a0b9d83a4da372e24a7b7
F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 29597a71d0848cd5faeb68b606a9127910c8dc57
-R 4765ab892066a2cf596b52ac188daaa7
+P 7701b07759d63537408a68bac85cb1b8b27160b7
+R 1af9cda1d47f108dd79a57e892ab3d60
U drh
-Z 0fd913631bd65c1d6b88eece64aed780
+Z d17b6d73dc0e258c19674947beb8c07b
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
-iD8DBQFNYIo8oxKgR168RlERAtxOAJ0W2UlkzgKSsQgJHB8/MuaurrnAOACeIEqH
-2d5x+c+4cCHEyAOLiV5KRVk=
-=mpQI
+iD8DBQFNYItqoxKgR168RlERAkvGAJ456/IGVD5IaXa+SVUvWNJiAFQjWwCdEmc5
+sY0984PvfU6Cksq4hCEZCN0=
+=PbW4
-----END PGP SIGNATURE-----
return rc;
}
+
+/*
+** Update the value of the change-counter at offsets 24 and 92 in
+** the header and the sqlite version number at offset 96.
+**
+** This is an unconditional update. See also the pager_incr_changecounter()
+** routine which only updates the change-counter if the update is actually
+** needed, as determined by the pPager->changeCountDone state variable.
+*/
+static void pager_write_changecounter(PgHdr *pPg){
+ u32 change_counter;
+
+ /* Increment the value just read and write it back to byte 24. */
+ change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1;
+ put32bits(((char*)pPg->pData)+24, change_counter);
+
+ /* Also store the SQLite version number in bytes 96..99 and in
+ ** bytes 92..95 store the change counter for which the version number
+ ** is valid. */
+ put32bits(((char*)pPg->pData)+92, change_counter);
+ put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER);
+}
+
/*
** This function is a wrapper around sqlite3WalFrames(). As well as logging
** the contents of the list of pages headed by pList (connected by pDirty),
** this function notifies any active backup processes that the pages have
-** changed.
+** changed.
+**
+** The list of pages passed into this routine is always sorted by page number.
+** Hence, if page 1 appears anywhere on the list, it will be the first page.
*/
static int pagerWalFrames(
Pager *pPager, /* Pager object */
int syncFlags /* Flags to pass to OsSync() (or 0) */
){
int rc; /* Return code */
+#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
+ PgHdr *p; /* For looping over pages */
+#endif
assert( pPager->pWal );
+#ifdef SQLITE_DEBUG
+ /* Verify that the page list is in accending order */
+ for(p=pList; p && p->pDirty; p=p->pDirty){
+ assert( p->pgno < p->pDirty->pgno );
+ }
+#endif
+
+ if( pList->pgno==1 ) pager_write_changecounter(pList);
rc = sqlite3WalFrames(pPager->pWal,
pPager->pageSize, pList, nTruncate, isCommit, syncFlags
);
}
#ifdef SQLITE_CHECK_PAGES
- {
- PgHdr *p;
- for(p=pList; p; p=p->pDirty) pager_set_pagehash(p);
+ for(p=pList; p; p=p->pDirty){
+ pager_set_pagehash(p);
}
#endif
char *pData; /* Data to write */
assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
+ if( pList->pgno==1 ) pager_write_changecounter(pList);
/* Encode the database */
CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
/*
** This routine is called to increment the value of the database file
** change-counter, stored as a 4-byte big-endian integer starting at
-** byte offset 24 of the pager file.
+** byte offset 24 of the pager file. The secondary change counter at
+** 92 is also updated, as is the SQLite version number at offset 96.
+**
+** But this only happens if the pPager->changeCountDone flag is false.
+** To avoid excess churning of page 1, the update only happens once.
+** See also the pager_write_changecounter() routine that does an
+** unconditional update of the change counters.
**
** If the isDirectMode flag is zero, then this is done by calling
** sqlite3PagerWrite() on page 1, then modifying the contents of the
if( !pPager->changeCountDone && pPager->dbSize>0 ){
PgHdr *pPgHdr; /* Reference to page 1 */
- u32 change_counter; /* Initial value of change-counter field */
assert( !pPager->tempFile && isOpen(pPager->fd) );
** direct mode, page 1 is always held in cache and hence the PagerGet()
** above is always successful - hence the ALWAYS on rc==SQLITE_OK.
*/
- if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){
+ if( !DIRECT_MODE && rc==SQLITE_OK ){
rc = sqlite3PagerWrite(pPgHdr);
}
if( rc==SQLITE_OK ){
- /* Increment the value just read and write it back to byte 24. */
- change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers);
- change_counter++;
- put32bits(((char*)pPgHdr->pData)+24, change_counter);
-
- /* Also store the SQLite version number in bytes 96..99 and in
- ** bytes 92..95 store the change counter for which the version number
- ** is valid. */
- put32bits(((char*)pPgHdr->pData)+92, change_counter);
- put32bits(((char*)pPgHdr->pData)+96, SQLITE_VERSION_NUMBER);
+ /* Actually do the update of the change counter */
+ pager_write_changecounter(pPgHdr);
/* If running in direct mode, write the contents of page 1 to the file. */
if( DIRECT_MODE ){