From ee03d629f5f561bc049043d243e4727ae2d0a47c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Jan 2009 15:33:45 +0000 Subject: [PATCH] Conjecture: a journal header with nRec==0 must be the last header in the journal. Add asserts to make this conjecture explicit. (CVS 6132) FossilOrigin-Name: 15b5b5f90c2ffa79155cdc2dbc4fb5583cb72017 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/pager.c | 32 ++++++++++++++++++++++---------- test/pcache.test | 7 +++---- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 061ce427ff..8f41891265 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfor\s'truncate\sfile'\soperations\son\sin-memory\sdatabases.\s(CVS\s6131) -D 2009-01-07T15:18:21 +C Conjecture:\sa\sjournal\sheader\swith\snRec==0\smust\sbe\sthe\slast\sheader\sin\sthe\njournal.\s\sAdd\sasserts\sto\smake\sthis\sconjecture\sexplicit.\s(CVS\s6132) +D 2009-01-07T15:33:46 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 05461a9b5803d5ad10c79f989801e9fd2cc3e592 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -142,7 +142,7 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60 F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5 F src/os_unix.c e6eacc7ec735ded605fefcbaf250058baa8feb12 F src/os_win.c 496e3ceb499aedc63622a89ef76f7af2dd902709 -F src/pager.c a799290e5cf9495f9991413ce84847011767b4d9 +F src/pager.c 2fd6d5a88a8a2a7222398640d88d0094a221b240 F src/pager.h 9870acb2d653848d90d765d7cbf163496d6c8111 F src/parse.y 4d0e33a702dc3ea7b69d8ae1914b3fbd32e46057 F src/pcache.c 16dc8da6e6ba6250f8dfd9ee46036db1cbceedc6 @@ -475,7 +475,7 @@ F test/pager2.test d4b7f6b70ff018b9995e622a32526b275f515042 F test/pager3.test 2323bf27fd5bd887b580247e5bce500ceee994b4 F test/pageropt.test 3ee6578891baaca967f0bd349e4abfa736229e1a F test/pagesize.test 0d9ff3fedfce6e5ffe8fa7aca9b6d3433a2e843b -F test/pcache.test 515b4c26e9f57660357dfff5b6b697acac1abc5f +F test/pcache.test ccd18b4d2b432f44319a82b0367ed843ee18cebd F test/pcache2.test 46efd980a89f737847b99327bda19e08fe11e402 F test/permutations.test af0962c17a32631de8b301c301c497adea9739f4 F test/pragma.test 325aa0833d483b8e0c98e8196f1cc49fa5d8c336 @@ -692,7 +692,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 04387ae10ab3be24c93497f4af6f48d6832f37eb -R cd03e1b03d4149ac01b912dddfeb4003 -U danielk1977 -Z 242d556585dea66787f6cacf6e86748b +P 83d1eafbde556f56969c6f285b6767d2c658dbfc +R e0c72c9528a9fa2ec3f8b366bc70534d +U drh +Z 5a8b01afe6b4e3b34d058c12ce65dc71 diff --git a/manifest.uuid b/manifest.uuid index 14af207e6b..623b96ccd2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83d1eafbde556f56969c6f285b6767d2c658dbfc \ No newline at end of file +15b5b5f90c2ffa79155cdc2dbc4fb5583cb72017 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 130c8255ec..5a7be86a64 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.538 2009/01/07 15:18:21 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.539 2009/01/07 15:33:46 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -1315,7 +1315,7 @@ static int pager_playback_one_page( return rc; } -#if /* !defined(NDEBUG) || */ defined(SQLITE_COVERAGE_TEST) +#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST) /* ** This routine looks ahead into the main journal file and determines ** whether or not the next record (the record that begins at file @@ -1646,12 +1646,15 @@ static int pager_playback(Pager *pPager, int isHot){ ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in ** the journal, it means that the journal might contain additional ** pages that need to be rolled back and that the number of pages - ** should be computed based on the journal file size. + ** should be computed based on the journal file size. + ** + ** 2009-01-07: We think #2565 is now unreachable due to changes + ** in the pcache. The assert that follows will fire if we are wrong. */ - testcase( nRec==0 && !isHot + assert( !(nRec==0 && !isHot && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)!=pPager->journalOff && ((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager))>0 - && pagerNextJournalPageIsValid(pPager) + && pagerNextJournalPageIsValid(pPager)) ); if( nRec==0 && !isHot && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ @@ -1784,10 +1787,10 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ ** test is related to ticket #2565. See the discussion in the ** pager_playback() function for additional information. */ - testcase( nJRec==0 + assert( !(nJRec==0 && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)!=pPager->journalOff && ((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager))>0 - && pagerNextJournalPageIsValid(pPager) + && pagerNextJournalPageIsValid(pPager)) ); if( nJRec==0 && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff @@ -3574,18 +3577,27 @@ int sqlite3PagerWrite(DbPage *pDbPage){ } } - /* If the PgHdr.needSync flag is set for any of the nPage pages + /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages ** starting at pg1, then it needs to be set for all of them. Because ** writing to any of these nPage pages may damage the others, the ** journal file must contain sync()ed copies of all of them ** before any of them can be written out to the database file. + ** + ** 2009-01-07: This block of code appears to be a no-op. I do not + ** believe it is possible for any page on the sector to not have + ** the PGHDR_NEED_SYNC flag set. The "pPage->flags |= PGHDR_NEED_SYNC" + ** line below does nothing, I think. But it does no harm to leave + ** this code in place until we can definitively prove this is the case. */ if( needSync ){ assert( !MEMDB && pPager->noSync==0 ); for(ii=0; iiflags |= PGHDR_NEED_SYNC; - sqlite3PagerUnref(pPage); + if( pPage ){ + assert( pPage->flags & PGHDR_NEED_SYNC ); /* 2009-01-07 conjecture */ + pPage->flags |= PGHDR_NEED_SYNC; + sqlite3PagerUnref(pPage); + } } assert(pPager->needSync); } diff --git a/test/pcache.test b/test/pcache.test index 0971319277..ad024fc373 100644 --- a/test/pcache.test +++ b/test/pcache.test @@ -11,7 +11,7 @@ # # This file is focused on testing the pcache module. # -# $Id: pcache.test,v 1.2 2008/09/05 05:29:09 danielk1977 Exp $ +# $Id: pcache.test,v 1.3 2009/01/07 15:33:46 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -64,7 +64,7 @@ do_test pcache-1.5 { pcache_stats } {current 11 max 20 min 20 recyclable 1} -do_test pcache-1.6 { +do_test pcache-1.6.1 { execsql { BEGIN; SELECT * FROM sqlite_master; @@ -76,7 +76,7 @@ do_test pcache-1.6 { # single pinned page in its cache. Connection [db] is holding 10 dirty # pages. It cannot recycle them because of the read lock held by db2. # -do_test pcache-1.6 { +do_test pcache-1.6.2 { execsql { CREATE INDEX i1 ON t1(a, b); CREATE INDEX i2 ON t2(a, b); @@ -144,4 +144,3 @@ do_test pcache-1.13 { } {current 15 max 15 min 10 recyclable 15} finish_test -