Improved detection of database corruption while balancing pages from an
auto_vacuum database with overflow pages. Test cases in TH3. FossilOrigin-Name: 35f04235c477501390acea126d07a730d81d03cdf7abcd82d861e397b3f75b0f
This commit is contained in:
parent
a1bd5c6aae
commit
0f1bf4c1ac
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Move\sa\slocal\svariable\sdeclaration\sinto\sthe\soutermost\sscope\sin\swhich\sit\nis\sused.\sThis\sfixes\san\sASAN\swarning.
|
||||
D 2019-01-13T00:58:57.018
|
||||
C Improved\sdetection\sof\sdatabase\scorruption\swhile\sbalancing\spages\sfrom\san\nauto_vacuum\sdatabase\swith\soverflow\spages.\s\sTest\scases\sin\sTH3.
|
||||
D 2019-01-13T20:17:21.006
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 45a3fef4d325ac0220c2172aeec4e4321da351f073f3b8e8ddea655f49ef6f2b
|
||||
@ -453,7 +453,7 @@ F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df
|
||||
F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c 789380da841ec283bf75c8b3e2c6423fed63ac16193b247cd43335f07e95f355
|
||||
F src/btree.c d2ee84255b7372e6a70447f3e260eadfca38d25b1039cf88341df4225cbb3e0e
|
||||
F src/btree.h febb2e817be499570b7a2e32a9bbb4b607a9234f6b84bb9ae84916d4806e96f2
|
||||
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
|
||||
F src/build.c b1e24f1deedee07955cad9c56928cdafa7df1615746688e817bfe0b020a68576
|
||||
@ -1798,7 +1798,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 0f850a25d67a752fe1e9059c0c3f78e00c222113e556a7605fd3c50817b573cb
|
||||
R d1042653a3404af381612d805e6f7ade
|
||||
P ac3b6021d9437ab1c027850d321f0a3e575b008763d8d515e2347f7d4e7c294b
|
||||
R b3c41bca6e263f72d137d37d5ad93455
|
||||
U drh
|
||||
Z c1dc9aa41961f051bb56f64dcc557e3c
|
||||
Z db68a7c462e1085d4719c3b28e40f5d1
|
||||
|
@ -1 +1 @@
|
||||
ac3b6021d9437ab1c027850d321f0a3e575b008763d8d515e2347f7d4e7c294b
|
||||
35f04235c477501390acea126d07a730d81d03cdf7abcd82d861e397b3f75b0f
|
31
src/btree.c
31
src/btree.c
@ -1066,7 +1066,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
|
||||
#else /* if defined SQLITE_OMIT_AUTOVACUUM */
|
||||
#define ptrmapPut(w,x,y,z,rc)
|
||||
#define ptrmapGet(w,x,y,z) SQLITE_OK
|
||||
#define ptrmapPutOvflPtr(x, y, rc)
|
||||
#define ptrmapPutOvflPtr(x, y, z, rc)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1359,18 +1359,20 @@ static u16 cellSize(MemPage *pPage, int iCell){
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
/*
|
||||
** If the cell pCell, part of page pPage contains a pointer
|
||||
** to an overflow page, insert an entry into the pointer-map
|
||||
** for the overflow page.
|
||||
** The cell pCell is currently part of page pSrc but will ultimately be part
|
||||
** of pPage. (pSrc and pPager are often the same.) If pCell contains a
|
||||
** pointer to an overflow page, insert an entry into the pointer-map for
|
||||
** the overflow page that will be valid after pCell has been moved to pPage.
|
||||
*/
|
||||
static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
|
||||
static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
|
||||
CellInfo info;
|
||||
if( *pRC ) return;
|
||||
assert( pCell!=0 );
|
||||
pPage->xParseCell(pPage, pCell, &info);
|
||||
if( info.nLocal<info.nPayload ){
|
||||
Pgno ovfl;
|
||||
if( SQLITE_WITHIN(pPage->aDataEnd, pCell, pCell+info.nLocal) ){
|
||||
if( SQLITE_WITHIN(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){
|
||||
testcase( pSrc!=pPage );
|
||||
*pRC = SQLITE_CORRUPT_BKPT;
|
||||
return;
|
||||
}
|
||||
@ -3491,7 +3493,7 @@ static int setChildPtrmaps(MemPage *pPage){
|
||||
for(i=0; i<nCell; i++){
|
||||
u8 *pCell = findCell(pPage, i);
|
||||
|
||||
ptrmapPutOvflPtr(pPage, pCell, &rc);
|
||||
ptrmapPutOvflPtr(pPage, pPage, pCell, &rc);
|
||||
|
||||
if( !pPage->leaf ){
|
||||
Pgno childPgno = get4byte(pCell);
|
||||
@ -6677,7 +6679,7 @@ static void insertCell(
|
||||
/* The cell may contain a pointer to an overflow page. If so, write
|
||||
** the entry for the overflow page into the pointer map.
|
||||
*/
|
||||
ptrmapPutOvflPtr(pPage, pCell, pRC);
|
||||
ptrmapPutOvflPtr(pPage, pPage, pCell, pRC);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -7093,7 +7095,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
|
||||
if( ISAUTOVACUUM ){
|
||||
ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc);
|
||||
if( szCell>pNew->minLocal ){
|
||||
ptrmapPutOvflPtr(pNew, pCell, &rc);
|
||||
ptrmapPutOvflPtr(pNew, pNew, pCell, &rc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7316,10 +7318,6 @@ static int balance_nonroot(
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
|
||||
|
||||
#if 0
|
||||
TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
|
||||
#endif
|
||||
|
||||
/* At this point pParent may have at most one overflow cell. And if
|
||||
** this overflow cell is present, it must be the cell with
|
||||
** index iParentIdx. This scenario comes about when this function
|
||||
@ -7785,7 +7783,8 @@ static int balance_nonroot(
|
||||
** populated, not here.
|
||||
*/
|
||||
if( ISAUTOVACUUM ){
|
||||
MemPage *pNew = apNew[0];
|
||||
MemPage *pOld;
|
||||
MemPage *pNew = pOld = apNew[0];
|
||||
u8 *aOld = pNew->aData;
|
||||
int cntOldNext = pNew->nCell + pNew->nOverflow;
|
||||
int usableSize = pBt->usableSize;
|
||||
@ -7795,7 +7794,7 @@ static int balance_nonroot(
|
||||
for(i=0; i<b.nCell; i++){
|
||||
u8 *pCell = b.apCell[i];
|
||||
if( i==cntOldNext ){
|
||||
MemPage *pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld];
|
||||
pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld];
|
||||
cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
|
||||
aOld = pOld->aData;
|
||||
}
|
||||
@ -7818,7 +7817,7 @@ static int balance_nonroot(
|
||||
ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
|
||||
}
|
||||
if( cachedCellSize(&b,i)>pNew->minLocal ){
|
||||
ptrmapPutOvflPtr(pNew, pCell, &rc);
|
||||
ptrmapPutOvflPtr(pNew, pOld, pCell, &rc);
|
||||
}
|
||||
if( rc ) goto balance_cleanup;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user