From: drh Date: Wed, 1 Jul 2015 17:53:49 +0000 (+0000) Subject: Simplification of PRAGMA integrity_check logic. Make sure that the depth X-Git-Tag: version-3.8.11~81 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e05b3f8f0bf6e7009c0746057535a81d1c3f05b2;p=thirdparty%2Fsqlite.git Simplification of PRAGMA integrity_check logic. Make sure that the depth of the right-most subtree is correct. Size reduction and performance increase, with no change in output. FossilOrigin-Name: 550705fcb64e7ad637686e47cabe2621d65851bf --- diff --git a/manifest b/manifest index ad6e53acd5..c6b3a9a010 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sharmless\scompiler\swarnings. -D 2015-07-01T04:08:40.538 +C Simplification\sof\sPRAGMA\sintegrity_check\slogic.\s\sMake\ssure\sthat\sthe\sdepth\nof\sthe\sright-most\ssubtree\sis\scorrect.\s\sSize\sreduction\sand\sperformance\sincrease,\nwith\sno\schange\sin\soutput. +D 2015-07-01T17:53:49.435 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 285a0a234ed7610d431d91671c136098c2bd86a9 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -269,9 +269,9 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3 F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 -F src/btree.c 075ce6ddce9e66277c898f5b6a44a8a7c61c8125 +F src/btree.c e283de2f9da7ec5e47bedcd442a66a671aa2e118 F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 -F src/btreeInt.h c54d380cb262549c4176e0d665518cc1a3861bdf +F src/btreeInt.h 2ad754dd4528baa8d0946a593cc373b890bf859e F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f @@ -314,8 +314,8 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 23eb5f56fac54d8fe0cb204291f3b3b2d94f23fc F src/os_win.c 27cc135e2d0b8b1e2e4944db1e2669a6a18fa0f8 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 922d8ea28387b79a117488da06ee84f77d50d71e -F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77 +F src/pager.c aa916ca28606ccf4b6877dfc2b643ccbca86589f +F src/pager.h 6d435f563b3f7fcae4b84433b76a6ac2730036e2 F src/parse.y 6d60dda8f8d418b6dc034f1fbccd816c459983a8 F src/pcache.c cde06aa50962595e412d497e22fd2e07878ba1f0 F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9 @@ -1364,7 +1364,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 59ad912c4c1f858e04d27b1b8f25581a5f6e5daf -R 71a875c7f3b6312a533d9c1fd4d005d9 +P 307195c8709d7fd2a642baa8011eb0c88cfdc0ac +R 1440540aa3867982699c114f203dbd2b U drh -Z 39cb6954bdcd951136843b690dd37c51 +Z 4a2c86e34c201f78bc5202943cc67b23 diff --git a/manifest.uuid b/manifest.uuid index 71a9643813..a2d7952053 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -307195c8709d7fd2a642baa8011eb0c88cfdc0ac \ No newline at end of file +550705fcb64e7ad637686e47cabe2621d65851bf \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a8e5beb227..a34c84fbcd 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8924,14 +8924,10 @@ static int btreeHeapPull(u32 *aHeap, u32 *pOut){ ** ** 1. Make sure that cells and freeblocks do not overlap ** but combine to completely cover the page. -** NO 2. Make sure cell keys are in order. -** NO 3. Make sure no key is less than or equal to zLowerBound. -** NO 4. Make sure no key is greater than or equal to zUpperBound. -** 5. Check the integrity of overflow pages. -** 6. Recursively call checkTreePage on all children. -** 7. Verify that the depth of all children is the same. -** 8. Make sure this page is at least 33% full or else it is -** the root of the tree. +** 2. Make sure integer cell keys are in order. +** 3. Check the integrity of overflow pages. +** 4. Recursively call checkTreePage on all children. +** 5. Verify that the depth of all children is the same. */ static int checkTreePage( IntegrityCk *pCheck, /* Context for the sanity check */ @@ -8939,7 +8935,7 @@ static int checkTreePage( i64 *pnParentMinKey, i64 *pnParentMaxKey ){ - MemPage *pPage; + MemPage *pPage = 0; int i, rc, depth, d2, pgno, cnt; int hdr, cellStart; int nCell; @@ -8976,7 +8972,6 @@ static int checkTreePage( assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */ checkAppendMsg(pCheck, "btreeInitPage() returns error code %d", rc); - releasePage(pPage); depth = -1; goto end_of_check; } @@ -8984,6 +8979,7 @@ static int checkTreePage( /* Check out all the cells. */ depth = 0; + pCheck->zPfx = "On tree page %d cell %d: "; for(i=0; inCell && pCheck->mxErr; i++){ u8 *pCell; u32 sz; @@ -8991,8 +8987,6 @@ static int checkTreePage( /* Check payload overflow pages */ - pCheck->zPfx = "On tree page %d cell %d: "; - pCheck->v1 = iPage; pCheck->v2 = i; pCell = findCell(pPage,i); pPage->xParseCell(pPage, pCell, &info); @@ -9041,20 +9035,21 @@ static int checkTreePage( if( !pPage->leaf ){ pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); pCheck->zPfx = "On page %d at right child: "; - pCheck->v1 = iPage; #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); } #endif - checkTreePage(pCheck, pgno, NULL, !pPage->nCell?NULL:&nMaxKey); + d2 = checkTreePage(pCheck, pgno, NULL, !pPage->nCell?NULL:&nMaxKey); + if( d2!=depth && iPage!=1 ){ + checkAppendMsg(pCheck, "Child page depth differs"); + } } /* For intKey leaf pages, check that the min/max keys are in order ** with any left/parent/right pages. */ pCheck->zPfx = "Page %d: "; - pCheck->v1 = iPage; if( pPage->leaf && pPage->intKey ){ /* if we are a left child page */ if( pnParentMinKey ){ @@ -9092,14 +9087,12 @@ static int checkTreePage( */ data = pPage->aData; hdr = pPage->hdrOffset; - heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); + heap = pCheck->heap; + heap[0] = 0; pCheck->zPfx = 0; - if( heap==0 ){ - pCheck->mallocFailed = 1; - }else{ + { int contentOffset = get2byteNotZero(&data[hdr+5]); assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ - heap[0] = 0; btreeHeapInsert(heap, contentOffset-1); /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the ** number of cells on the page. */ @@ -9167,10 +9160,9 @@ static int checkTreePage( cnt, data[hdr+7], iPage); } } - sqlite3PageFree(heap); - releasePage(pPage); end_of_check: + releasePage(pPage); pCheck->zPfx = saved_zPfx; pCheck->v1 = saved_v1; pCheck->v2 = saved_v2; @@ -9200,14 +9192,14 @@ char *sqlite3BtreeIntegrityCheck( int *pnErr /* Write number of errors seen to this variable */ ){ Pgno i; - int nRef; + VVA_ONLY( int nRef ); IntegrityCk sCheck; BtShared *pBt = p->pBt; char zErr[100]; sqlite3BtreeEnter(p); assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); - nRef = sqlite3PagerRefcount(pBt->pPager); + assert( (nRef = sqlite3PagerRefcount(pBt->pPager))>=0 ); sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = btreePagecount(sCheck.pBt); @@ -9217,21 +9209,26 @@ char *sqlite3BtreeIntegrityCheck( sCheck.zPfx = 0; sCheck.v1 = 0; sCheck.v2 = 0; - *pnErr = 0; + sCheck.aPgRef = 0; + sCheck.heap = 0; + sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); if( sCheck.nPage==0 ){ - sqlite3BtreeLeave(p); - return 0; + goto integrity_ck_cleanup; } sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); if( !sCheck.aPgRef ){ - *pnErr = 1; - sqlite3BtreeLeave(p); - return 0; + sCheck.mallocFailed = 1; + goto integrity_ck_cleanup; + } + sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); + if( sCheck.heap==0 ){ + sCheck.mallocFailed = 1; + goto integrity_ck_cleanup; } + i = PENDING_BYTE_PAGE(pBt); if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); - sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); /* Check the integrity of the freelist */ @@ -9249,9 +9246,7 @@ char *sqlite3BtreeIntegrityCheck( checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); } #endif - sCheck.zPfx = "List of tree roots: "; checkTreePage(&sCheck, aRoot[i], NULL, NULL); - sCheck.zPfx = 0; } /* Make sure every page in the file is referenced @@ -9276,28 +9271,20 @@ char *sqlite3BtreeIntegrityCheck( #endif } - /* Make sure this analysis did not leave any unref() pages. - ** This is an internal consistency check; an integrity check - ** of the integrity check. - */ - if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){ - checkAppendMsg(&sCheck, - "Outstanding page count goes from %d to %d during this analysis", - nRef, sqlite3PagerRefcount(pBt->pPager) - ); - } - /* Clean up and report errors. */ - sqlite3BtreeLeave(p); +integrity_ck_cleanup: + sqlite3PageFree(sCheck.heap); sqlite3_free(sCheck.aPgRef); if( sCheck.mallocFailed ){ sqlite3StrAccumReset(&sCheck.errMsg); - *pnErr = sCheck.nErr+1; - return 0; + sCheck.nErr++; } *pnErr = sCheck.nErr; if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg); + /* Make sure this analysis did not leave any unref() pages. */ + assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); + sqlite3BtreeLeave(p); return sqlite3StrAccumFinish(&sCheck.errMsg); } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ diff --git a/src/btreeInt.h b/src/btreeInt.h index d74ea5557f..cbf6c99847 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -682,6 +682,7 @@ struct IntegrityCk { const char *zPfx; /* Error message prefix */ int v1, v2; /* Values for up to two %d fields in zPfx */ StrAccum errMsg; /* Accumulate the error message text here */ + u32 *heap; /* Min-heap used for analyzing cell coverage */ }; /* diff --git a/src/pager.c b/src/pager.c index 982413ca8a..060edb8d1d 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6387,12 +6387,14 @@ u8 sqlite3PagerIsreadonly(Pager *pPager){ return pPager->readOnly; } +#ifdef SQLITE_DEBUG /* ** Return the number of references to the pager. */ int sqlite3PagerRefcount(Pager *pPager){ return sqlite3PcacheRefCount(pPager->pPCache); } +#endif /* ** Return the approximate number of bytes of memory currently diff --git a/src/pager.h b/src/pager.h index e07fa88fc5..e3b57f435e 100644 --- a/src/pager.h +++ b/src/pager.h @@ -173,7 +173,9 @@ int sqlite3PagerSharedLock(Pager *pPager); /* Functions used to query pager state and configuration. */ u8 sqlite3PagerIsreadonly(Pager*); u32 sqlite3PagerDataVersion(Pager*); -int sqlite3PagerRefcount(Pager*); +#ifdef SQLITE_DEBUG + int sqlite3PagerRefcount(Pager*); +#endif int sqlite3PagerMemUsed(Pager*); const char *sqlite3PagerFilename(Pager*, int); const sqlite3_vfs *sqlite3PagerVfs(Pager*);