diff --git a/manifest b/manifest index 5016365229..a683cb3b8f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sto\sthe\sproxy\slocking\sso\sthat\sos_unix.c\scompiles\son\slinux\swith\sproxy\nlocking\somitted.\s(CVS\s5935) -D 2008-11-21T00:24:42 +C On\sa\sROLLBACK,\sif\sthere\spage\scache\sentries\swhich\sare\sdirty\sbut\snot\sin\sthe\nrollback\sjournal,\smake\ssure\sthey\sget\sreinitialized\sin\sthe\sbtree\slayer.\s(CVS\s5936) +D 2008-11-21T03:23:43 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 0aa7bbe3be6acc4045706e3bb3fd0b8f38f4a3b5 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -139,7 +139,7 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60 F src/os_os2.c d12285d66df674c42f6f544a6f7c21bf1a954ee1 F src/os_unix.c 28cc4da7886c265c0a58f6975346b83180f03e5b F src/os_win.c 3dff41670fb9798a869c636626bb7d6d8b6a45bb -F src/pager.c db12a8333e54e7bbf62dc621ada5507adb3a6493 +F src/pager.c 8e2ebfd226351fd7856d6384187411471deafdc6 F src/pager.h a02ef8e6cc7e78b54874166e5ce786c9d4c489bf F src/parse.y 2c4758b4c5ead6de8cf7112f5a7cce7561d313fe F src/pcache.c f3121a531745b20f5b824201eb63949a7e2959ac @@ -581,6 +581,7 @@ F test/tkt3457.test e9ca2b90f0eb1fb8be73a30d29aacb2e3abedeb9 F test/tkt3461.test 5a63e8d8ee5ce00f076b1e2f82aba5480a0f14ed F test/tkt3472.test e689a687631e59c7a47d9438148115fee23b16c3 F test/tkt3493.test 8472b3464e49a27ff7271308eec46154209e667b +F test/tkt35xx.test 7bad910326076e1147b56717a436a68c9d5a227a F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 F test/trace.test 951cd0f5f571e7f36bf7bfe04be70f90fb16fb00 F test/trans.test 2fd24cd7aa0b879d49a224cbd647d698f1e7ac5c @@ -660,7 +661,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P b9bc36d3d5e35821ef69c0881a84c0afed253c9e -R 51d99d1efef810ac91db46cd7349fd5c +P 6f910b7036817f4bb4de807bf48938d20ab033cc +R 07e73e1f53ea5064ce74d8b65c948f50 U drh -Z 0b65fc7ed0458f20fc913219cf654811 +Z 8e850a75352c5d8dd456f4d89f060e1a diff --git a/manifest.uuid b/manifest.uuid index 331e062b52..da2be48dad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f910b7036817f4bb4de807bf48938d20ab033cc \ No newline at end of file +faded96f36229ee85039276db693391d0f10648c \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 6d5783ec99..8107bbc268 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.506 2008/11/19 18:30:29 drh Exp $ +** @(#) $Id: pager.c,v 1.507 2008/11/21 03:23:43 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -1061,9 +1061,6 @@ static u32 pager_cksum(Pager *pPager, const u8 *aData){ return cksum; } -/* Forward declaration */ -static void makeClean(PgHdr*); - /* ** Read a single page from the journal file opened on file descriptor ** jfd. Playback this one page. @@ -1173,7 +1170,9 @@ static int pager_playback_one_page( if( pPager->xReiniter ){ pPager->xReiniter(pPg); } - if( isMainJrnl ) makeClean(pPg); + if( isMainJrnl ){ + sqlite3PcacheMakeClean(pPg); + } #ifdef SQLITE_CHECK_PAGES pPg->pageHash = pager_pagehash(pPg); #endif @@ -1518,6 +1517,20 @@ static int pager_playback(Pager *pPager, int isHot){ assert( 0 ); end_playback: + /* There may be pages in cache that are dirty but which were not in + ** the rollback journal. Such pages would have been taken out of the + ** freelist (and hence marked as DontRollback). All such pages must + ** be reinitialized. + */ + if( rc==SQLITE_OK && pPager->xReiniter ){ + PgHdr *pDirty; /* List of page that are still dirty */ + pDirty = sqlite3PcacheDirtyList(pPager->pPCache); + while( pDirty ){ + pPager->xReiniter(pDirty); + sqlite3PcacheMakeClean(pDirty); + pDirty = pDirty->pDirty; + } + } if( rc==SQLITE_OK ){ zMaster = pPager->pTmpSpace; rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); @@ -3094,23 +3107,6 @@ int sqlite3PagerBegin(DbPage *pPg, int exFlag){ return rc; } -/* -** Make a page dirty. Set its dirty flag and add it to the dirty -** page list. -*/ -static void makeDirty(PgHdr *pPg){ - sqlite3PcacheMakeDirty(pPg); -} - -/* -** Make a page clean. Clear its dirty bit and remove it from the -** dirty page list. -*/ -static void makeClean(PgHdr *pPg){ - sqlite3PcacheMakeClean(pPg); -} - - /* ** Mark a data page as writeable. The page is written into the journal ** if it is not there already. This routine must be called before making @@ -3162,7 +3158,7 @@ static int pager_write(PgHdr *pPg){ /* Mark the page as dirty. If the page has already been written ** to the journal then we can return right away. */ - makeDirty(pPg); + sqlite3PcacheMakeDirty(pPg); if( pageInJournal(pPg) && (pageInStatement(pPg) || pPager->stmtInUse==0) ){ pPager->dirtyCache = 1; pPager->dbModified = 1; @@ -4091,7 +4087,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ sqlite3PcacheDrop(pPgOld); } - makeDirty(pPg); + sqlite3PcacheMakeDirty(pPg); pPager->dirtyCache = 1; pPager->dbModified = 1; @@ -4126,7 +4122,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ pPager->needSync = 1; assert( pPager->noSync==0 && !MEMDB ); pPgHdr->flags |= PGHDR_NEED_SYNC; - makeDirty(pPgHdr); + sqlite3PcacheMakeDirty(pPgHdr); sqlite3PagerUnref(pPgHdr); } diff --git a/test/tkt35xx.test b/test/tkt35xx.test new file mode 100644 index 0000000000..4cbb2e92fb --- /dev/null +++ b/test/tkt35xx.test @@ -0,0 +1,39 @@ +# 2008 November 20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# When a transaction rolls back, make sure that dirty pages in the +# page cache which are not in the rollback journal are reinitialized +# in the btree layer. +# +# $Id: tkt35xx.test,v 1.1 2008/11/21 03:23:43 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_test tkt35xx-1.1 { + execsql { + PRAGMA auto_vacuum = 0; + CREATE TABLE t1(a,b,c); + CREATE INDEX i1 ON t1(c); + INSERT INTO t1 VALUES(0, 0, zeroblob(676)); + INSERT INTO t1 VALUES(1, 1, zeroblob(676)); + DELETE FROM t1; + BEGIN; + INSERT INTO t1 VALUES(0, 0, zeroblob(676)); + INSERT INTO t1 VALUES(1, 1, zeroblob(676)); + ROLLBACK; + INSERT INTO t1 VALUES(0, 0, zeroblob(676)); + } + execsql { + INSERT INTO t1 VALUES(1, 1, zeroblob(676)); + } +} {}