diff --git a/manifest b/manifest index efba17f7ac..584b41bf23 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\sdebugging\sinstrumentation\sadded\sto\sthe\spager.\s(CVS\s4078) -D 2007-06-16T03:06:28 +C Fix\sa\sdatabase\scorruption\sproblem\sthat\scan\soccur\sin\sauto-vacuum\smode\swhen\na\smalloc()\sfailure\scauses\sa\sstatement\srollback,\sadditional\sstatements\nare\srun\sin\sthe\ssame\stransaction,\sthen\sthe\stotal\stransaction\srolls\sback.\s(CVS\s4079) +D 2007-06-16T04:42:12 F Makefile.in b9971ab07868cf2b3209fe3bf8c52e7e25af4193 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -94,7 +94,7 @@ F src/os_unix.c f2ccf2e9a925fc679faf7a8fe85700e0f13cf0e1 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c a4a02246d23edcc8113f5957d7db4772d9cd71bc +F src/pager.c a8e5c2fd00737ddd7d8c8416d0fdbbf904d78b64 F src/pager.h 94110a5570dca30d54a883e880a3633b2e4c05ae F src/parse.y 2ed1d91fdcb4ae7ae7d1f4674544297807c7cc26 F src/pragma.c 0d25dad58bdfd6789943a10f1b9663c2eb85b96d @@ -506,7 +506,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 7d3c1f08a34fcf2ca5c79d6e58f713ae6a4b34e8 -R 22dcb4d1b3c757bf921381ac2ad50631 +P dcdb20f81ae923f6f56d75c7b8b89a0b3abff954 +R e52cc159103410bf628cb2caa9ba87b2 U drh -Z aa8c8e6b272cf52bad3cb3c217bce91b +Z 5e8ccb501c2183f5e479995480e6033d diff --git a/manifest.uuid b/manifest.uuid index c8e08ec9f6..67410fda45 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dcdb20f81ae923f6f56d75c7b8b89a0b3abff954 \ No newline at end of file +c9dcf2b926c99ff9cee68589f364461ab2a1d11f \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index e17048079b..94432b6164 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.344 2007/06/16 03:06:28 drh Exp $ +** @(#) $Id: pager.c,v 1.345 2007/06/16 04:42:12 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -1106,13 +1106,14 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ ** This occurs when a page is changed prior to the start of a statement ** then changed again within the statement. When rolling back such a ** statement we must not write to the original database unless we know - ** for certain that original page contents are in the main rollback - ** journal. Otherwise, if a full ROLLBACK occurs after the statement - ** rollback the full ROLLBACK will not restore the page to its original - ** content. Two conditions must be met before writing to the database - ** files. (1) the database must be locked. (2) we know that the original - ** page content is in the main journal either because the page is not in - ** cache or else it is marked as needSync==0. + ** for certain that original page contents are synced into the main rollback + ** journal. Otherwise, a power loss might leave modified data in the + ** database file without an entry in the rollback journal that can + ** restore the database to its original form. Two conditions must be + ** met before writing to the database files. (1) the database must be + ** locked. (2) we know that the original page content is fully synced + ** in the main journal either because the page is not in cache or else + ** the page is marked as needSync==0. */ pPg = pager_lookup(pPager, pgno); PAGERTRACE4("PLAYBACK %d page %d hash(%08x)\n", @@ -4243,15 +4244,15 @@ void sqlite3PagerSetCodec( #ifndef SQLITE_OMIT_AUTOVACUUM /* -** Move the page identified by pData to location pgno in the file. +** Move the page pPg to location pgno in the file. ** -** There must be no references to the current page pgno. If current page -** pgno is not already in the rollback journal, it is not written there by -** by this routine. The same applies to the page pData refers to on entry to -** this routine. +** There must be no references to the page previously located at +** pgno (which we call pPgOld) though that page is allowed to be +** in cache. If the page previous located at pgno is not already +** in the rollback journal, it is not put there by by this routine. ** -** References to the page refered to by pData remain valid. Updating any -** meta-data associated with page pData (i.e. data stored in the nExtra bytes +** References to the page pPg remain valid. Updating any +** meta-data associated with pPg (i.e. data stored in the nExtra bytes ** allocated along with the page) is the responsibility of the caller. ** ** A transaction must be active when this routine is called. It used to be @@ -4260,7 +4261,7 @@ void sqlite3PagerSetCodec( ** transaction is active). */ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){ - PgHdr *pPgOld; + PgHdr *pPgOld; /* The page being overwritten. */ int h; Pgno needSyncPgno = 0; @@ -4286,17 +4287,23 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){ ** page pgno before the 'move' operation, it needs to be retained ** for the page moved there. */ + pPg->needSync = 0; pPgOld = pager_lookup(pPager, pgno); if( pPgOld ){ assert( pPgOld->nRef==0 ); unlinkHashChain(pPager, pPgOld); makeClean(pPgOld); - if( pPgOld->needSync ){ - assert( pPgOld->inJournal ); - pPg->inJournal = 1; - pPg->needSync = 1; - assert( pPager->needSync ); - } + pPg->needSync = pPgOld->needSync; + }else{ + pPg->needSync = 0; + } + if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){ + pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0; + }else if( (int)pgno>=pPager->origDbSize ){ + pPg->inJournal = 1; + }else{ + pPg->inJournal = 0; + assert( pPg->needSync==0 ); } /* Change the page number for pPg and insert it into the new hash-chain. */