From: dan Date: Sat, 22 Aug 2015 20:32:39 +0000 (+0000) Subject: Fix a problem to do with detecting unlocked transaction conflicts if another client... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0c52b373a0d3606ca4475f506d67be9c568a7186;p=thirdparty%2Fsqlite.git Fix a problem to do with detecting unlocked transaction conflicts if another client restarts the wal while the transaction is running. FossilOrigin-Name: e3968b256282d8c0a87c26667b1ba02faf7a5a17 --- diff --git a/manifest b/manifest index bc04296ba0..1778b94253 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sfurther\stests\sfor\sdeferred\spage\sallocation.\sAnd\sfixes\sfor\sthe\ssame. -D 2015-08-22T17:28:55.533 +C Fix\sa\sproblem\sto\sdo\swith\sdetecting\sunlocked\stransaction\sconflicts\sif\sanother\sclient\srestarts\sthe\swal\swhile\sthe\stransaction\sis\srunning. +D 2015-08-22T20:32:39.272 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e2218eb228374422969de7b1680eda6864affcef F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -411,7 +411,7 @@ F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 F src/vtab.c d31174e4c8f592febab3fa7f69e18320b4fd657a F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb -F src/wal.c 0ba4899f02457be91fe5bc734638fee00c807f64 +F src/wal.c 4c69d27ed7ec7006008d8309dc5c9ab742273c12 F src/wal.h a701096b9bf5761b8c5f4b07082249e1950afc9a F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba F src/where.c 66518a14a1238611aa0744d6980b6b7f544f4816 @@ -1228,8 +1228,8 @@ F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264 F test/unique2.test 41e7f83c6827605991160a31380148a9fc5f1339 F test/unixexcl.test cd6c765f75e50e8e2c2ba763149e5d340ea19825 F test/unlocked.test d143a871bd874311d4e5c98ce458218ca6b579fd -F test/unlocked2.test 7f913b404cda03f22bc7b299e8eb82a34d2880c5 -F test/unlocked3.test 4facd06286885faa9bd53713fa3d701ca403aeb2 +F test/unlocked2.test aaa42a08052a146466220b6c3a062ff3c4776ad6 +F test/unlocked3.test 06173e406a8c1a550448f79329ed4c3311905062 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32 F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b @@ -1381,7 +1381,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 c2327a3b8e5d604ab948b1e9f6cfc401429e51db -R c62a3f455b34280d099a1332c1c4f1e4 +P ed0a31be726e60115a5dd73d4ed580201b400ab7 +R 4d5e4d57de949c83b8660752ea3918ee U dan -Z 1442e612d3eba52580ab50755ceb943f +Z 75094882a86841f2760b97ee8543ae22 diff --git a/manifest.uuid b/manifest.uuid index 545070a432..c18cc52736 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed0a31be726e60115a5dd73d4ed580201b400ab7 \ No newline at end of file +e3968b256282d8c0a87c26667b1ba02faf7a5a17 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index a9d8a44086..fcf5a15044 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2594,13 +2594,14 @@ int sqlite3WalLockForCommit(Wal *pWal, PgHdr *pPage1, Bitvec *pAllRead){ /* TODO: Check header checksum is good here. */ if( memcmp(&pWal->hdr, (void*)pHead, sizeof(WalIndexHdr))!=0 ){ - /* TODO: Is this safe? Because it holds the WRITER lock this thread - ** has exclusive access to the live header, but might it be corrupt? - ** This code should check that the wal-index-header is Ok, and return - ** SQLITE_BUSY_SNAPSHOT if it is not. */ int iHash; int iLastHash = walFramePage(pHead->mxFrame); - for(iHash=walFramePage(pWal->hdr.mxFrame+1); iHash<=iLastHash; iHash++){ + u32 iFirst = pWal->hdr.mxFrame+1; /* First wal frame to check */ + if( memcmp(pWal->hdr.aSalt, (u32*)pHead->aSalt, sizeof(u32)*2) ){ + assert( pWal->readLock==0 ); + iFirst = 1; + } + for(iHash=walFramePage(iFirst); iHash<=iLastHash; iHash++){ volatile ht_slot *aHash; volatile u32 *aPgno; u32 iZero; @@ -2608,7 +2609,7 @@ int sqlite3WalLockForCommit(Wal *pWal, PgHdr *pPage1, Bitvec *pAllRead){ rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero); if( rc==SQLITE_OK ){ int i; - int iMin = (pWal->hdr.mxFrame+1 - iZero); + int iMin = (iFirst - iZero); int iMax = (iHash==0) ? HASHTABLE_NPAGE_ONE : HASHTABLE_NPAGE; if( iMin<1 ) iMin = 1; if( iMax>pHead->mxFrame ) iMax = pHead->mxFrame; diff --git a/test/unlocked2.test b/test/unlocked2.test index 927fe3e675..6953753643 100644 --- a/test/unlocked2.test +++ b/test/unlocked2.test @@ -257,5 +257,40 @@ do_multiclient_test tn { do_test 5.$tn.5 { sql3 { PRAGMA integrity_check } } {ok} } +#------------------------------------------------------------------------- +# +do_multiclient_test tn { + do_test 6.$tn.1 { + sql1 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(randomblob(1500)); + PRAGMA wal_checkpoint; + } + } {wal 0 5 5} + + do_test 6.$tn.2 { + sql1 { + BEGIN UNLOCKED; + INSERT INTO t1 VALUES(randomblob(1500)); + INSERT INTO t1 VALUES(randomblob(1500)); + } + } {} + + do_test 6.$tn.3 { + sql2 { + BEGIN; + INSERT INTO t1 VALUES(randomblob(1500)); + INSERT INTO t1 VALUES(randomblob(1500)); + COMMIT; + } + } {} + + do_test 6.$tn.4 { + list [catch { sql1 COMMIT } msg] $msg + } {1 {database is locked}} + do_test 6.$tn.5 { sql3 { PRAGMA integrity_check } } {ok} + do_test 6.$tn.5 { sql3 { SELECT count(*) from t1 } } {3} +} finish_test diff --git a/test/unlocked3.test b/test/unlocked3.test index 04e741dc5b..b4deaf9a92 100644 --- a/test/unlocked3.test +++ b/test/unlocked3.test @@ -55,6 +55,22 @@ proc do_sql_op {iTbl iOp} { " } + "D" { + set sql " + DELETE FROM t$iTbl WHERE rowid IN ( + SELECT rowid FROM t$iTbl o WHERE ( + SELECT count(*) FROM t$iTbl i WHERE i.rowid