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 |