| OLD | NEW |
| 1 # 2010 May 5 | 1 # 2010 May 5 |
| 2 # | 2 # |
| 3 # The author disclaims copyright to this source code. In place of | 3 # The author disclaims copyright to this source code. In place of |
| 4 # a legal notice, here is a blessing: | 4 # a legal notice, here is a blessing: |
| 5 # | 5 # |
| 6 # May you do good and not evil. | 6 # May you do good and not evil. |
| 7 # May you find forgiveness for yourself and forgive others. | 7 # May you find forgiveness for yourself and forgive others. |
| 8 # May you share freely, never taking more than you give. | 8 # May you share freely, never taking more than you give. |
| 9 # | 9 # |
| 10 #*********************************************************************** | 10 #*********************************************************************** |
| 11 # This file implements regression tests for SQLite library. The | 11 # This file implements regression tests for SQLite library. The |
| 12 # focus of this file is testing the operation of the library in | 12 # focus of this file is testing the operation of the library in |
| 13 # "PRAGMA journal_mode=WAL" mode. | 13 # "PRAGMA journal_mode=WAL" mode. |
| 14 # | 14 # |
| 15 | 15 |
| 16 set testdir [file dirname $argv0] | 16 set testdir [file dirname $argv0] |
| 17 source $testdir/tester.tcl | 17 source $testdir/tester.tcl |
| 18 source $testdir/lock_common.tcl | 18 source $testdir/lock_common.tcl |
| 19 source $testdir/malloc_common.tcl | 19 source $testdir/malloc_common.tcl |
| 20 source $testdir/wal_common.tcl | 20 source $testdir/wal_common.tcl |
| 21 | 21 |
| 22 set testprefix wal2 | 22 set testprefix wal2 |
| 23 | 23 |
| 24 ifcapable !wal {finish_test ; return } | 24 ifcapable !wal {finish_test ; return } |
| 25 | 25 |
| 26 set sqlite_sync_count 0 |
| 27 proc cond_incr_sync_count {adj} { |
| 28 global sqlite_sync_count |
| 29 if {$::tcl_platform(platform) == "windows"} { |
| 30 incr sqlite_sync_count $adj |
| 31 } { |
| 32 ifcapable !dirsync { |
| 33 incr sqlite_sync_count $adj |
| 34 } |
| 35 } |
| 36 } |
| 37 |
| 26 proc set_tvfs_hdr {file args} { | 38 proc set_tvfs_hdr {file args} { |
| 27 | 39 |
| 28 # Set $nHdr to the number of bytes in the wal-index header: | 40 # Set $nHdr to the number of bytes in the wal-index header: |
| 29 set nHdr 48 | 41 set nHdr 48 |
| 30 set nInt [expr {$nHdr/4}] | 42 set nInt [expr {$nHdr/4}] |
| 31 | 43 |
| 32 if {[llength $args]>2} { | 44 if {[llength $args]>2} { |
| 33 error {wrong # args: should be "set_tvfs_hdr fileName ?val1? ?val2?"} | 45 error {wrong # args: should be "set_tvfs_hdr fileName ?val1? ?val2?"} |
| 34 } | 46 } |
| 35 | 47 |
| 36 set blob [tvfs shm $file] | 48 set blob [tvfs shm $file] |
| 49 if {$::tcl_platform(byteOrder)=="bigEndian"} {set fmt I} {set fmt i} |
| 37 | 50 |
| 38 if {[llength $args]} { | 51 if {[llength $args]} { |
| 39 set ia [lindex $args 0] | 52 set ia [lindex $args 0] |
| 40 set ib $ia | 53 set ib $ia |
| 41 if {[llength $args]==2} { | 54 if {[llength $args]==2} { |
| 42 set ib [lindex $args 1] | 55 set ib [lindex $args 1] |
| 43 } | 56 } |
| 44 binary scan $blob a[expr $nHdr*2]a* dummy tail | 57 binary scan $blob a[expr $nHdr*2]a* dummy tail |
| 45 set blob [binary format i${nInt}i${nInt}a* $ia $ib $tail] | 58 set blob [binary format ${fmt}${nInt}${fmt}${nInt}a* $ia $ib $tail] |
| 46 tvfs shm $file $blob | 59 tvfs shm $file $blob |
| 47 } | 60 } |
| 48 | 61 |
| 49 binary scan $blob i${nInt} ints | 62 binary scan $blob ${fmt}${nInt} ints |
| 50 return $ints | 63 return $ints |
| 51 } | 64 } |
| 52 | 65 |
| 53 proc incr_tvfs_hdr {file idx incrval} { | 66 proc incr_tvfs_hdr {file idx incrval} { |
| 54 set ints [set_tvfs_hdr $file] | 67 set ints [set_tvfs_hdr $file] |
| 55 set v [lindex $ints $idx] | 68 set v [lindex $ints $idx] |
| 56 incr v $incrval | 69 incr v $incrval |
| 57 lset ints $idx $v | 70 lset ints $idx $v |
| 58 set_tvfs_hdr $file $ints | 71 set_tvfs_hdr $file $ints |
| 59 } | 72 } |
| 60 | 73 |
| 61 | 74 |
| 62 #------------------------------------------------------------------------- | 75 #------------------------------------------------------------------------- |
| 63 # Test case wal2-1.*: | 76 # Test case wal2-1.*: |
| 64 # | 77 # |
| 65 # Set up a small database containing a single table. The database is not | 78 # Set up a small database containing a single table. The database is not |
| 66 # checkpointed during the test - all content resides in the log file. | 79 # checkpointed during the test - all content resides in the log file. |
| 67 # | 80 # |
| 68 # Two connections are established to the database file - a writer ([db]) | 81 # Two connections are established to the database file - a writer ([db]) |
| 69 # and a reader ([db2]). For each of the 8 integer fields in the wal-index | 82 # and a reader ([db2]). For each of the 8 integer fields in the wal-index |
| 70 # header (6 fields and 2 checksum values), do the following: | 83 # header (6 fields and 2 checksum values), do the following: |
| 71 # | 84 # |
| 72 # 1. Modify the database using the writer. | 85 # 1. Modify the database using the writer. |
| 73 # | 86 # |
| 74 # 2. Attempt to read the database using the reader. Before the reader | 87 # 2. Attempt to read the database using the reader. Before the reader |
| 75 # has a chance to snapshot the wal-index header, increment one | 88 # has a chance to snapshot the wal-index header, increment one |
| 76 # of the the integer fields (so that the reader ends up with a corrupted | 89 # of the integer fields (so that the reader ends up with a corrupted |
| 77 # header). | 90 # header). |
| 78 # | 91 # |
| 79 # 3. Check that the reader recovers the wal-index and reads the correct | 92 # 3. Check that the reader recovers the wal-index and reads the correct |
| 80 # database content. | 93 # database content. |
| 81 # | 94 # |
| 82 do_test wal2-1.0 { | 95 do_test wal2-1.0 { |
| 83 proc tvfs_cb {method filename args} { | 96 proc tvfs_cb {method filename args} { |
| 84 set ::filename $filename | 97 set ::filename $filename |
| 85 return SQLITE_OK | 98 return SQLITE_OK |
| 86 } | 99 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 106 } {4 10} | 119 } {4 10} |
| 107 do_test wal2-1.1 { | 120 do_test wal2-1.1 { |
| 108 execsql { SELECT count(a), sum(a) FROM t1 } db2 | 121 execsql { SELECT count(a), sum(a) FROM t1 } db2 |
| 109 } {4 10} | 122 } {4 10} |
| 110 | 123 |
| 111 set RECOVER [list \ | 124 set RECOVER [list \ |
| 112 {0 1 lock exclusive} {1 7 lock exclusive} \ | 125 {0 1 lock exclusive} {1 7 lock exclusive} \ |
| 113 {1 7 unlock exclusive} {0 1 unlock exclusive} \ | 126 {1 7 unlock exclusive} {0 1 unlock exclusive} \ |
| 114 ] | 127 ] |
| 115 set READ [list \ | 128 set READ [list \ |
| 129 {4 1 lock shared} {4 1 unlock shared} \ |
| 130 ] |
| 131 set INITSLOT [list \ |
| 116 {4 1 lock exclusive} {4 1 unlock exclusive} \ | 132 {4 1 lock exclusive} {4 1 unlock exclusive} \ |
| 117 {4 1 lock shared} {4 1 unlock shared} \ | |
| 118 ] | 133 ] |
| 119 | 134 |
| 120 foreach {tn iInsert res wal_index_hdr_mod wal_locks} " | 135 foreach {tn iInsert res wal_index_hdr_mod wal_locks} " |
| 121 2 5 {5 15} 0 {$RECOVER $READ} | 136 2 5 {5 15} 0 {$RECOVER $READ} |
| 122 3 6 {6 21} 1 {$RECOVER $READ} | 137 3 6 {6 21} 1 {$RECOVER $READ} |
| 123 4 7 {7 28} 2 {$RECOVER $READ} | 138 4 7 {7 28} 2 {$RECOVER $READ} |
| 124 5 8 {8 36} 3 {$RECOVER $READ} | 139 5 8 {8 36} 3 {$RECOVER $READ} |
| 125 6 9 {9 45} 4 {$RECOVER $READ} | 140 6 9 {9 45} 4 {$RECOVER $READ} |
| 126 7 10 {10 55} 5 {$RECOVER $READ} | 141 7 10 {10 55} 5 {$RECOVER $READ} |
| 127 8 11 {11 66} 6 {$RECOVER $READ} | 142 8 11 {11 66} 6 {$RECOVER $READ} |
| 128 9 12 {12 78} 7 {$RECOVER $READ} | 143 9 12 {12 78} 7 {$RECOVER $READ} |
| 129 10 13 {13 91} 8 {$RECOVER $READ} | 144 10 13 {13 91} 8 {$RECOVER $READ} |
| 130 11 14 {14 105} 9 {$RECOVER $READ} | 145 11 14 {14 105} 9 {$RECOVER $READ} |
| 131 12 15 {15 120} -1 {$READ} | 146 12 15 {15 120} -1 {$INITSLOT $READ} |
| 132 " { | 147 " { |
| 133 | 148 |
| 134 do_test wal2-1.$tn.1 { | 149 do_test wal2-1.$tn.1 { |
| 135 execsql { INSERT INTO t1 VALUES($iInsert) } | 150 execsql { INSERT INTO t1 VALUES($iInsert) } |
| 136 set ::locks [list] | 151 set ::locks [list] |
| 137 proc tvfs_cb {method args} { | 152 proc tvfs_cb {method args} { |
| 138 lappend ::locks [lindex $args 2] | 153 lappend ::locks [lindex $args 2] |
| 139 return SQLITE_OK | 154 return SQLITE_OK |
| 140 } | 155 } |
| 141 tvfs filter xShmLock | 156 tvfs filter xShmLock |
| 142 if {$::wal_index_hdr_mod >= 0} { | 157 if {$::wal_index_hdr_mod >= 0} { |
| 143 incr_tvfs_hdr $::filename $::wal_index_hdr_mod 1 | 158 incr_tvfs_hdr $::filename $::wal_index_hdr_mod 1 |
| 144 } | 159 } |
| 145 execsql { SELECT count(a), sum(a) FROM t1 } db2 | 160 execsql { SELECT count(a), sum(a) FROM t1 } db2 |
| 146 } $res | 161 } $res |
| 147 | 162 |
| 148 do_test wal2-1.$tn.2 { | 163 do_test wal2-1.$tn.2 { |
| 149 set ::locks | 164 set ::locks |
| 150 } $wal_locks | 165 } $wal_locks |
| 151 } | 166 } |
| 152 db close | 167 db close |
| 153 db2 close | 168 db2 close |
| 154 tvfs delete | 169 tvfs delete |
| 155 file delete -force test.db test.db-wal test.db-journal | 170 forcedelete test.db test.db-wal test.db-journal |
| 156 | 171 |
| 157 #------------------------------------------------------------------------- | 172 #------------------------------------------------------------------------- |
| 158 # This test case is very similar to the previous one, except, after | 173 # This test case is very similar to the previous one, except, after |
| 159 # the reader reads the corrupt wal-index header, but before it has | 174 # the reader reads the corrupt wal-index header, but before it has |
| 160 # a chance to re-read it under the cover of the RECOVER lock, the | 175 # a chance to re-read it under the cover of the RECOVER lock, the |
| 161 # wal-index header is replaced with a valid, but out-of-date, header. | 176 # wal-index header is replaced with a valid, but out-of-date, header. |
| 162 # | 177 # |
| 163 # Because the header checksum looks Ok, the reader does not run recovery, | 178 # Because the header checksum looks Ok, the reader does not run recovery, |
| 164 # it simply drops back to a READ lock and proceeds. But because the | 179 # it simply drops back to a READ lock and proceeds. But because the |
| 165 # header is out-of-date, the reader reads the out-of-date snapshot. | 180 # header is out-of-date, the reader reads the out-of-date snapshot. |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 | 267 |
| 253 if {$::wal_index_hdr_mod >= 0} { | 268 if {$::wal_index_hdr_mod >= 0} { |
| 254 incr_tvfs_hdr $::filename $::wal_index_hdr_mod 1 | 269 incr_tvfs_hdr $::filename $::wal_index_hdr_mod 1 |
| 255 } | 270 } |
| 256 execsql { SELECT count(a), sum(a) FROM t1 } db2 | 271 execsql { SELECT count(a), sum(a) FROM t1 } db2 |
| 257 } $res1 | 272 } $res1 |
| 258 } | 273 } |
| 259 db close | 274 db close |
| 260 db2 close | 275 db2 close |
| 261 tvfs delete | 276 tvfs delete |
| 262 file delete -force test.db test.db-wal test.db-journal | 277 forcedelete test.db test.db-wal test.db-journal |
| 263 | 278 |
| 264 | 279 |
| 265 if 0 { | 280 if 0 { |
| 266 #------------------------------------------------------------------------- | 281 #------------------------------------------------------------------------- |
| 267 # This test case - wal2-3.* - tests the response of the library to an | 282 # This test case - wal2-3.* - tests the response of the library to an |
| 268 # SQLITE_BUSY when attempting to obtain a READ or RECOVER lock. | 283 # SQLITE_BUSY when attempting to obtain a READ or RECOVER lock. |
| 269 # | 284 # |
| 270 # wal2-3.0 - 2: SQLITE_BUSY when obtaining a READ lock | 285 # wal2-3.0 - 2: SQLITE_BUSY when obtaining a READ lock |
| 271 # wal2-3.3 - 6: SQLITE_BUSY when obtaining a RECOVER lock | 286 # wal2-3.3 - 6: SQLITE_BUSY when obtaining a RECOVER lock |
| 272 # | 287 # |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 list [info exists ::sabotage] [info exists ::locked] | 340 list [info exists ::sabotage] [info exists ::locked] |
| 326 } {1 1} | 341 } {1 1} |
| 327 do_test wal2-3.4 { | 342 do_test wal2-3.4 { |
| 328 execsql { SELECT count(a), sum(a) FROM t1 } | 343 execsql { SELECT count(a), sum(a) FROM t1 } |
| 329 } {4 10} | 344 } {4 10} |
| 330 do_test wal2-3.5 { | 345 do_test wal2-3.5 { |
| 331 list [info exists ::sabotage] [info exists ::locked] | 346 list [info exists ::sabotage] [info exists ::locked] |
| 332 } {0 0} | 347 } {0 0} |
| 333 db close | 348 db close |
| 334 tvfs delete | 349 tvfs delete |
| 335 file delete -force test.db test.db-wal test.db-journal | 350 forcedelete test.db test.db-wal test.db-journal |
| 336 | 351 |
| 337 } | 352 } |
| 338 | 353 |
| 339 #------------------------------------------------------------------------- | 354 #------------------------------------------------------------------------- |
| 340 # Test that a database connection using a VFS that does not support the | 355 # Test that a database connection using a VFS that does not support the |
| 341 # xShmXXX interfaces cannot open a WAL database. | 356 # xShmXXX interfaces cannot open a WAL database. |
| 342 # | 357 # |
| 343 do_test wal2-4.1 { | 358 do_test wal2-4.1 { |
| 344 sqlite3 db test.db | 359 sqlite3 db test.db |
| 345 execsql { | 360 execsql { |
| 346 PRAGMA auto_vacuum = 0; | 361 PRAGMA auto_vacuum = 0; |
| 347 PRAGMA journal_mode = WAL; | 362 PRAGMA journal_mode = WAL; |
| 348 CREATE TABLE data(x); | 363 CREATE TABLE data(x); |
| 349 INSERT INTO data VALUES('need xShmOpen to see this'); | 364 INSERT INTO data VALUES('need xShmOpen to see this'); |
| 350 PRAGMA wal_checkpoint; | 365 PRAGMA wal_checkpoint; |
| 351 } | 366 } |
| 352 } {wal 0 5 5} | 367 # Three pages in the WAL file at this point: One copy of page 1 and two |
| 368 # of the root page for table "data". |
| 369 } {wal 0 3 3} |
| 353 do_test wal2-4.2 { | 370 do_test wal2-4.2 { |
| 354 db close | 371 db close |
| 355 testvfs tvfs -noshm 1 | 372 testvfs tvfs -noshm 1 |
| 356 sqlite3 db test.db -vfs tvfs | 373 sqlite3 db test.db -vfs tvfs |
| 357 catchsql { SELECT * FROM data } | 374 catchsql { SELECT * FROM data } |
| 358 } {1 {unable to open database file}} | 375 } {1 {unable to open database file}} |
| 359 do_test wal2-4.3 { | 376 do_test wal2-4.3 { |
| 360 db close | 377 db close |
| 361 testvfs tvfs | 378 testvfs tvfs |
| 362 sqlite3 db test.db -vfs tvfs | 379 sqlite3 db test.db -vfs tvfs |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 # wal2-6.4.*: Check that xShmLock calls are omitted in exclusive locking | 439 # wal2-6.4.*: Check that xShmLock calls are omitted in exclusive locking |
| 423 # mode. | 440 # mode. |
| 424 # | 441 # |
| 425 # wal2-6.5.*: | 442 # wal2-6.5.*: |
| 426 # | 443 # |
| 427 # wal2-6.6.*: Check that if the xShmLock() to reaquire a WAL read-lock when | 444 # wal2-6.6.*: Check that if the xShmLock() to reaquire a WAL read-lock when |
| 428 # exiting exclusive mode fails (i.e. SQLITE_IOERR), then the | 445 # exiting exclusive mode fails (i.e. SQLITE_IOERR), then the |
| 429 # connection silently remains in exclusive mode. | 446 # connection silently remains in exclusive mode. |
| 430 # | 447 # |
| 431 do_test wal2-6.1.1 { | 448 do_test wal2-6.1.1 { |
| 432 file delete -force test.db test.db-wal test.db-journal | 449 forcedelete test.db test.db-wal test.db-journal |
| 433 sqlite3 db test.db | 450 sqlite3 db test.db |
| 434 execsql { | 451 execsql { |
| 435 Pragma Journal_Mode = Wal; | 452 Pragma Journal_Mode = Wal; |
| 436 } | 453 } |
| 437 } {wal} | 454 } {wal} |
| 438 do_test wal2-6.1.2 { | 455 do_test wal2-6.1.2 { |
| 439 execsql { PRAGMA lock_status } | 456 execsql { PRAGMA lock_status } |
| 440 } {main unlocked temp closed} | 457 } {main unlocked temp closed} |
| 441 do_test wal2-6.1.3 { | 458 do_test wal2-6.1.3 { |
| 442 execsql { | 459 execsql { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 465 } {1 2 main shared temp closed} | 482 } {1 2 main shared temp closed} |
| 466 do_test wal2-6.1.6 { | 483 do_test wal2-6.1.6 { |
| 467 execsql { | 484 execsql { |
| 468 INSERT INTO t1 VALUES(3, 4); | 485 INSERT INTO t1 VALUES(3, 4); |
| 469 PRAGMA lock_status; | 486 PRAGMA lock_status; |
| 470 } | 487 } |
| 471 } {main shared temp closed} | 488 } {main shared temp closed} |
| 472 db close | 489 db close |
| 473 | 490 |
| 474 do_test wal2-6.2.1 { | 491 do_test wal2-6.2.1 { |
| 475 file delete -force test.db test.db-wal test.db-journal | 492 forcedelete test.db test.db-wal test.db-journal |
| 476 sqlite3 db test.db | 493 sqlite3 db test.db |
| 477 execsql { | 494 execsql { |
| 478 Pragma Locking_Mode = Exclusive; | 495 Pragma Locking_Mode = Exclusive; |
| 479 Pragma Journal_Mode = Wal; | 496 Pragma Journal_Mode = Wal; |
| 480 Pragma Lock_Status; | 497 Pragma Lock_Status; |
| 481 } | 498 } |
| 482 } {exclusive wal main exclusive temp closed} | 499 } {exclusive wal main exclusive temp closed} |
| 483 do_test wal2-6.2.2 { | 500 do_test wal2-6.2.2 { |
| 484 execsql { | 501 execsql { |
| 485 BEGIN; | 502 BEGIN; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 do_test wal2-6.2.9 { | 550 do_test wal2-6.2.9 { |
| 534 execsql { | 551 execsql { |
| 535 INSERT INTO t1 VALUES(5, 6); | 552 INSERT INTO t1 VALUES(5, 6); |
| 536 SELECT * FROM t1; | 553 SELECT * FROM t1; |
| 537 pragma lock_status; | 554 pragma lock_status; |
| 538 } | 555 } |
| 539 } {1 2 3 4 5 6 main shared temp closed} | 556 } {1 2 3 4 5 6 main shared temp closed} |
| 540 db close | 557 db close |
| 541 | 558 |
| 542 do_test wal2-6.3.1 { | 559 do_test wal2-6.3.1 { |
| 543 file delete -force test.db test.db-wal test.db-journal | 560 forcedelete test.db test.db-wal test.db-journal |
| 544 sqlite3 db test.db | 561 sqlite3 db test.db |
| 545 execsql { | 562 execsql { |
| 546 PRAGMA journal_mode = WAL; | 563 PRAGMA journal_mode = WAL; |
| 547 PRAGMA locking_mode = exclusive; | 564 PRAGMA locking_mode = exclusive; |
| 548 BEGIN; | 565 BEGIN; |
| 549 CREATE TABLE t1(x); | 566 CREATE TABLE t1(x); |
| 550 INSERT INTO t1 VALUES('Chico'); | 567 INSERT INTO t1 VALUES('Chico'); |
| 551 INSERT INTO t1 VALUES('Harpo'); | 568 INSERT INTO t1 VALUES('Harpo'); |
| 552 COMMIT; | 569 COMMIT; |
| 553 } | 570 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 578 execsql { PRAGMA lock_status } | 595 execsql { PRAGMA lock_status } |
| 579 } {main exclusive temp closed} | 596 } {main exclusive temp closed} |
| 580 db close | 597 db close |
| 581 | 598 |
| 582 | 599 |
| 583 # This test - wal2-6.4.* - uses a single database connection and the | 600 # This test - wal2-6.4.* - uses a single database connection and the |
| 584 # [testvfs] instrumentation to test that xShmLock() is being called | 601 # [testvfs] instrumentation to test that xShmLock() is being called |
| 585 # as expected when a WAL database is used with locking_mode=exclusive. | 602 # as expected when a WAL database is used with locking_mode=exclusive. |
| 586 # | 603 # |
| 587 do_test wal2-6.4.1 { | 604 do_test wal2-6.4.1 { |
| 588 file delete -force test.db test.db-wal test.db-journal | 605 forcedelete test.db test.db-wal test.db-journal |
| 589 proc tvfs_cb {method args} { | 606 proc tvfs_cb {method args} { |
| 590 set ::shm_file [lindex $args 0] | 607 set ::shm_file [lindex $args 0] |
| 591 if {$method == "xShmLock"} { lappend ::locks [lindex $args 2] } | 608 if {$method == "xShmLock"} { lappend ::locks [lindex $args 2] } |
| 592 return "SQLITE_OK" | 609 return "SQLITE_OK" |
| 593 } | 610 } |
| 594 testvfs tvfs | 611 testvfs tvfs |
| 595 tvfs script tvfs_cb | 612 tvfs script tvfs_cb |
| 596 sqlite3 db test.db -vfs tvfs | 613 sqlite3 db test.db -vfs tvfs |
| 614 set {} {} |
| 597 } {} | 615 } {} |
| 598 | 616 |
| 599 set RECOVERY { | 617 set RECOVERY { |
| 600 {0 1 lock exclusive} {1 7 lock exclusive} | 618 {0 1 lock exclusive} {1 7 lock exclusive} |
| 601 {1 7 unlock exclusive} {0 1 unlock exclusive} | 619 {1 7 unlock exclusive} {0 1 unlock exclusive} |
| 602 } | 620 } |
| 603 set READMARK0_READ { | 621 set READMARK0_READ { |
| 604 {3 1 lock shared} {3 1 unlock shared} | 622 {3 1 lock shared} {3 1 unlock shared} |
| 605 } | 623 } |
| 606 set READMARK0_WRITE { | 624 set READMARK0_WRITE { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 sqlite3 db test.db | 728 sqlite3 db test.db |
| 711 execsql { | 729 execsql { |
| 712 PRAGMA auto_vacuum = 0; | 730 PRAGMA auto_vacuum = 0; |
| 713 PRAGMA journal_mode = wal; | 731 PRAGMA journal_mode = wal; |
| 714 PRAGMA locking_mode = exclusive; | 732 PRAGMA locking_mode = exclusive; |
| 715 CREATE TABLE t2(a, b); | 733 CREATE TABLE t2(a, b); |
| 716 PRAGMA wal_checkpoint; | 734 PRAGMA wal_checkpoint; |
| 717 INSERT INTO t2 VALUES('I', 'II'); | 735 INSERT INTO t2 VALUES('I', 'II'); |
| 718 PRAGMA journal_mode; | 736 PRAGMA journal_mode; |
| 719 } | 737 } |
| 720 } {wal exclusive 0 3 3 wal} | 738 } {wal exclusive 0 2 2 wal} |
| 721 do_test wal2-6.5.2 { | 739 do_test wal2-6.5.2 { |
| 722 execsql { | 740 execsql { |
| 723 PRAGMA locking_mode = normal; | 741 PRAGMA locking_mode = normal; |
| 724 INSERT INTO t2 VALUES('III', 'IV'); | 742 INSERT INTO t2 VALUES('III', 'IV'); |
| 725 PRAGMA locking_mode = exclusive; | 743 PRAGMA locking_mode = exclusive; |
| 726 SELECT * FROM t2; | 744 SELECT * FROM t2; |
| 727 } | 745 } |
| 728 } {normal exclusive I II III IV} | 746 } {normal exclusive I II III IV} |
| 729 do_test wal2-6.5.3 { | 747 do_test wal2-6.5.3 { |
| 730 execsql { PRAGMA wal_checkpoint } | 748 execsql { PRAGMA wal_checkpoint } |
| 731 } {0 4 4} | 749 } {0 2 2} |
| 732 db close | 750 db close |
| 733 | 751 |
| 734 proc lock_control {method filename handle spec} { | 752 proc lock_control {method filename handle spec} { |
| 735 foreach {start n op type} $spec break | 753 foreach {start n op type} $spec break |
| 736 if {$op == "lock"} { return SQLITE_IOERR } | 754 if {$op == "lock"} { return SQLITE_IOERR } |
| 737 return SQLITE_OK | 755 return SQLITE_OK |
| 738 } | 756 } |
| 739 do_test wal2-6.6.1 { | 757 do_test wal2-6.6.1 { |
| 740 testvfs T | 758 testvfs T |
| 741 T script lock_control | 759 T script lock_control |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 } {0 {I II III IV V VI VII VIII IX X}} | 791 } {0 {I II III IV V VI VII VIII IX X}} |
| 774 | 792 |
| 775 db close | 793 db close |
| 776 db2 close | 794 db2 close |
| 777 T delete | 795 T delete |
| 778 | 796 |
| 779 #------------------------------------------------------------------------- | 797 #------------------------------------------------------------------------- |
| 780 # Test a theory about the checksum algorithm. Theory was false and this | 798 # Test a theory about the checksum algorithm. Theory was false and this |
| 781 # test did not provoke a bug. | 799 # test did not provoke a bug. |
| 782 # | 800 # |
| 783 file delete -force test.db test.db-wal test.db-journal | 801 forcedelete test.db test.db-wal test.db-journal |
| 784 do_test wal2-7.1.1 { | 802 do_test wal2-7.1.1 { |
| 785 sqlite3 db test.db | 803 sqlite3 db test.db |
| 786 execsql { | 804 execsql { |
| 787 PRAGMA page_size = 4096; | 805 PRAGMA page_size = 4096; |
| 788 PRAGMA journal_mode = WAL; | 806 PRAGMA journal_mode = WAL; |
| 789 CREATE TABLE t1(a, b); | 807 CREATE TABLE t1(a, b); |
| 790 } | 808 } |
| 791 file size test.db | 809 file size test.db |
| 792 } {4096} | 810 } {4096} |
| 793 do_test wal2-7.1.2 { | 811 do_test wal2-7.1.2 { |
| 794 file copy -force test.db test2.db | 812 forcecopy test.db test2.db |
| 795 file copy -force test.db-wal test2.db-wal | 813 forcecopy test.db-wal test2.db-wal |
| 796 hexio_write test2.db-wal 48 FF | 814 # The first 32 bytes of the WAL file contain the WAL header. Offset 48 |
| 815 # is the first byte of the checksum for the first frame in the WAL. |
| 816 # The following three lines replaces the contents of that byte with |
| 817 # a different value. |
| 818 set newval FF |
| 819 if {$newval == [hexio_read test2.db-wal 48 1]} { set newval 00 } |
| 820 hexio_write test2.db-wal 48 $newval |
| 797 } {1} | 821 } {1} |
| 798 do_test wal2-7.1.3 { | 822 do_test wal2-7.1.3 { |
| 799 sqlite3 db2 test2.db | 823 sqlite3 db2 test2.db |
| 800 execsql { PRAGMA wal_checkpoint } db2 | 824 execsql { PRAGMA wal_checkpoint } db2 |
| 801 execsql { SELECT * FROM sqlite_master } db2 | 825 execsql { SELECT * FROM sqlite_master } db2 |
| 802 } {} | 826 } {} |
| 803 db close | 827 db close |
| 804 db2 close | 828 db2 close |
| 805 file delete -force test.db test.db-wal test.db-journal | 829 forcedelete test.db test.db-wal test.db-journal |
| 806 do_test wal2-8.1.2 { | 830 do_test wal2-8.1.2 { |
| 807 sqlite3 db test.db | 831 sqlite3 db test.db |
| 808 execsql { | 832 execsql { |
| 809 PRAGMA auto_vacuum=OFF; | 833 PRAGMA auto_vacuum=OFF; |
| 810 PRAGMA page_size = 1024; | 834 PRAGMA page_size = 1024; |
| 811 PRAGMA journal_mode = WAL; | 835 PRAGMA journal_mode = WAL; |
| 812 CREATE TABLE t1(x); | 836 CREATE TABLE t1(x); |
| 813 INSERT INTO t1 VALUES(zeroblob(8188*1020)); | 837 INSERT INTO t1 VALUES(zeroblob(8188*1020)); |
| 814 CREATE TABLE t2(y); | 838 CREATE TABLE t2(y); |
| 815 PRAGMA wal_checkpoint; | 839 PRAGMA wal_checkpoint; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 # Test that even if the checksums for both are valid, if the two copies | 875 # Test that even if the checksums for both are valid, if the two copies |
| 852 # of the wal-index header in the wal-index do not match, the client | 876 # of the wal-index header in the wal-index do not match, the client |
| 853 # runs (or at least tries to run) database recovery. | 877 # runs (or at least tries to run) database recovery. |
| 854 # | 878 # |
| 855 # | 879 # |
| 856 proc get_name {method args} { set ::filename [lindex $args 0] ; tvfs filter {} } | 880 proc get_name {method args} { set ::filename [lindex $args 0] ; tvfs filter {} } |
| 857 testvfs tvfs | 881 testvfs tvfs |
| 858 tvfs script get_name | 882 tvfs script get_name |
| 859 tvfs filter xShmOpen | 883 tvfs filter xShmOpen |
| 860 | 884 |
| 861 file delete -force test.db test.db-wal test.db-journal | 885 forcedelete test.db test.db-wal test.db-journal |
| 862 do_test wal2-9.1 { | 886 do_test wal2-9.1 { |
| 863 sqlite3 db test.db -vfs tvfs | 887 sqlite3 db test.db -vfs tvfs |
| 864 execsql { | 888 execsql { |
| 865 PRAGMA journal_mode = WAL; | 889 PRAGMA journal_mode = WAL; |
| 866 CREATE TABLE x(y); | 890 CREATE TABLE x(y); |
| 867 INSERT INTO x VALUES('Barton'); | 891 INSERT INTO x VALUES('Barton'); |
| 868 INSERT INTO x VALUES('Deakin'); | 892 INSERT INTO x VALUES('Deakin'); |
| 869 } | 893 } |
| 870 | 894 |
| 871 # Set $wih(1) to the contents of the wal-index header after | 895 # Set $wih(1) to the contents of the wal-index header after |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 db2 close | 1044 db2 close |
| 1021 tvfs delete | 1045 tvfs delete |
| 1022 | 1046 |
| 1023 #------------------------------------------------------------------------- | 1047 #------------------------------------------------------------------------- |
| 1024 # If a connection is required to create a WAL or SHM file, it creates | 1048 # If a connection is required to create a WAL or SHM file, it creates |
| 1025 # the new files with the same file-system permissions as the database | 1049 # the new files with the same file-system permissions as the database |
| 1026 # file itself. Test this. | 1050 # file itself. Test this. |
| 1027 # | 1051 # |
| 1028 if {$::tcl_platform(platform) == "unix"} { | 1052 if {$::tcl_platform(platform) == "unix"} { |
| 1029 faultsim_delete_and_reopen | 1053 faultsim_delete_and_reopen |
| 1030 set umask [exec /bin/sh -c umask] | 1054 # Changed on 2012-02-13: umask is deliberately ignored for -wal files. |
| 1055 #set umask [exec /bin/sh -c umask] |
| 1056 set umask 0 |
| 1057 |
| 1031 | 1058 |
| 1032 do_test wal2-12.1 { | 1059 do_test wal2-12.1 { |
| 1033 sqlite3 db test.db | 1060 sqlite3 db test.db |
| 1034 execsql { | 1061 execsql { |
| 1035 CREATE TABLE tx(y, z); | 1062 CREATE TABLE tx(y, z); |
| 1036 PRAGMA journal_mode = WAL; | 1063 PRAGMA journal_mode = WAL; |
| 1037 } | 1064 } |
| 1038 db close | 1065 db close |
| 1039 list [file exists test.db-wal] [file exists test.db-shm] | 1066 list [file exists test.db-wal] [file exists test.db-shm] |
| 1040 } {0 0} | 1067 } {0 0} |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 } $b($can_read,$can_write) | 1183 } $b($can_read,$can_write) |
| 1157 } | 1184 } |
| 1158 catch { db close } | 1185 catch { db close } |
| 1159 } | 1186 } |
| 1160 } | 1187 } |
| 1161 | 1188 |
| 1162 #------------------------------------------------------------------------- | 1189 #------------------------------------------------------------------------- |
| 1163 # Test that "PRAGMA checkpoint_fullsync" appears to be working. | 1190 # Test that "PRAGMA checkpoint_fullsync" appears to be working. |
| 1164 # | 1191 # |
| 1165 foreach {tn sql reslist} { | 1192 foreach {tn sql reslist} { |
| 1166 1 { } {8 0 3 0 5 0} | 1193 1 { } {10 0 4 0 6 0} |
| 1167 2 { PRAGMA checkpoint_fullfsync = 1 } {8 4 3 2 5 2} | 1194 2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2} |
| 1168 3 { PRAGMA checkpoint_fullfsync = 0 } {8 0 3 0 5 0} | 1195 3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0} |
| 1169 } { | 1196 } { |
| 1170 faultsim_delete_and_reopen | 1197 faultsim_delete_and_reopen |
| 1171 | 1198 |
| 1172 execsql {PRAGMA auto_vacuum = 0} | 1199 execsql {PRAGMA auto_vacuum = 0} |
| 1173 execsql $sql | 1200 execsql $sql |
| 1201 do_execsql_test wal2-14.$tn.0 { PRAGMA page_size = 4096 } {} |
| 1174 do_execsql_test wal2-14.$tn.1 { PRAGMA journal_mode = WAL } {wal} | 1202 do_execsql_test wal2-14.$tn.1 { PRAGMA journal_mode = WAL } {wal} |
| 1175 | 1203 |
| 1176 set sqlite_sync_count 0 | 1204 set sqlite_sync_count 0 |
| 1177 set sqlite_fullsync_count 0 | 1205 set sqlite_fullsync_count 0 |
| 1178 | 1206 |
| 1179 do_execsql_test wal2-14.$tn.2 { | 1207 do_execsql_test wal2-14.$tn.2 { |
| 1180 PRAGMA wal_autocheckpoint = 10; | 1208 PRAGMA wal_autocheckpoint = 10; |
| 1181 CREATE TABLE t1(a, b); -- 2 wal syncs | 1209 CREATE TABLE t1(a, b); -- 2 wal syncs |
| 1182 INSERT INTO t1 VALUES(1, 2); -- 1 wal sync | 1210 INSERT INTO t1 VALUES(1, 2); -- 2 wal sync |
| 1183 PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync | 1211 PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync |
| 1184 BEGIN; | 1212 BEGIN; |
| 1185 INSERT INTO t1 VALUES(3, 4); | 1213 INSERT INTO t1 VALUES(3, 4); |
| 1186 INSERT INTO t1 VALUES(5, 6); | 1214 INSERT INTO t1 VALUES(5, 6); |
| 1187 COMMIT; -- 1 wal sync | 1215 COMMIT; -- 2 wal sync |
| 1188 PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync | 1216 PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync |
| 1189 } {10 0 5 5 0 2 2} | 1217 } {10 0 3 3 0 1 1} |
| 1190 | 1218 |
| 1191 do_test wal2-14.$tn.3 { | 1219 do_test wal2-14.$tn.3 { |
| 1220 cond_incr_sync_count 1 |
| 1192 list $sqlite_sync_count $sqlite_fullsync_count | 1221 list $sqlite_sync_count $sqlite_fullsync_count |
| 1193 } [lrange $reslist 0 1] | 1222 } [lrange $reslist 0 1] |
| 1194 | 1223 |
| 1195 set sqlite_sync_count 0 | 1224 set sqlite_sync_count 0 |
| 1196 set sqlite_fullsync_count 0 | 1225 set sqlite_fullsync_count 0 |
| 1197 | 1226 |
| 1198 do_test wal2-14.$tn.4 { | 1227 do_test wal2-14.$tn.4 { |
| 1199 execsql { INSERT INTO t1 VALUES(7, zeroblob(12*4096)) } | 1228 execsql { INSERT INTO t1 VALUES(7, zeroblob(12*4096)) } |
| 1200 list $sqlite_sync_count $sqlite_fullsync_count | 1229 list $sqlite_sync_count $sqlite_fullsync_count |
| 1201 } [lrange $reslist 2 3] | 1230 } [lrange $reslist 2 3] |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1212 list $sqlite_sync_count $sqlite_fullsync_count | 1241 list $sqlite_sync_count $sqlite_fullsync_count |
| 1213 } [lrange $reslist 4 5] | 1242 } [lrange $reslist 4 5] |
| 1214 } | 1243 } |
| 1215 | 1244 |
| 1216 catch { db close } | 1245 catch { db close } |
| 1217 | 1246 |
| 1218 # PRAGMA checkpoint_fullsync | 1247 # PRAGMA checkpoint_fullsync |
| 1219 # PRAGMA fullfsync | 1248 # PRAGMA fullfsync |
| 1220 # PRAGMA synchronous | 1249 # PRAGMA synchronous |
| 1221 # | 1250 # |
| 1222 foreach {tn settings commit_sync ckpt_sync} { | 1251 foreach {tn settings restart_sync commit_sync ckpt_sync} { |
| 1223 1 {0 0 off} {0 0} {0 0} | 1252 1 {0 0 off} {0 0} {0 0} {0 0} |
| 1224 2 {0 0 normal} {0 0} {2 0} | 1253 2 {0 0 normal} {1 0} {0 0} {2 0} |
| 1225 3 {0 0 full} {1 0} {2 0} | 1254 3 {0 0 full} {2 0} {1 0} {2 0} |
| 1226 | 1255 |
| 1227 4 {0 1 off} {0 0} {0 0} | 1256 4 {0 1 off} {0 0} {0 0} {0 0} |
| 1228 5 {0 1 normal} {0 0} {0 2} | 1257 5 {0 1 normal} {0 1} {0 0} {0 2} |
| 1229 6 {0 1 full} {0 1} {0 2} | 1258 6 {0 1 full} {0 2} {0 1} {0 2} |
| 1230 | 1259 |
| 1231 7 {1 0 off} {0 0} {0 0} | 1260 7 {1 0 off} {0 0} {0 0} {0 0} |
| 1232 8 {1 0 normal} {0 0} {0 2} | 1261 8 {1 0 normal} {1 0} {0 0} {0 2} |
| 1233 9 {1 0 full} {1 0} {0 2} | 1262 9 {1 0 full} {2 0} {1 0} {0 2} |
| 1234 | 1263 |
| 1235 10 {1 1 off} {0 0} {0 0} | 1264 10 {1 1 off} {0 0} {0 0} {0 0} |
| 1236 11 {1 1 normal} {0 0} {0 2} | 1265 11 {1 1 normal} {0 1} {0 0} {0 2} |
| 1237 12 {1 1 full} {0 1} {0 2} | 1266 12 {1 1 full} {0 2} {0 1} {0 2} |
| 1238 } { | 1267 } { |
| 1239 forcedelete test.db | 1268 forcedelete test.db |
| 1240 | 1269 |
| 1241 testvfs tvfs -default 1 | 1270 testvfs tvfs -default 1 |
| 1242 tvfs filter xSync | 1271 tvfs filter xSync |
| 1243 tvfs script xSyncCb | 1272 tvfs script xSyncCb |
| 1244 proc xSyncCb {method file fileid flags} { | 1273 proc xSyncCb {method file fileid flags} { |
| 1245 incr ::sync($flags) | 1274 incr ::sync($flags) |
| 1246 } | 1275 } |
| 1247 | 1276 |
| 1248 sqlite3 db test.db | 1277 sqlite3 db test.db |
| 1249 do_execsql_test 15.$tn.1 " | 1278 do_execsql_test 15.$tn.1 " |
| 1279 PRAGMA page_size = 4096; |
| 1250 CREATE TABLE t1(x); | 1280 CREATE TABLE t1(x); |
| 1281 PRAGMA wal_autocheckpoint = OFF; |
| 1251 PRAGMA journal_mode = WAL; | 1282 PRAGMA journal_mode = WAL; |
| 1252 PRAGMA checkpoint_fullfsync = [lindex $settings 0]; | 1283 PRAGMA checkpoint_fullfsync = [lindex $settings 0]; |
| 1253 PRAGMA fullfsync = [lindex $settings 1]; | 1284 PRAGMA fullfsync = [lindex $settings 1]; |
| 1254 PRAGMA synchronous = [lindex $settings 2]; | 1285 PRAGMA synchronous = [lindex $settings 2]; |
| 1255 " {wal} | 1286 " {0 wal} |
| 1256 | 1287 |
| 1257 do_test 15.$tn.2 { | 1288 do_test 15.$tn.2 { |
| 1258 set sync(normal) 0 | 1289 set sync(normal) 0 |
| 1259 set sync(full) 0 | 1290 set sync(full) 0 |
| 1260 execsql { INSERT INTO t1 VALUES('abc') } | 1291 execsql { INSERT INTO t1 VALUES('abc') } |
| 1261 list $::sync(normal) $::sync(full) | 1292 list $::sync(normal) $::sync(full) |
| 1293 } $restart_sync |
| 1294 |
| 1295 do_test 15.$tn.3 { |
| 1296 set sync(normal) 0 |
| 1297 set sync(full) 0 |
| 1298 execsql { INSERT INTO t1 VALUES('abc') } |
| 1299 list $::sync(normal) $::sync(full) |
| 1262 } $commit_sync | 1300 } $commit_sync |
| 1263 | 1301 |
| 1264 do_test 15.$tn.3 { | 1302 do_test 15.$tn.4 { |
| 1265 set sync(normal) 0 | 1303 set sync(normal) 0 |
| 1266 set sync(full) 0 | 1304 set sync(full) 0 |
| 1267 execsql { INSERT INTO t1 VALUES('def') } | 1305 execsql { INSERT INTO t1 VALUES('def') } |
| 1268 list $::sync(normal) $::sync(full) | 1306 list $::sync(normal) $::sync(full) |
| 1269 } $commit_sync | 1307 } $commit_sync |
| 1270 | 1308 |
| 1271 do_test 15.$tn.4 { | 1309 do_test 15.$tn.5 { |
| 1272 set sync(normal) 0 | 1310 set sync(normal) 0 |
| 1273 set sync(full) 0 | 1311 set sync(full) 0 |
| 1274 execsql { PRAGMA wal_checkpoint } | 1312 execsql { PRAGMA wal_checkpoint } |
| 1275 list $::sync(normal) $::sync(full) | 1313 list $::sync(normal) $::sync(full) |
| 1276 } $ckpt_sync | 1314 } $ckpt_sync |
| 1277 | 1315 |
| 1278 db close | 1316 db close |
| 1279 tvfs delete | 1317 tvfs delete |
| 1280 } | 1318 } |
| 1281 | 1319 |
| 1282 | 1320 |
| 1283 | 1321 |
| 1284 finish_test | 1322 finish_test |
| OLD | NEW |