From: dan Date: Mon, 3 Dec 2018 19:29:37 +0000 (+0000) Subject: Cherrypick a couple of fixes from begin-concurrent-pnu into this branch. The X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51883dfc8bcbba9f409d2d1efe8cadbd501000c3;p=thirdparty%2Fsqlite.git Cherrypick a couple of fixes from begin-concurrent-pnu into this branch. The differences between the two branches are now that this one does not have "PRAGMA noop_update" or the mutex-free PRNG. FossilOrigin-Name: a56506b9387a067ef259504d127694ad20223f4b08781d1676ff7f5fdd9443d8 --- diff --git a/manifest b/manifest index eadf9a7db7..b00fa69f09 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bring\sup\sto\sdate\swith\sversion\s3.26.0. -D 2018-12-03T18:15:52.710 +C Cherrypick\sa\scouple\sof\sfixes\sfrom\sbegin-concurrent-pnu\sinto\sthis\sbranch.\sThe\ndifferences\sbetween\sthe\stwo\sbranches\sare\snow\sthat\sthis\sone\sdoes\snot\shave\n"PRAGMA\snoop_update"\sor\sthe\smutex-free\sPRNG. +D 2018-12-03T19:29:37.766 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in a050c8670ea0d7b37b2192306cbb50d392acd9902b84e9b56f3444d006f97a6c @@ -451,7 +451,7 @@ F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab F src/bitvec.c 8433d9e98dd6f2ea3286e0d2fe5d65de1bfc18a706486eb2026b01be066b5806 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 4ad4c92bbd327b72cc7b3444de6b6d0f416e29ef0b21b2c3ec16165ba4070804 +F src/btree.c 4a2184be69d491d4b0228d4e397d67cb0802bbec06e7615b485ea1af69a131f6 F src/btree.h 1ed41c71481a1196a520064f2282bc13d768bbd8ae2850e319a3048f8ee7cb3d F src/btreeInt.h 6c65e6c96f561596f6870c79a64d4706af81613881d7947e3f063e923f14115f F src/build.c 5e04fb8528a4a915ed9af94b5cd068e53f2cfa9824d37464c4059279ea9bc8a0 @@ -735,6 +735,8 @@ F test/concurrent2.test 9dfbeb0a323733fe1d13443371734bb94a674dbf777f464365475903 F test/concurrent3.test 530671ac706f6a1d0f4992dbdd33a86408330d03cd90fb9e82ecb1b27f5fd081 F test/concurrent4.test e0b12cd467137e50259df3b4f837507e82aaa07c35941c88664dc8ed1d089c44 F test/concurrent5.test 0c16cbf7446af162a14e6def30445e94016064eb994e5aa4ebb2bebc59554176 +F test/concurrent6.test a7860e9ca13bb5fb76bcf41c5524fbfa9c37e6e258ecf84ffb5748a272488c67 +F test/concurrent7.test b96fa5c4cfdf8d5c0bc66b6934214500bad0260884a736f054ccc76e81aae85d F test/conflict.test 029faa2d81a0d1cafb5f88614beb663d972c01db F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c F test/conflict3.test a83db76a6c3503b2fa057c7bfb08c318d8a422202d8bc5b86226e078e5b49ff9 @@ -1790,7 +1792,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 28a615a2e0f48b0fee3eaf7841ff902e069fa6c221df6ad9a57b8709c88561fb bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9 -R ad7ac98b07a5e19a9d448dcba578a20a -U drh -Z e005195a2c11998dc5b1c6dec19b9447 +P f0ddb358cc68e5ec6d9e758893ab3da058a3b2e705124a7449279c992e672a4a +Q +50c8952c92b9f0c61935fb0df04ed1426d9e266a812071b7bf5b0215c5552757 +Q +570233716032f258b878d52c4d5a47e07292d66fa84e3a85c0388ec15efee625 +Q +dc0fc2aa7cbefeb5f0ba8c992fd3e9adcfb5a4d61e2321c1bd93f4d36ba9aafc +R 0b6ca72792de50021b48db0500a10b60 +U dan +Z e7051457303763dcda2174967ac468b5 diff --git a/manifest.uuid b/manifest.uuid index d0b8f54408..13eb6ed24f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f0ddb358cc68e5ec6d9e758893ab3da058a3b2e705124a7449279c992e672a4a \ No newline at end of file +a56506b9387a067ef259504d127694ad20223f4b08781d1676ff7f5fdd9443d8 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 828d63c180..f4f7365b92 100644 --- a/src/btree.c +++ b/src/btree.c @@ -656,11 +656,48 @@ static void btreePtrmapDelete(BtShared *pBt){ pBt->pMap = 0; } } + +/* +** Check that the pointer-map does not contain any entries with a parent +** page of 0. Call sqlite3_log() multiple times to output the entire +** data structure if it does. +*/ +static void btreePtrmapCheck(BtShared *pBt, Pgno nPage){ + Pgno i; + int bProblem = 0; + BtreePtrmap *p = pBt->pMap; + + for(i=p->iFirst; i<=nPage; i++){ + PtrmapEntry *pEntry = &p->aPtr[i-p->iFirst]; + if( pEntry->eType==PTRMAP_OVERFLOW1 + || pEntry->eType==PTRMAP_OVERFLOW2 + || pEntry->eType==PTRMAP_BTREE + ){ + if( pEntry->parent==0 ){ + bProblem = 1; + break; + } + } + } + + if( bProblem ){ + for(i=p->iFirst; i<=nPage; i++){ + PtrmapEntry *pEntry = &p->aPtr[i-p->iFirst]; + sqlite3_log(SQLITE_CORRUPT, + "btreePtrmapCheck: pgno=%d eType=%d parent=%d", + (int)i, (int)pEntry->eType, (int)pEntry->parent + ); + } + abort(); + } +} + #else /* SQLITE_OMIT_CONCURRENT */ # define btreePtrmapAllocate(x) SQLITE_OK # define btreePtrmapDelete(x) # define btreePtrmapBegin(x,y) SQLITE_OK # define btreePtrmapEnd(x,y,z) +# define btreePtrmapCheck(y,z) #endif /* SQLITE_OMIT_CONCURRENT */ static void releasePage(MemPage *pPage); /* Forward reference */ @@ -4152,7 +4189,10 @@ static int btreeRelocateRange( if( pEntry->eType==PTRMAP_FREEPAGE ){ Pgno dummy; rc = allocateBtreePage(pBt, &pFree, &dummy, iPg, BTALLOC_EXACT); - releasePage(pFree); + if( pFree ){ + assert( sqlite3PagerPageRefcount(pFree->pDbPage)==1 ); + sqlite3PcacheDrop(pFree->pDbPage); + } assert( rc!=SQLITE_OK || dummy==iPg ); }else if( pnCurrent ){ btreeGetPage(pBt, iPg, &pPg, 0); @@ -4210,6 +4250,8 @@ static int btreeFixUnlocked(Btree *p){ Pgno iHTrunk = get4byte(&p1[32]); u32 nHFree = get4byte(&p1[36]); + btreePtrmapCheck(pBt, nPage); + /* Attach the head database free list to the end of the current ** transactions free-list (if any). */ if( iTrunk!=0 ){ @@ -4236,10 +4278,12 @@ static int btreeFixUnlocked(Btree *p){ /* The current transaction allocated pages pMap->iFirst through ** nPage (inclusive) at the end of the database file. Meanwhile, ** other transactions have allocated (iFirst..nHPage). So move - ** pages (iFirst..MIN(nPage,nHPage)) to (MAX(nPage,nHPage)+1). */ + ** pages (iFirst..MIN(nPage,nHPage)) to (MAX(nPage,nHPage)+1). */ Pgno iLast = MIN(nPage, nHPage); /* Last page to move */ Pgno nCurrent; /* Current size of db */ + nCurrent = MAX(nPage, nHPage); + pBt->nPage = nCurrent; rc = btreeRelocateRange(pBt, pMap->iFirst, iLast, &nCurrent); /* There are now no collisions with the snapshot at the head of the @@ -6229,7 +6273,7 @@ static int allocateBtreePage( ** stores stores the total number of pages on the freelist. */ n = get4byte(&pPage1->aData[36]); testcase( n==mxPage-1 ); - if( ISCONCURRENT==0 && n>=mxPage ){ + if( n>=mxPage ){ return SQLITE_CORRUPT_BKPT; } diff --git a/test/concurrent6.test b/test/concurrent6.test new file mode 100644 index 0000000000..44718b7dbc --- /dev/null +++ b/test/concurrent6.test @@ -0,0 +1,60 @@ +# 2017 May 26 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +source $testdir/wal_common.tcl +set ::testprefix concurrent6 + +ifcapable !concurrent { + finish_test + return +} + +sqlite3 db2 test.db + +do_execsql_test 1.0 { + PRAGMA page_size = 1024; + PRAGMA journal_mode = wal; + CREATE TABLE t1(x); + CREATE TABLE t2(x); + CREATE TABLE t3(x); + CREATE TABLE t4(x); + + INSERT INTO t1 VALUES(zeroblob(1500)); +} {wal} + +do_execsql_test -db db2 1.1 { + BEGIN CONCURRENT; + INSERT INTO t3 VALUES(zeroblob(4000)); + DELETE FROM t1; +} + +do_execsql_test 1.2 { + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100) + INSERT INTO t2 SELECT zeroblob(1000) FROM s; + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100) + INSERT INTO t4 SELECT zeroblob(1000) FROM s; + + DELETE FROM t4; +} + +do_execsql_test -db db2 1.3 { + COMMIT; +} + + +finish_test + diff --git a/test/concurrent7.test b/test/concurrent7.test new file mode 100644 index 0000000000..871e428031 --- /dev/null +++ b/test/concurrent7.test @@ -0,0 +1,52 @@ +# 2018 Jan 5 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix concurrent7 + +sqlite3 db2 test.db + +do_execsql_test 1 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x); + CREATE TABLE t2(x); +} {wal} + +do_execsql_test -db db2 2 { + SELECT * FROM t1; +} + +do_execsql_test 3 { + BEGIN CONCURRENT; + INSERT INTO t1 VALUES(randomblob(1500)); + INSERT INTO t1 VALUES(randomblob(1500)); + DELETE FROM t1 WHERE rowid = 1; +} + +do_execsql_test -db db2 4 { + INSERT INTO t2 VALUES(randomblob(1500)); + INSERT INTO t2 VALUES(randomblob(1500)); + INSERT INTO t2 VALUES(randomblob(1500)); + INSERT INTO t2 VALUES(randomblob(1500)); + DELETE FROM t2 WHERE rowid IN (1, 2); +} + +do_execsql_test 5 { + COMMIT; + PRAGMA integrity_check; +} {ok} + +finish_test + +