From 8220da7b8b1a9450607ea78266cd78110a318970 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 5 Jul 2010 17:43:32 +0000 Subject: [PATCH] When rolling back page 1 from a journal, restore the "nReserve" setting in case it has been corrupted by a prior crash. FossilOrigin-Name: c0d124da88e84e68679c2f3f4b2b35c03aecc916 --- manifest | 24 +++++++++++++++++------- manifest.uuid | 2 +- src/pager.c | 50 +++++++++++++++++++++++++------------------------- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 2b8bfa0e95..4a70add3a2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Do\snot\sreport\san\serror\sif\sthe\sopen-file-count\sis\snot\sas\sit\sshould\sbe\safter\srunning\sa\smulti-threaded\stest.\sThe\scounter\sinstrumentation\sis\snot\sthread-safe. -D 2010-07-05T14:54:49 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C When\srolling\sback\spage\s1\sfrom\sa\sjournal,\srestore\sthe\s"nReserve"\ssetting\nin\scase\sit\shas\sbeen\scorrupted\sby\sa\sprior\scrash. +D 2010-07-05T17:43:32 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -156,7 +159,7 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19 F src/os_unix.c c6112f0ae34f23ae5ca0189a685e084befbdcf26 F src/os_win.c 883caa09d8cf7c4dfdef6eba6930466cb8a8275c -F src/pager.c e4470e43f0fefe5f81034efb706a2b1f4db5ca41 +F src/pager.c 14ec8ea3d27cf4c8b7b6a6139c150b50dd28df3e F src/pager.h 879fdde5a102d2f21a3135d6f647530b21c2796c F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07 @@ -830,7 +833,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 684eae6623ef1d0336b7a734b17ed307c720b6f4 -R 63f603eae54aff0b7014e11adb19abba -U dan -Z c2e1163608ea0fe576a6717534083382 +P ea80b21c881fabaec1da788588c35c6c9782dcbd +R 5de919a3a55f2a8c35bbb58047acd345 +U drh +Z aa2a677064258d9e6322a258f0100e48 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFMMhnIoxKgR168RlERAv13AJ0RezR75fN7II4WYQ+k2k88YWRNwgCeOLx/ +tAjj2vuEc4/BCzTdXBrdXV8= +=hcXV +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 2574592c50..04aaee85d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea80b21c881fabaec1da788588c35c6c9782dcbd \ No newline at end of file +c0d124da88e84e68679c2f3f4b2b35c03aecc916 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index a7d8565de1..038a87fd76 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1517,6 +1517,21 @@ static u32 pager_cksum(Pager *pPager, const u8 *aData){ return cksum; } +/* +** Report the current page size and number of reserved bytes back +** to the codec. +*/ +#ifdef SQLITE_HAS_CODEC +static void pagerReportSize(Pager *pPager){ + if( pPager->xCodecSizeChng ){ + pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, + (int)pPager->nReserve); + } +} +#else +# define pagerReportSize(X) /* No-op if we do not support a codec */ +#endif + /* ** Read a single page from either the journal file (if isMainJrnl==1) or ** from the sub-journal (if isMainJrnl==0) and playback that page. @@ -1609,12 +1624,21 @@ static int pager_playback_one_page( } } + /* If this page has already been played by before during the current + ** rollback, then don't bother to play it back again. + */ if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ return rc; } - assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE ); + /* When playing back page 1, restore the nReserve setting + */ + if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ + pPager->nReserve = ((u8*)aData)[20]; + pagerReportSize(pPager); + } + /* If the pager is in RESERVED state, then there must be a copy of this ** page in the pager cache. In this case just update the pager cache, ** not the database file. The page is left marked dirty in this case. @@ -2751,21 +2775,6 @@ void sqlite3PagerSetBusyhandler( pPager->pBusyHandlerArg = pBusyHandlerArg; } -/* -** Report the current page size and number of reserved bytes back -** to the codec. -*/ -#ifdef SQLITE_HAS_CODEC -static void pagerReportSize(Pager *pPager){ - if( pPager->xCodecSizeChng ){ - pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, - (int)pPager->nReserve); - } -} -#else -# define pagerReportSize(X) /* No-op if we do not support a codec */ -#endif - /* ** Change the page size used by the Pager object. The new page size ** is passed in *pPageSize. @@ -2905,15 +2914,6 @@ int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ ** to WAL mode yet. */ assert( !pagerUseWal(pPager) ); -#if 0 - if( pagerUseWal(pPager) ){ - int isInWal = 0; - rc = sqlite3WalRead(pPager->pWal, 1, &isInWal, N, pDest); - if( rc!=SQLITE_OK || isInWal ){ - return rc; - } - } -#endif if( isOpen(pPager->fd) ){ IOTRACE(("DBHDR %p 0 %d\n", pPager, N))