From 4ef24490a1bcd95a18588d9f633d589fe894475a Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Wed, 23 May 2007 09:52:41 +0000 Subject: [PATCH] Fix a database corrupting bug in the optimistic overflow chain. Exposed by running bigrow.test with auto-vacuum enabled. (CVS 4030) FossilOrigin-Name: 10ee2d50cbcdcbbd8141ff2aba4fd2c0c0b70d67 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 25 +++++++++++++++++-------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 3e92122fbe..5db49b98db 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\scomments\sono\sthe\sSQLITE_MIXED_ENDIAN_64BIT_FLOAT\sissue.\s(CVS\s4029) -D 2007-05-23T07:20:09 +C Fix\sa\sdatabase\scorrupting\sbug\sin\sthe\soptimistic\soverflow\schain.\sExposed\sby\srunning\sbigrow.test\swith\sauto-vacuum\senabled.\s(CVS\s4030) +D 2007-05-23T09:52:42 F Makefile.in a42354804b50c2708ce72cf79e4daa30f50191b5 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -62,7 +62,7 @@ F src/alter.c 1b1deeb97446ed87f2fa17a3eb6236548841a348 F src/analyze.c e8fcb1c35ace8418615eb18d9601f321ac86b2ec F src/attach.c ba628db0c2b6a362f036d017bf1196cdfe4ebb37 F src/auth.c 5ea90bc93dfea46e9fe4bf531e14c7cd98219ecb -F src/btree.c 9179039d9a023da986c168e276680fed9dcc57fd +F src/btree.c 8b39c5aad153744919c79efbeca92a17e5167c2f F src/btree.h 1d527bf61ed176f980c34999d5793a0fd45dcf8c F src/btreeInt.h f92c0577f49d961c0148b477a25647e8fd80eecf F src/build.c 50992d92e131a9aa9aa6657fb1ddc13e176fd70c @@ -494,7 +494,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 6e19ef758207cedd6db8b2796ef5d4d688cc0b62 -R 5b955388b5718234e99bb751cff2d291 -U drh -Z eaf7c05ab3e15bb90bfa5a13a327e560 +P dd48a31e671de09f59661b2ba1a20e7b9f09099a +R 0a4b7a5a7560782609618616930efe42 +U danielk1977 +Z 355df7558cb933d10fd908dea6dfeba4 diff --git a/manifest.uuid b/manifest.uuid index 45c5171e7c..0f1c5b30d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dd48a31e671de09f59661b2ba1a20e7b9f09099a \ No newline at end of file +10ee2d50cbcdcbbd8141ff2aba4fd2c0c0b70d67 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 9bc1854cc4..3d3a64d9ef 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.383 2007/05/17 18:28:11 danielk1977 Exp $ +** $Id: btree.c,v 1.384 2007/05/23 09:52:42 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -1877,7 +1877,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin){ if( eType==PTRMAP_FREEPAGE ){ if( nFin==0 ){ /* Remove the page from the files free-list. This is not required - ** if nFin is non-zero. In this case, the free-list will be + ** if nFin is non-zero. In that case, the free-list will be ** truncated to zero after this function returns, so it doesn't ** matter if it still contains some garbage entries. */ @@ -3451,7 +3451,7 @@ static int allocateBtreePage( ** the entire-list will be searched for that page. */ #ifndef SQLITE_OMIT_AUTOVACUUM - if( exact ){ + if( exact && nearby<=sqlite3PagerPagecount(pBt->pPager) ){ u8 eType; assert( nearby>0 ); assert( pBt->autoVacuum ); @@ -3808,6 +3808,7 @@ static int fillInCell( Pgno pgnoOvfl = 0; int nHeader; CellInfo info; + Pgno pgnoFirstOvfl = 0; /* Fill in the header. */ nHeader = 0; @@ -3852,7 +3853,7 @@ static int fillInCell( } while( PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) ); - if( pgnoOvfl>1 ){ + if( pgnoOvfl>1 && pgnoOvfl!=pgnoFirstOvfl ){ /* isExact = 1; */ } } @@ -3861,11 +3862,19 @@ static int fillInCell( #ifndef SQLITE_OMIT_AUTOVACUUM /* If the database supports auto-vacuum, and the second or subsequent ** overflow page is being allocated, add an entry to the pointer-map - ** for that page now. The entry for the first overflow page will be - ** added later, by the insertCell() routine. + ** for that page now. + ** + ** If this is the first overflow page, then write a partial entry + ** to the pointer-map. If we write nothing to this pointer-map slot, + ** then the optimistic overflow chain processing in clearCell() + ** may misinterpret the uninitialised values and delete the + ** wrong pages from the database. */ - if( pBt->autoVacuum && pgnoPtrmap!=0 && rc==SQLITE_OK ){ - rc = ptrmapPut(pBt, pgnoOvfl, PTRMAP_OVERFLOW2, pgnoPtrmap); + if( pBt->autoVacuum && rc==SQLITE_OK ){ + u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1); + rc = ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap); + }else{ + pgnoFirstOvfl = pgnoOvfl; } #endif if( rc ){