|
1 # 2005 December 30 |
|
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 # The focus of the tests in this file are IO errors that occur in a shared |
|
13 # cache context. What happens to connection B if one connection A encounters |
|
14 # an IO-error whilst reading or writing the file-system? |
|
15 # |
|
16 # $Id: shared_err.test,v 1.23 2008/09/29 14:12:57 danielk1977 Exp $ |
|
17 |
|
18 proc skip {args} {} |
|
19 |
|
20 |
|
21 set testdir [file dirname $argv0] |
|
22 source $testdir/tester.tcl |
|
23 source $testdir/malloc_common.tcl |
|
24 db close |
|
25 |
|
26 ifcapable !shared_cache||!subquery { |
|
27 finish_test |
|
28 return |
|
29 } |
|
30 |
|
31 set ::enable_shared_cache [sqlite3_enable_shared_cache 1] |
|
32 |
|
33 do_ioerr_test shared_ioerr-1 -tclprep { |
|
34 sqlite3 db2 test.db |
|
35 execsql { |
|
36 PRAGMA read_uncommitted = 1; |
|
37 CREATE TABLE t1(a,b,c); |
|
38 BEGIN; |
|
39 SELECT * FROM sqlite_master; |
|
40 } db2 |
|
41 } -sqlbody { |
|
42 SELECT * FROM sqlite_master; |
|
43 INSERT INTO t1 VALUES(1,2,3); |
|
44 BEGIN TRANSACTION; |
|
45 INSERT INTO t1 VALUES(1,2,3); |
|
46 INSERT INTO t1 VALUES(4,5,6); |
|
47 ROLLBACK; |
|
48 SELECT * FROM t1; |
|
49 BEGIN TRANSACTION; |
|
50 INSERT INTO t1 VALUES(1,2,3); |
|
51 INSERT INTO t1 VALUES(4,5,6); |
|
52 COMMIT; |
|
53 SELECT * FROM t1; |
|
54 DELETE FROM t1 WHERE a<100; |
|
55 } -cleanup { |
|
56 do_test shared_ioerr-1.$n.cleanup.1 { |
|
57 set res [catchsql { |
|
58 SELECT * FROM t1; |
|
59 } db2] |
|
60 set possible_results [list \ |
|
61 "1 {disk I/O error}" \ |
|
62 "0 {1 2 3}" \ |
|
63 "0 {1 2 3 1 2 3 4 5 6}" \ |
|
64 "0 {1 2 3 1 2 3 4 5 6 1 2 3 4 5 6}" \ |
|
65 "0 {}" \ |
|
66 "1 {database disk image is malformed}" \ |
|
67 ] |
|
68 set rc [expr [lsearch -exact $possible_results $res] >= 0] |
|
69 if {$rc != 1} { |
|
70 puts "" |
|
71 puts "Result: $res" |
|
72 } |
|
73 set rc |
|
74 } {1} |
|
75 |
|
76 # The "database disk image is malformed" is a special case that can |
|
77 # occur if an IO error occurs during a rollback in the {SELECT * FROM t1} |
|
78 # statement above. This test is to make sure there is no real database |
|
79 # corruption. |
|
80 db2 close |
|
81 do_test shared_ioerr-1.$n.cleanup.2 { |
|
82 execsql {pragma integrity_check} db |
|
83 } {ok} |
|
84 } |
|
85 |
|
86 do_ioerr_test shared_ioerr-2 -tclprep { |
|
87 sqlite3 db2 test.db |
|
88 execsql { |
|
89 PRAGMA read_uncommitted = 1; |
|
90 BEGIN; |
|
91 CREATE TABLE t1(a, b); |
|
92 INSERT INTO t1(oid) VALUES(NULL); |
|
93 INSERT INTO t1(oid) SELECT NULL FROM t1; |
|
94 INSERT INTO t1(oid) SELECT NULL FROM t1; |
|
95 INSERT INTO t1(oid) SELECT NULL FROM t1; |
|
96 INSERT INTO t1(oid) SELECT NULL FROM t1; |
|
97 INSERT INTO t1(oid) SELECT NULL FROM t1; |
|
98 INSERT INTO t1(oid) SELECT NULL FROM t1; |
|
99 INSERT INTO t1(oid) SELECT NULL FROM t1; |
|
100 INSERT INTO t1(oid) SELECT NULL FROM t1; |
|
101 INSERT INTO t1(oid) SELECT NULL FROM t1; |
|
102 INSERT INTO t1(oid) SELECT NULL FROM t1; |
|
103 UPDATE t1 set a = oid, b = 'abcdefghijklmnopqrstuvwxyz0123456789'; |
|
104 CREATE INDEX i1 ON t1(a); |
|
105 COMMIT; |
|
106 BEGIN; |
|
107 SELECT * FROM sqlite_master; |
|
108 } db2 |
|
109 } -tclbody { |
|
110 set ::residx 0 |
|
111 execsql {DELETE FROM t1 WHERE 0 = (a % 2);} |
|
112 incr ::residx |
|
113 |
|
114 # When this transaction begins the table contains 512 entries. The |
|
115 # two statements together add 512+146 more if it succeeds. |
|
116 # (1024/7==146) |
|
117 execsql {BEGIN;} |
|
118 execsql {INSERT INTO t1 SELECT a+1, b FROM t1;} |
|
119 execsql {INSERT INTO t1 SELECT 'string' || a, b FROM t1 WHERE 0 = (a%7);} |
|
120 execsql {COMMIT;} |
|
121 |
|
122 incr ::residx |
|
123 } -cleanup { |
|
124 catchsql ROLLBACK |
|
125 do_test shared_ioerr-2.$n.cleanup.1 { |
|
126 set res [catchsql { |
|
127 SELECT max(a), min(a), count(*) FROM (SELECT a FROM t1 order by a); |
|
128 } db2] |
|
129 set possible_results [list \ |
|
130 {0 {1024 1 1024}} \ |
|
131 {0 {1023 1 512}} \ |
|
132 {0 {string994 1 1170}} \ |
|
133 ] |
|
134 set idx [lsearch -exact $possible_results $res] |
|
135 set success [expr {$idx==$::residx || $res=="1 {disk I/O error}"}] |
|
136 if {!$success} { |
|
137 puts "" |
|
138 puts "Result: \"$res\" ($::residx)" |
|
139 } |
|
140 set success |
|
141 } {1} |
|
142 db2 close |
|
143 } |
|
144 |
|
145 # This test is designed to provoke an IO error when a cursor position is |
|
146 # "saved" (because another cursor is going to modify the underlying table). |
|
147 # |
|
148 do_ioerr_test shared_ioerr-3 -tclprep { |
|
149 sqlite3 db2 test.db |
|
150 execsql { |
|
151 PRAGMA read_uncommitted = 1; |
|
152 PRAGMA cache_size = 10; |
|
153 BEGIN; |
|
154 CREATE TABLE t1(a, b, UNIQUE(a, b)); |
|
155 } db2 |
|
156 for {set i 0} {$i < 200} {incr i} { |
|
157 set a [string range [string repeat "[format %03d $i]." 5] 0 end-1] |
|
158 |
|
159 set b [string repeat $i 2000] |
|
160 execsql {INSERT INTO t1 VALUES($a, $b)} db2 |
|
161 } |
|
162 execsql {COMMIT} db2 |
|
163 set ::DB2 [sqlite3_connection_pointer db2] |
|
164 set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY] |
|
165 sqlite3_step $::STMT ;# Cursor points at 000.000.000.000 |
|
166 sqlite3_step $::STMT ;# Cursor points at 001.001.001.001 |
|
167 |
|
168 } -tclbody { |
|
169 execsql { |
|
170 BEGIN; |
|
171 INSERT INTO t1 VALUES('201.201.201.201.201', NULL); |
|
172 UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%'; |
|
173 COMMIT; |
|
174 } |
|
175 } -cleanup { |
|
176 set ::steprc [sqlite3_step $::STMT] |
|
177 set ::column [sqlite3_column_text $::STMT 0] |
|
178 set ::finalrc [sqlite3_finalize $::STMT] |
|
179 |
|
180 # There are three possible outcomes here (assuming persistent IO errors): |
|
181 # |
|
182 # 1. If the [sqlite3_step] did not require any IO (required pages in |
|
183 # the cache), then the next row ("002...") may be retrieved |
|
184 # successfully. |
|
185 # |
|
186 # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns |
|
187 # SQLITE_ERROR and [sqlite3_finalize] returns IOERR. |
|
188 # |
|
189 # 3. If, after the initial IO error, SQLite tried to rollback the |
|
190 # active transaction and a second IO error was encountered, then |
|
191 # statement $::STMT will have been aborted. This means [sqlite3_stmt] |
|
192 # returns SQLITE_ABORT, and the statement cursor does not move. i.e. |
|
193 # [sqlite3_column] still returns the current row ("001...") and |
|
194 # [sqlite3_finalize] returns SQLITE_OK. |
|
195 # |
|
196 |
|
197 do_test shared_ioerr-3.$n.cleanup.1 { |
|
198 expr { |
|
199 $::steprc eq "SQLITE_ROW" || |
|
200 $::steprc eq "SQLITE_ERROR" || |
|
201 $::steprc eq "SQLITE_ABORT" |
|
202 } |
|
203 } {1} |
|
204 do_test shared_ioerr-3.$n.cleanup.2 { |
|
205 expr { |
|
206 ($::steprc eq "SQLITE_ROW" && $::column eq "002.002.002.002.002") || |
|
207 ($::steprc eq "SQLITE_ERROR" && $::column eq "") || |
|
208 ($::steprc eq "SQLITE_ABORT" && $::column eq "001.001.001.001.001") |
|
209 } |
|
210 } {1} |
|
211 do_test shared_ioerr-3.$n.cleanup.3 { |
|
212 expr { |
|
213 ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") || |
|
214 ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") || |
|
215 ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_ABORT") |
|
216 } |
|
217 } {1} |
|
218 |
|
219 # db2 eval {select * from sqlite_master} |
|
220 db2 close |
|
221 } |
|
222 |
|
223 # This is a repeat of the previous test except that this time we |
|
224 # are doing a reverse-order scan of the table when the cursor is |
|
225 # "saved". |
|
226 # |
|
227 do_ioerr_test shared_ioerr-3rev -tclprep { |
|
228 sqlite3 db2 test.db |
|
229 execsql { |
|
230 PRAGMA read_uncommitted = 1; |
|
231 PRAGMA cache_size = 10; |
|
232 BEGIN; |
|
233 CREATE TABLE t1(a, b, UNIQUE(a, b)); |
|
234 } db2 |
|
235 for {set i 0} {$i < 200} {incr i} { |
|
236 set a [string range [string repeat "[format %03d $i]." 5] 0 end-1] |
|
237 |
|
238 set b [string repeat $i 2000] |
|
239 execsql {INSERT INTO t1 VALUES($a, $b)} db2 |
|
240 } |
|
241 execsql {COMMIT} db2 |
|
242 set ::DB2 [sqlite3_connection_pointer db2] |
|
243 set ::STMT [sqlite3_prepare $::DB2 \ |
|
244 "SELECT a FROM t1 ORDER BY a DESC" -1 DUMMY] |
|
245 sqlite3_step $::STMT ;# Cursor points at 199.199.199.199.199 |
|
246 sqlite3_step $::STMT ;# Cursor points at 198.198.198.198.198 |
|
247 |
|
248 } -tclbody { |
|
249 execsql { |
|
250 BEGIN; |
|
251 INSERT INTO t1 VALUES('201.201.201.201.201', NULL); |
|
252 UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%'; |
|
253 COMMIT; |
|
254 } |
|
255 } -cleanup { |
|
256 set ::steprc [sqlite3_step $::STMT] |
|
257 set ::column [sqlite3_column_text $::STMT 0] |
|
258 set ::finalrc [sqlite3_finalize $::STMT] |
|
259 |
|
260 # There are three possible outcomes here (assuming persistent IO errors): |
|
261 # |
|
262 # 1. If the [sqlite3_step] did not require any IO (required pages in |
|
263 # the cache), then the next row ("002...") may be retrieved |
|
264 # successfully. |
|
265 # |
|
266 # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns |
|
267 # SQLITE_ERROR and [sqlite3_finalize] returns IOERR. |
|
268 # |
|
269 # 3. If, after the initial IO error, SQLite tried to rollback the |
|
270 # active transaction and a second IO error was encountered, then |
|
271 # statement $::STMT will have been aborted. This means [sqlite3_stmt] |
|
272 # returns SQLITE_ABORT, and the statement cursor does not move. i.e. |
|
273 # [sqlite3_column] still returns the current row ("001...") and |
|
274 # [sqlite3_finalize] returns SQLITE_OK. |
|
275 # |
|
276 |
|
277 do_test shared_ioerr-3rev.$n.cleanup.1 { |
|
278 expr { |
|
279 $::steprc eq "SQLITE_ROW" || |
|
280 $::steprc eq "SQLITE_ERROR" || |
|
281 $::steprc eq "SQLITE_ABORT" |
|
282 } |
|
283 } {1} |
|
284 do_test shared_ioerr-3rev.$n.cleanup.2 { |
|
285 expr { |
|
286 ($::steprc eq "SQLITE_ROW" && $::column eq "197.197.197.197.197") || |
|
287 ($::steprc eq "SQLITE_ERROR" && $::column eq "") || |
|
288 ($::steprc eq "SQLITE_ABORT" && $::column eq "198.198.198.198.198") |
|
289 } |
|
290 } {1} |
|
291 do_test shared_ioerr-3rev.$n.cleanup.3 { |
|
292 expr { |
|
293 ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") || |
|
294 ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") || |
|
295 ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_ABORT") |
|
296 } |
|
297 } {1} |
|
298 |
|
299 # db2 eval {select * from sqlite_master} |
|
300 db2 close |
|
301 } |
|
302 |
|
303 # Provoke a malloc() failure when a cursor position is being saved. This |
|
304 # only happens with index cursors (because they malloc() space to save the |
|
305 # current key value). It does not happen with tables, because an integer |
|
306 # key does not require a malloc() to store. |
|
307 # |
|
308 # The library should return an SQLITE_NOMEM to the caller. The query that |
|
309 # owns the cursor (the one for which the position is not saved) should |
|
310 # continue unaffected. |
|
311 # |
|
312 do_malloc_test shared_err-4 -tclprep { |
|
313 sqlite3 db2 test.db |
|
314 execsql { |
|
315 PRAGMA read_uncommitted = 1; |
|
316 BEGIN; |
|
317 CREATE TABLE t1(a, b, UNIQUE(a, b)); |
|
318 } db2 |
|
319 for {set i 0} {$i < 5} {incr i} { |
|
320 set a [string repeat $i 10] |
|
321 set b [string repeat $i 2000] |
|
322 execsql {INSERT INTO t1 VALUES($a, $b)} db2 |
|
323 } |
|
324 execsql {COMMIT} db2 |
|
325 set ::DB2 [sqlite3_connection_pointer db2] |
|
326 set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY] |
|
327 sqlite3_step $::STMT ;# Cursor points at 0000000000 |
|
328 sqlite3_step $::STMT ;# Cursor points at 1111111111 |
|
329 } -tclbody { |
|
330 execsql { |
|
331 INSERT INTO t1 VALUES(6, NULL); |
|
332 } |
|
333 } -cleanup { |
|
334 do_test shared_malloc-4.$::n.cleanup.1 { |
|
335 set ::rc [sqlite3_step $::STMT] |
|
336 expr {$::rc=="SQLITE_ROW" || $::rc=="SQLITE_ERROR"} |
|
337 } {1} |
|
338 if {$::rc=="SQLITE_ROW"} { |
|
339 do_test shared_malloc-4.$::n.cleanup.2 { |
|
340 sqlite3_column_text $::STMT 0 |
|
341 } {2222222222} |
|
342 } |
|
343 do_test shared_malloc-4.$::n.cleanup.3 { |
|
344 set rc [sqlite3_finalize $::STMT] |
|
345 expr {$rc=="SQLITE_OK" || $rc=="SQLITE_ABORT" || |
|
346 $rc=="SQLITE_NOMEM" || $rc=="SQLITE_IOERR"} |
|
347 } {1} |
|
348 # db2 eval {select * from sqlite_master} |
|
349 db2 close |
|
350 } |
|
351 |
|
352 do_malloc_test shared_err-5 -tclbody { |
|
353 db close |
|
354 sqlite3 dbX test.db |
|
355 sqlite3 dbY test.db |
|
356 dbX close |
|
357 dbY close |
|
358 } -cleanup { |
|
359 catch {dbX close} |
|
360 catch {dbY close} |
|
361 } |
|
362 |
|
363 do_malloc_test shared_err-6 -tclbody { |
|
364 catch {db close} |
|
365 sqlite3_thread_cleanup |
|
366 sqlite3_enable_shared_cache 0 |
|
367 } -cleanup { |
|
368 sqlite3_enable_shared_cache 1 |
|
369 } |
|
370 |
|
371 # As of 3.5.0, sqlite3_enable_shared_cache can be called at |
|
372 # any time and from any thread |
|
373 #do_test shared_err-misuse-7.1 { |
|
374 # sqlite3 db test.db |
|
375 # catch { |
|
376 # sqlite3_enable_shared_cache 0 |
|
377 # } msg |
|
378 # set msg |
|
379 #} {library routine called out of sequence} |
|
380 |
|
381 # Again provoke a malloc() failure when a cursor position is being saved, |
|
382 # this time during a ROLLBACK operation by some other handle. |
|
383 # |
|
384 # The library should return an SQLITE_NOMEM to the caller. The query that |
|
385 # owns the cursor (the one for which the position is not saved) should |
|
386 # be aborted. |
|
387 # |
|
388 set ::aborted 0 |
|
389 do_malloc_test shared_err-8 -tclprep { |
|
390 sqlite3 db2 test.db |
|
391 execsql { |
|
392 PRAGMA read_uncommitted = 1; |
|
393 BEGIN; |
|
394 CREATE TABLE t1(a, b, UNIQUE(a, b)); |
|
395 } db2 |
|
396 for {set i 0} {$i < 2} {incr i} { |
|
397 set a [string repeat $i 10] |
|
398 set b [string repeat $i 2000] |
|
399 execsql {INSERT INTO t1 VALUES($a, $b)} db2 |
|
400 } |
|
401 execsql {COMMIT} db2 |
|
402 set ::DB2 [sqlite3_connection_pointer db2] |
|
403 set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY] |
|
404 sqlite3_step $::STMT ;# Cursor points at 0000000000 |
|
405 sqlite3_step $::STMT ;# Cursor points at 1111111111 |
|
406 } -tclbody { |
|
407 execsql { |
|
408 BEGIN; |
|
409 INSERT INTO t1 VALUES(6, NULL); |
|
410 ROLLBACK; |
|
411 } |
|
412 } -cleanup { |
|
413 # UPDATE: As of [5668], if the rollback fails SQLITE_CORRUPT is returned. |
|
414 # So these tests have been updated to expect SQLITE_CORRUPT and its |
|
415 # associated English language error message. |
|
416 # |
|
417 do_test shared_malloc-8.$::n.cleanup.1 { |
|
418 set res [catchsql {SELECT a FROM t1} db2] |
|
419 set ans [lindex $res 1] |
|
420 if {[lindex $res 0]} { |
|
421 set r [expr { |
|
422 $ans=="disk I/O error" || |
|
423 $ans=="out of memory" || |
|
424 $ans=="database disk image is malformed" |
|
425 }] |
|
426 } else { |
|
427 set r [expr {[lrange $ans 0 1]=="0000000000 1111111111"}] |
|
428 } |
|
429 } {1} |
|
430 do_test shared_malloc-8.$::n.cleanup.2 { |
|
431 set rc1 [sqlite3_step $::STMT] |
|
432 set rc2 [sqlite3_finalize $::STMT] |
|
433 if {$rc2=="SQLITE_ABORT"} { |
|
434 incr ::aborted |
|
435 } |
|
436 expr { |
|
437 ($rc1=="SQLITE_DONE" && $rc2=="SQLITE_OK") || |
|
438 ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_ABORT") || |
|
439 ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_NOMEM") || |
|
440 ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_IOERR") || |
|
441 ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_CORRUPT") |
|
442 } |
|
443 } {1} |
|
444 db2 close |
|
445 } |
|
446 do_test shared_malloc-8.X { |
|
447 # Test that one or more queries were aborted due to the malloc() failure. |
|
448 expr $::aborted>=1 |
|
449 } {1} |
|
450 |
|
451 # This test is designed to catch a specific bug that was present during |
|
452 # development of 3.5.0. If a malloc() failed while setting the page-size, |
|
453 # a buffer (Pager.pTmpSpace) was being freed. This could cause a seg-fault |
|
454 # later if another connection tried to use the pager. |
|
455 # |
|
456 # This test will crash 3.4.2. |
|
457 # |
|
458 do_malloc_test shared_err-9 -tclprep { |
|
459 sqlite3 db2 test.db |
|
460 } -sqlbody { |
|
461 PRAGMA page_size = 4096; |
|
462 PRAGMA page_size = 1024; |
|
463 } -cleanup { |
|
464 db2 eval { |
|
465 CREATE TABLE abc(a, b, c); |
|
466 BEGIN; |
|
467 INSERT INTO abc VALUES(1, 2, 3); |
|
468 ROLLBACK; |
|
469 } |
|
470 db2 close |
|
471 } |
|
472 |
|
473 catch {db close} |
|
474 catch {db2 close} |
|
475 do_malloc_test shared_err-10 -tclprep { |
|
476 sqlite3 db test.db |
|
477 sqlite3 db2 test.db |
|
478 |
|
479 db eval { SELECT * FROM sqlite_master } |
|
480 db2 eval { |
|
481 BEGIN; |
|
482 CREATE TABLE abc(a, b, c); |
|
483 } |
|
484 } -tclbody { |
|
485 catch {db eval {SELECT * FROM sqlite_master}} |
|
486 error 1 |
|
487 } -cleanup { |
|
488 execsql { SELECT * FROM sqlite_master } |
|
489 } |
|
490 |
|
491 do_malloc_test shared_err-11 -tclprep { |
|
492 sqlite3 db test.db |
|
493 sqlite3 db2 test.db |
|
494 |
|
495 db eval { SELECT * FROM sqlite_master } |
|
496 db2 eval { |
|
497 BEGIN; |
|
498 CREATE TABLE abc(a, b, c); |
|
499 } |
|
500 } -tclbody { |
|
501 catch {db eval {SELECT * FROM sqlite_master}} |
|
502 catch {sqlite3_errmsg16 db} |
|
503 error 1 |
|
504 } -cleanup { |
|
505 execsql { SELECT * FROM sqlite_master } |
|
506 } |
|
507 |
|
508 catch {db close} |
|
509 catch {db2 close} |
|
510 |
|
511 do_malloc_test shared_err-12 -sqlbody { |
|
512 CREATE TABLE abc(a, b, c); |
|
513 INSERT INTO abc VALUES(1, 2, 3); |
|
514 } |
|
515 |
|
516 catch {db close} |
|
517 catch {db2 close} |
|
518 sqlite3_enable_shared_cache $::enable_shared_cache |
|
519 finish_test |