From 785a38f066312184bd947d05b76b576adf7afa50 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 8 Dec 2014 20:29:23 +0000 Subject: [PATCH] Add extra tests to e_walckpt.test. FossilOrigin-Name: d6832aa24c8d93b4532a651b86605bd0a0d0aa78 --- manifest | 12 +-- manifest.uuid | 2 +- test/e_walckpt.test | 202 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 207 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c02b815662..ec93f98b98 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\smutex\scalls\saround\sa\scall\sto\ssqlite3SchemaGet()\swithin\ssqlite3_open(). -D 2014-12-08T20:20:16.943 +C Add\sextra\stests\sto\se_walckpt.test. +D 2014-12-08T20:29:23.119 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6c4f961fa91d0b4fa121946a19f9e5eac2f2f809 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -478,7 +478,7 @@ F test/e_update.test 312cb8f5ccfe41515a6bb092f8ea562a9bd54d52 F test/e_uri.test 5ae33760fb2039c61aa2d90886f1664664173585 F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9 F test/e_wal.test 0967f0b8f1dfda871dc7b9b5574198f1f4f7d69a -F test/e_walckpt.test de5a8d86c5b95569309c6da796dbea870c22e003 +F test/e_walckpt.test 18de8fca6b74f29bf7d24a2e267eec749b8fec50 F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473 F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40 @@ -1226,7 +1226,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7047ce32a234484b8ba15311e6560aa74ff692c9 -R 4e003866b87e6ab46d2d338deacb76ac +P 45415899545767888d36dcc0bafaf0ef415d94c2 +R 4d0b2e4f612d2fa1f8086c766c614446 U dan -Z bc6db0f22fd7a4f485084a7efedf6bfd +Z 31f22aa5ae36276bb2e8d99e02610d8f diff --git a/manifest.uuid b/manifest.uuid index 0ebf53643d..804aec562f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45415899545767888d36dcc0bafaf0ef415d94c2 \ No newline at end of file +d6832aa24c8d93b4532a651b86605bd0a0d0aa78 \ No newline at end of file diff --git a/test/e_walckpt.test b/test/e_walckpt.test index 8b0aae798a..f0edc46bee 100644 --- a/test/e_walckpt.test +++ b/test/e_walckpt.test @@ -69,9 +69,9 @@ foreach {tn script} { 2 { proc checkpoint {db mode args} { - set sql "PRAGMA wal_checkpoint" + set sql "PRAGMA wal_checkpoint = $mode" if {[llength $args] && [lindex $args 0]!=""} { - set sql "PRAGMA [lindex $args 0].wal_checkpoint" + set sql "PRAGMA [lindex $args 0].wal_checkpoint = $mode" } set rc [catch { $db eval $sql } msg] if {$rc} { @@ -261,6 +261,204 @@ foreach {tn script} { db2 close tvfs delete + proc busy_handler {mode busy_handler_mode n} { + incr ::busy_handler_counter + switch -- $busy_handler_mode { + 1 { + # Do nothing. Do not block. + return 1 + } + + 2 { + # Close first the reader, then later the writer. + if {$n==5} { catch {db2 eval commit} } + if {$n==10} { catch {db3 eval commit} } + return 0 + } + + 3 { + # Close first the writer, then later the reader. + if {$n==5} { catch {db2 eval commit} } + if {$n==10} { catch {db3 eval commit} } + return 0 + } + } + } + + foreach {mode busy_handler_mode} { + passive 1 + full 1 + full 2 + full 3 + } { + + set ::sync_counter 0 + + proc tvfs_callback {method args} { + set tail [file tail [lindex $args 0]] + if {$method == "xSync" && $tail == "test.db"} { + incr ::sync_counter + } + + if {$method == "xWrite" && $tail=="test.db"} { + if {$::write_ok < 0} { + set ::write_ok [expr ![catch {db5 eval { BEGIN IMMEDIATE }}]] + catch { db5 eval ROLLBACK } + } + if {$::read_ok < 0} { + set ::read_ok [expr ![catch {db5 eval { SELECT * FROM t1 }}]] + } + } + } + + catch { db close } + forcedelete test.db + testvfs tvfs + sqlite3 db test.db -vfs tvfs + #tvfs filter xSync + tvfs script tvfs_callback + + do_execsql_test $tn.4.$mode.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(a, b); + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + } {wal} + + # Open a reader on the current database snapshot. + do_test $tn.4.$mode.1 { + sqlite3 db2 test.db -vfs tvfs + execsql { + BEGIN; + SELECT * FROM t1 UNION ALL SELECT * FROM t2; + } db2 + } {1 2 3 4 5 6} + + # Open a writer. Write a transaction. Then begin, but do not commit, + # a second transaction. + do_test $tn.4.$mode.2 { + sqlite3 db3 test.db -vfs tvfs + execsql { + INSERT INTO t2 VALUES(7, 8); + BEGIN; + INSERT INTO t2 VALUES(9, 10); + SELECT * FROM t1 UNION ALL SELECT * FROM t2; + } db3 + } {1 2 3 4 5 6 7 8 9 10} + + sqlite3 db5 test.db -vfs tvfs + + # Register a busy-handler with connection [db]. + # + db busy [list busy_handler $mode $busy_handler_mode] + set ::sync_counter 0 + set ::busy_handler_counter 0 + set ::read_ok -1 + set ::write_ok -1 + + do_test $tn.4.$mode.3 { + checkpoint db $mode main + set {} {} + } {} + + if { $mode=="passive" } { + # EVIDENCE-OF: R-16333-64433 Checkpoint as many frames as possible + # without waiting for any database readers or writers to finish, then + # sync the database file if all frames in the log were checkpointed. + # + # "As many frames as possible" means all but the last two transactions + # (the two that write to table t2, of which the scond is unfinished). + # So copying the db file only we see the t1 change, but not the t2 + # modifications. + # + # The busy handler is not invoked (see below) and the db reader and + # writer are still active - so the checkpointer did not wait for either + # readers or writers. As a result the checkpoint was not finished and + # so the db file is not synced. + # + # EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked + # in the SQLITE_CHECKPOINT_PASSIVE mode. + # + # It's not. Test case "$tn.4.$mode.6". + # + do_test $tn.4.$mode.4 { + forcecopy test.db abc.db + sqlite3 db4 abc.db + db4 eval { SELECT * FROM t1 UNION ALL SELECT * FROM t2 } + } {1 2 3 4 5 6} + do_test $tn.4.$mode.5 { set ::sync_counter } 0 + do_test $tn.4.$mode.6 { set ::busy_handler_counter } 0 + db4 close + + db2 eval COMMIT + db3 eval COMMIT + + # EVIDENCE-OF: R-65499-53765 On the other hand, passive mode might leave + # the checkpoint unfinished if there are concurrent readers or writers. + # + # The reader and writer have now dropped their locks. And so a + # checkpoint now is able to checkpoint more frames. Showing that the + # attempt above was left "unfinished". + # + # Also, because the checkpoint finishes this time, the db is synced. + # Which is part of R-16333-64433 above. + # + do_test $tn.4.$mode.7 { + checkpoint db $mode main + forcecopy test.db abc.db + sqlite3 db4 abc.db + db4 eval { SELECT * FROM t1 UNION ALL SELECT * FROM t2 } + } {1 2 3 4 5 6 7 8 9 10} + do_test $tn.4.$mode.6 { set ::sync_counter } 1 + do_test $tn.4.$mode.7 { set ::busy_handler_counter } 0 + db4 close + } + + if { $mode=="full" } { + if {$busy_handler_mode==2 || $busy_handler_mode==3} { + # EVIDENCE-OF: R-59171-47567 This mode blocks (it invokes the + # busy-handler callback) until there is no database writer and all + # readers are reading from the most recent database snapshot. + # + # Show that both the reader and writer have finished: + # + do_test $tn.4.$mode.7 { + list [catchsql COMMIT db2] [catchsql COMMIT db3] + } [list \ + {1 {cannot commit - no transaction is active}} \ + {1 {cannot commit - no transaction is active}} \ + ] + + # EVIDENCE-OF: R-29177-48281 It then checkpoints all frames in the log + # file and syncs the database file. + # + do_test $tn.4.$mode.8 { + forcecopy test.db abc.db + sqlite3 db4 abc.db + db4 eval { SELECT * FROM t1 UNION ALL SELECT * FROM t2 } + } {1 2 3 4 5 6 7 8 9 10} + do_test $tn.4.$mode.9 { set ::sync_counter } 1 + db4 close + + # EVIDENCE-OF: R-51867-44713 This mode blocks new database writers + # while it is pending, but new database readers are allowed to continue + # unimpeded. + do_test $tn.4.$mode.10 { + list $::write_ok $::read_ok + } {0 1} + + } + } + + db2 close + db3 close + db5 close + } + + db close + tvfs delete } #-----------------------------------------------------------------------