OLD | NEW |
1 # 2008 May 12 | 1 # 2008 May 12 |
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 #*********************************************************************** |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 execsql { pragma locking_mode=exclusive } | 84 execsql { pragma locking_mode=exclusive } |
85 set nRow [db one {SELECT count(*) FROM a}] | 85 set nRow [db one {SELECT count(*) FROM a}] |
86 | 86 |
87 # Dirty (at least) one of the pages in the cache. | 87 # Dirty (at least) one of the pages in the cache. |
88 do_test ioerr5-1.$locking_mode-$iFail.1 { | 88 do_test ioerr5-1.$locking_mode-$iFail.1 { |
89 execsql { | 89 execsql { |
90 BEGIN EXCLUSIVE; | 90 BEGIN EXCLUSIVE; |
91 INSERT INTO a VALUES(1, 'ABCDEFGHIJKLMNOP'); | 91 INSERT INTO a VALUES(1, 'ABCDEFGHIJKLMNOP'); |
92 } | 92 } |
93 } {} | 93 } {} |
| 94 |
| 95 # Open a read-only cursor on table "a". If the COMMIT below is |
| 96 # interrupted by a persistent IO error, the pager will transition to |
| 97 # PAGER_ERROR state. If there are no other read-only cursors open, |
| 98 # from there the pager immediately discards all cached data and |
| 99 # switches to PAGER_OPEN state. This read-only cursor stops that |
| 100 # from happening, leaving the pager stuck in PAGER_ERROR state. |
| 101 # |
| 102 set channel [db incrblob -readonly a Name [db last_insert_rowid]] |
94 | 103 |
95 # Now try to commit the transaction. Cause an IO error to occur | 104 # Now try to commit the transaction. Cause an IO error to occur |
96 # within this operation, which moves the pager into the error state. | 105 # within this operation, which moves the pager into the error state. |
97 # | 106 # |
98 set ::sqlite_io_error_persist 1 | 107 set ::sqlite_io_error_persist 1 |
99 set ::sqlite_io_error_pending $iFail | 108 set ::sqlite_io_error_pending $iFail |
100 do_test ioerr5-1.$locking_mode-$iFail.2 { | 109 do_test ioerr5-1.$locking_mode-$iFail.2 { |
101 set rc [catchsql {COMMIT}] | 110 set rc [catchsql {COMMIT}] |
102 list | 111 list |
103 } {} | 112 } {} |
104 set ::sqlite_io_error_hit 0 | 113 set ::sqlite_io_error_hit 0 |
105 set ::sqlite_io_error_persist 0 | 114 set ::sqlite_io_error_persist 0 |
106 set ::sqlite_io_error_pending 0 | 115 set ::sqlite_io_error_pending 0 |
107 | 116 |
108 # Read the contents of the database file into a Tcl variable. | 117 # Read the contents of the database file into a Tcl variable. |
109 # | 118 # |
110 set fd [open test.db] | 119 set fd [open test.db] |
111 fconfigure $fd -translation binary -encoding binary | 120 fconfigure $fd -translation binary -encoding binary |
112 set zDatabase [read $fd] | 121 set zDatabase [read $fd] |
113 close $fd | 122 close $fd |
114 | 123 |
115 # Set a very low soft-limit and then try to compile an SQL statement | 124 # Set a very low soft-limit and then try to compile an SQL statement |
116 # from UTF-16 text. To do this, SQLite will need to reclaim memory | 125 # from UTF-16 text. To do this, SQLite will need to reclaim memory |
117 # from the pager that is in error state. Including that associated | 126 # from the pager that is in error state. Including that associated |
118 # with the dirty page. | 127 # with the dirty page. |
119 # | 128 # |
120 do_test ioerr5-1.$locking_mode-$iFail.3 { | 129 do_test ioerr5-1.$locking_mode-$iFail.3 { |
121 set bt [btree_from_db db] | |
122 sqlite3_soft_heap_limit 1024 | 130 sqlite3_soft_heap_limit 1024 |
123 compilesql16 "SELECT 10" | 131 compilesql16 "SELECT 10" |
124 array set stats [btree_pager_stats $bt] | 132 } {SQLITE_OK} |
125 | 133 |
126 # If the pager made it all the way to PAGER_SYNCED state, then | 134 close $channel |
127 # both in-memory pages are clean. Following the calls to | |
128 # release_memory() that were made as part of the [compilesql16] | |
129 # above, there will be zero pages left in the cache. | |
130 # | |
131 # If the pager did not make it as far as PAGER_SYNCED, the two | |
132 # in memory pages are still dirty. So there will be 2 pages left | |
133 # in the cache following the release_memory() calls. | |
134 # | |
135 if {$stats(state)==5} { | |
136 set nPage 0 | |
137 } | |
138 expr {$stats(page)==$nPage} | |
139 } {1} | |
140 | 135 |
141 # Ensure that nothing was written to the database while reclaiming | 136 # Ensure that nothing was written to the database while reclaiming |
142 # memory from the pager in error state. | 137 # memory from the pager in error state. |
143 # | 138 # |
144 do_test ioerr5-1.$locking_mode-$iFail.4 { | 139 do_test ioerr5-1.$locking_mode-$iFail.4 { |
145 set fd [open test.db] | 140 set fd [open test.db] |
146 fconfigure $fd -translation binary -encoding binary | 141 fconfigure $fd -translation binary -encoding binary |
147 set zDatabase2 [read $fd] | 142 set zDatabase2 [read $fd] |
148 close $fd | 143 close $fd |
149 expr {$zDatabase eq $zDatabase2} | 144 expr {$zDatabase eq $zDatabase2} |
150 } {1} | 145 } {1} |
151 | 146 |
152 if {$rc eq [list 0 {}]} { | 147 if {$rc eq [list 0 {}]} { |
153 do_test ioerr5.1-$locking_mode-$iFail.3 { | 148 do_test ioerr5.1-$locking_mode-$iFail.3 { |
154 execsql { SELECT count(*) FROM a } | 149 execsql { SELECT count(*) FROM a } |
155 } [expr $nRow+1] | 150 } [expr $nRow+1] |
156 break | 151 break |
157 } | 152 } |
158 } | 153 } |
159 } | 154 } |
160 | 155 |
161 # Make sure this test script doesn't leave any files open. | 156 # Make sure this test script doesn't leave any files open. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 do_test ioerr5-2.X { | 207 do_test ioerr5-2.X { |
213 catch { db close } | 208 catch { db close } |
214 catch { db2 close } | 209 catch { db2 close } |
215 set sqlite_open_file_count | 210 set sqlite_open_file_count |
216 } 0 | 211 } 0 |
217 | 212 |
218 sqlite3_enable_shared_cache $::enable_shared_cache | 213 sqlite3_enable_shared_cache $::enable_shared_cache |
219 sqlite3_soft_heap_limit $::soft_limit | 214 sqlite3_soft_heap_limit $::soft_limit |
220 | 215 |
221 finish_test | 216 finish_test |
OLD | NEW |