wasCSharpSQLite – Blame information for rev 7
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | # 2010 May 25 |
2 | # |
||
3 | # The author disclaims copyright to this source code. In place of |
||
4 | # a legal notice, here is a blessing: |
||
5 | # |
||
6 | # May you do good and not evil. |
||
7 | # May you find forgiveness for yourself and forgive others. |
||
8 | # May you share freely, never taking more than you give. |
||
9 | # |
||
10 | #*********************************************************************** |
||
11 | # |
||
12 | |||
13 | |||
14 | set testdir [file dirname $argv0] |
||
15 | source $testdir/tester.tcl |
||
16 | source $testdir/lock_common.tcl |
||
17 | source $testdir/wal_common.tcl |
||
18 | ifcapable !wal {finish_test ; return } |
||
19 | |||
20 | |||
21 | #------------------------------------------------------------------------- |
||
22 | # This test case demonstrates a flaw in the wal-index manipulation that |
||
23 | # existed at one point: If a process crashes mid-transaction, it may have |
||
24 | # already added some entries to one of the hash-tables in the wal-index. |
||
25 | # If the transaction were to be explicitly rolled back at this point, the |
||
26 | # hash-table entries would be removed as part of the rollback. However, |
||
27 | # if the process crashes, the transaction is implicitly rolled back and |
||
28 | # the rogue entries remain in the hash table. |
||
29 | # |
||
30 | # Normally, this causes no problem - readers can tell the difference |
||
31 | # between committed and uncommitted entries in the hash table. However, |
||
32 | # if it happens often enough that all slots in the hash-table become |
||
33 | # non-zero, the next process that attempts to read or write the hash |
||
34 | # table falls into an infinite loop. |
||
35 | # |
||
36 | # Even if run with an SQLite version affected by the bug, this test case |
||
37 | # only goes into an infinite loop if SQLite is compiled without SQLITE_DEBUG |
||
38 | # defined. If SQLITE_DEBUG is defined, the program is halted by a failing |
||
39 | # assert() before entering the infinite loop. |
||
40 | # |
||
41 | # walcrash2-1.1: Create a database. Commit a transaction that adds 8 frames |
||
42 | # to the WAL (and 8 entry to the first hash-table in the |
||
43 | # wal-index). |
||
44 | # |
||
45 | # walcrash2-1.2: Have an external process open a transaction, add 8 entries |
||
46 | # to the wal-index hash-table, then crash. Repeat this 1023 |
||
47 | # times (so that the wal-index contains 8192 entries - all |
||
48 | # slots are non-zero). |
||
49 | # |
||
50 | # walcrash2-1.3: Using a new database connection, attempt to query the |
||
51 | # database. This should cause the process to go into the |
||
52 | # infinite loop. |
||
53 | # |
||
54 | do_test walcrash2-1.1 { |
||
55 | execsql { |
||
56 | PRAGMA page_size = 1024; |
||
57 | PRAGMA auto_vacuum = off; |
||
58 | PRAGMA journal_mode = WAL; |
||
59 | PRAGMA synchronous = NORMAL; |
||
60 | BEGIN; |
||
61 | CREATE TABLE t1(x); |
||
62 | CREATE TABLE t2(x); |
||
63 | CREATE TABLE t3(x); |
||
64 | CREATE TABLE t4(x); |
||
65 | CREATE TABLE t5(x); |
||
66 | CREATE TABLE t6(x); |
||
67 | CREATE TABLE t7(x); |
||
68 | COMMIT; |
||
69 | } |
||
70 | file size test.db-wal |
||
71 | } [wal_file_size 8 1024] |
||
72 | for {set nEntry 8} {$nEntry < 8192} {incr nEntry 8} { |
||
73 | do_test walcrash2-1.2.[expr $nEntry/8] { |
||
74 | set C [launch_testfixture] |
||
75 | testfixture $C { |
||
76 | sqlite3 db test.db |
||
77 | db eval { |
||
78 | PRAGMA cache_size = 15; |
||
79 | BEGIN; |
||
80 | INSERT INTO t1 VALUES(randomblob(900)); -- 1 row, 1 page |
||
81 | INSERT INTO t1 SELECT * FROM t1; -- 2 rows, 3 pages |
||
82 | INSERT INTO t1 SELECT * FROM t1; -- 4 rows, 5 pages |
||
83 | INSERT INTO t1 SELECT * FROM t1; -- 8 rows, 9 pages |
||
84 | INSERT INTO t1 SELECT * FROM t1; -- 16 rows, 17 pages |
||
85 | INSERT INTO t1 SELECT * FROM t1 LIMIT 3; -- 20 rows, 20 pages |
||
86 | } |
||
87 | } |
||
88 | close $C |
||
89 | file size test.db-wal |
||
90 | } [wal_file_size 16 1024] |
||
91 | } |
||
92 | do_test walcrash2-1.3 { |
||
93 | sqlite3 db2 test.db |
||
94 | execsql { SELECT count(*) FROM t1 } db2 |
||
95 | } {0} |
||
96 | catch { db2 close } |
||
97 | |||
98 | finish_test |
||
99 |