From: dan Date: Wed, 26 Aug 2015 18:02:20 +0000 (+0000) Subject: Fix a problem allowing some conflicting transactions to be committed. X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=de36c76a2369c76d6edf53f11381357685dff889;p=thirdparty%2Fsqlite.git Fix a problem allowing some conflicting transactions to be committed. FossilOrigin-Name: a0566382d564ca17fd13475a44fed8f714742d97 --- diff --git a/manifest b/manifest index 452016bd91..79ab2b14bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smiscellaneous\stest\scases\sfor\sconcurrent\stransactions. -D 2015-08-25T19:10:29.114 +C Fix\sa\sproblem\sallowing\ssome\sconflicting\stransactions\sto\sbe\scommitted. +D 2015-08-26T18:02:20.162 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 a21412a803f0eafecf48e707fb97c64368a0d267 +F src/wal.c 44ec009f7742a660d3558845e47e870af4542689 F src/wal.h 903ef67e17f8b466dc7cfc4186fc23e80be10ff8 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba F src/where.c 66518a14a1238611aa0744d6980b6b7f544f4816 @@ -526,7 +526,7 @@ F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b F test/concfault.test 500f17c3fcfe7705114422bcc6ddd3c740001a43 F test/concurrent.test ecf97fdcfb11dda1db52b2714d7d52d0922789f1 F test/concurrent2.test de43cd6703360dc6268907f1617f0d353d8a43c1 -F test/concurrent3.test 7dcf81372c06cbac58e7e630aebf7292945947bb +F test/concurrent3.test 8474b7ac80bc977bab4fe014c0b036c16779d8cb F test/conflict.test 841bcf7cabbfca39c577eb8411ea8601843b46a8 F test/conflict2.test 0d3af4fb534fa1bd020c79960bb56e4d52655f09 F test/conflict3.test dec0634c0f31dec9a4b01c63063e939f0cd21b6b @@ -1382,7 +1382,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 f32b57b49311693eb0c0c9f6f14859e7b1fa93d8 -R cbe24c6dda59af48460d1125c5ffff88 +P 779b1d0e17bc54062b2b09cdbf94e9e2f4bae4f7 +R 522c73a54721e2428308711f9566b92e U dan -Z 967a64b7790792e3ecfbe18cee7c81a2 +Z 5afacf522fa16d68d46082708ed9d148 diff --git a/manifest.uuid b/manifest.uuid index 16d88ba06c..5d4bfea3dc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -779b1d0e17bc54062b2b09cdbf94e9e2f4bae4f7 \ No newline at end of file +a0566382d564ca17fd13475a44fed8f714742d97 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 4db4209750..445d084628 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2680,7 +2680,7 @@ int sqlite3WalLockForCommit(Wal *pWal, PgHdr *pPage1, Bitvec *pAllRead){ int iMax = (iHash==0) ? HASHTABLE_NPAGE_ONE : HASHTABLE_NPAGE; if( iMin<1 ) iMin = 1; if( iMax>head.mxFrame ) iMax = head.mxFrame; - for(i=iMin; i<=iMax; i++){ + for(i=iMin; rc==SQLITE_OK && i<=iMax; i++){ PgHdr *pPg; if( aPgno[i]==1 ){ /* Check that the schema cookie has not been modified. If diff --git a/test/concurrent3.test b/test/concurrent3.test index 25e5d7c6c9..a90fa2b973 100644 --- a/test/concurrent3.test +++ b/test/concurrent3.test @@ -24,6 +24,12 @@ ifcapable !concurrent { return } +db close +sqlite3_shutdown +#test_sqlite3_log xLog +#proc xLog {error_code msg} { puts "$error_code: $msg" } +reset_db + proc create_schema {} { db eval { PRAGMA journal_mode = wal; @@ -128,5 +134,96 @@ foreach {tn oplist} { } } +#------------------------------------------------------------------------- +# +proc create_schema2 {} { + db eval { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x INTEGER PRIMARY KEY, y); + CREATE INDEX i1 ON t1(y); + } +} + +proc randint {nMax} { + db eval {SELECT abs(random() % $nMax)} +} + +proc do_sql_op2 {db iOp} { + switch -- $iOp { + i { + # Insert 1 rows. + set r [randint 1000000000] + set ::rows($r) 1 + #puts "insert row $r" + $db eval { INSERT OR IGNORE INTO t1 VALUES($r, randomblob(50)); } + } + + d { + # Insert 1 row + set keys [array names ::rows] + set r [randint [llength $keys]] + set rowid [lindex $keys $r] + $db eval { DELETE FROM t1 WHERE x=$rowid } + unset ::rows($rowid) + } + } +} + +foreach {tn nRepeat oplist} { + - - ---------------------------- + 1 100 { 1iiiiiiiiii } + 2 100 { 1i 2d } + 3 100 { 1d 2i } + 4 50 { 1d 2i 3d } + 5 500 { 1i 2i 3i 4i } +} { + if {[string range $oplist 0 0]=="-"} { + array unset rows + reset_db + create_schema2 + continue + } + + foreach db $DBLIST { + sqlite3 $db test.db + set stats($db,0) 0 + set stats($db,1) 0 + } + array unset used + + do_test 2.$tn { + + for {set i 0} {$i < $nRepeat} {incr i} { + foreach db $DBLIST { $db eval "BEGIN CONCURRENT" } + + foreach op $oplist { + set iDb [string range $op 0 0] + set used(db$iDb) 1 + foreach char [split [string range $op 1 end] {}] { + do_sql_op2 "db$iDb" $char + } + } + + foreach db $DBLIST { + if {$i==272 && $db=="db4"} breakpoint + set rc [catch { $db eval COMMIT } msg] + if {$rc} { $db eval ROLLBACK } + incr stats($db,$rc) + } + set res [db eval {PRAGMA integrity_check}] + if {$res != "ok"} { puts "after $db $rc: $res" ; after 1000000 } + } + } {} + + foreach db $DBLIST { + $db close + } + foreach k [lsort [array names used]] { + puts "$k: $stats($k,0) committed, $stats($k,1) rolled back" + } +} + + + finish_test