OLD | NEW |
1 # 2010 April 13 | 1 # 2010 April 13 |
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 wal | 22 set testprefix wal |
23 | 23 |
24 ifcapable !wal {finish_test ; return } | 24 ifcapable !wal {finish_test ; return } |
25 | 25 |
26 proc reopen_db {} { | 26 proc reopen_db {} { |
27 catch { db close } | 27 catch { db close } |
28 file delete -force test.db test.db-wal test.db-wal-summary | 28 forcedelete test.db test.db-wal test.db-wal-summary |
29 sqlite3_wal db test.db | 29 sqlite3_wal db test.db |
30 } | 30 } |
31 | 31 |
32 set ::blobcnt 0 | 32 set ::blobcnt 0 |
33 proc blob {nByte} { | 33 proc blob {nByte} { |
34 incr ::blobcnt | 34 incr ::blobcnt |
35 return [string range [string repeat "${::blobcnt}x" $nByte] 1 $nByte] | 35 return [string range [string repeat "${::blobcnt}x" $nByte] 1 $nByte] |
36 } | 36 } |
37 | 37 |
38 proc sqlite3_wal {args} { | 38 proc sqlite3_wal {args} { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 execsql { | 204 execsql { |
205 INSERT INTO t1 VALUES('x', 'y'); | 205 INSERT INTO t1 VALUES('x', 'y'); |
206 RELEASE tr; | 206 RELEASE tr; |
207 } | 207 } |
208 expr { $logsize == [file size test.db-wal] } | 208 expr { $logsize == [file size test.db-wal] } |
209 } {1} | 209 } {1} |
210 do_test wal-4.4.5 { | 210 do_test wal-4.4.5 { |
211 execsql { SELECT count(*) FROM t2 } | 211 execsql { SELECT count(*) FROM t2 } |
212 } {1} | 212 } {1} |
213 do_test wal-4.4.6 { | 213 do_test wal-4.4.6 { |
214 file copy -force test.db test2.db | 214 forcecopy test.db test2.db |
215 file copy -force test.db-wal test2.db-wal | 215 forcecopy test.db-wal test2.db-wal |
216 sqlite3 db2 test2.db | 216 sqlite3 db2 test2.db |
217 execsql { SELECT count(*) FROM t2 ; SELECT count(*) FROM t1 } db2 | 217 execsql { SELECT count(*) FROM t2 ; SELECT count(*) FROM t1 } db2 |
218 } {1 2} | 218 } {1 2} |
219 do_test wal-4.4.7 { | 219 do_test wal-4.4.7 { |
220 execsql { PRAGMA integrity_check } db2 | 220 execsql { PRAGMA integrity_check } db2 |
221 } {ok} | 221 } {ok} |
222 db2 close | 222 db2 close |
223 | 223 |
224 do_test wal-4.5.1 { | 224 do_test wal-4.5.1 { |
225 reopen_db | 225 reopen_db |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 INSERT INTO t1 VALUES('x', 'y'); | 262 INSERT INTO t1 VALUES('x', 'y'); |
263 RELEASE tr; | 263 RELEASE tr; |
264 COMMIT; | 264 COMMIT; |
265 } | 265 } |
266 expr { $logsize == [file size test.db-wal] } | 266 expr { $logsize == [file size test.db-wal] } |
267 } {1} | 267 } {1} |
268 do_test wal-4.5.5 { | 268 do_test wal-4.5.5 { |
269 execsql { SELECT count(*) FROM t2 ; SELECT count(*) FROM t1 } | 269 execsql { SELECT count(*) FROM t2 ; SELECT count(*) FROM t1 } |
270 } {1 2} | 270 } {1 2} |
271 do_test wal-4.5.6 { | 271 do_test wal-4.5.6 { |
272 file copy -force test.db test2.db | 272 forcecopy test.db test2.db |
273 file copy -force test.db-wal test2.db-wal | 273 forcecopy test.db-wal test2.db-wal |
274 sqlite3 db2 test2.db | 274 sqlite3 db2 test2.db |
275 execsql { SELECT count(*) FROM t2 ; SELECT count(*) FROM t1 } db2 | 275 execsql { SELECT count(*) FROM t2 ; SELECT count(*) FROM t1 } db2 |
276 } {1 2} | 276 } {1 2} |
277 do_test wal-4.5.7 { | 277 do_test wal-4.5.7 { |
278 execsql { PRAGMA integrity_check } db2 | 278 execsql { PRAGMA integrity_check } db2 |
279 } {ok} | 279 } {ok} |
280 db2 close | 280 db2 close |
281 | 281 |
282 do_test wal-4.6.1 { | 282 do_test wal-4.6.1 { |
283 execsql { | 283 execsql { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 } | 315 } |
316 } {1 2} | 316 } {1 2} |
317 do_test wal-5.4 { | 317 do_test wal-5.4 { |
318 execsql { | 318 execsql { |
319 CREATE TEMP TABLE t3(x UNIQUE); | 319 CREATE TEMP TABLE t3(x UNIQUE); |
320 BEGIN; | 320 BEGIN; |
321 INSERT INTO t2 VALUES(3, 4); | 321 INSERT INTO t2 VALUES(3, 4); |
322 INSERT INTO t3 VALUES('abc'); | 322 INSERT INTO t3 VALUES('abc'); |
323 } | 323 } |
324 catchsql { INSERT INTO t3 VALUES('abc') } | 324 catchsql { INSERT INTO t3 VALUES('abc') } |
325 } {1 {column x is not unique}} | 325 } {1 {UNIQUE constraint failed: t3.x}} |
326 do_test wal-5.5 { | 326 do_test wal-5.5 { |
327 execsql { | 327 execsql { |
328 COMMIT; | 328 COMMIT; |
329 SELECT * FROM t2; | 329 SELECT * FROM t2; |
330 } | 330 } |
331 } {1 2 3 4} | 331 } {1 2 3 4} |
332 db close | 332 db close |
333 | 333 |
334 foreach sector {512 4096} { | 334 foreach sector {512 4096} { |
335 sqlite3_simulate_device -sectorsize $sector | 335 sqlite3_simulate_device -sectorsize $sector |
336 foreach pgsz {512 1024 2048 4096} { | 336 foreach pgsz {512 1024 2048 4096} { |
337 file delete -force test.db test.db-wal | 337 forcedelete test.db test.db-wal |
338 do_test wal-6.$sector.$pgsz.1 { | 338 do_test wal-6.$sector.$pgsz.1 { |
339 sqlite3 db test.db -vfs devsym | 339 sqlite3 db test.db -vfs devsym |
340 execsql " | 340 execsql " |
341 PRAGMA page_size = $pgsz; | 341 PRAGMA page_size = $pgsz; |
342 PRAGMA auto_vacuum = 0; | 342 PRAGMA auto_vacuum = 0; |
343 PRAGMA journal_mode = wal; | 343 PRAGMA journal_mode = wal; |
344 " | 344 " |
345 execsql " | 345 execsql " |
346 CREATE TABLE t1(a, b); | 346 CREATE TABLE t1(a, b); |
347 INSERT INTO t1 VALUES(1, 2); | 347 INSERT INTO t1 VALUES(1, 2); |
348 " | 348 " |
349 db close | 349 db close |
350 file size test.db | 350 file size test.db |
351 } [expr $pgsz*2] | 351 } [expr $pgsz*2] |
352 | 352 |
353 do_test wal-6.$sector.$pgsz.2 { | 353 do_test wal-6.$sector.$pgsz.2 { |
354 log_deleted test.db-wal | 354 log_deleted test.db-wal |
355 } {1} | 355 } {1} |
356 } | 356 } |
357 } | 357 } |
358 | 358 |
359 do_test wal-7.1 { | 359 do_test wal-7.1 { |
360 file delete -force test.db test.db-wal | 360 forcedelete test.db test.db-wal |
361 sqlite3_wal db test.db | 361 sqlite3_wal db test.db |
362 execsql { | 362 execsql { |
363 PRAGMA page_size = 1024; | 363 PRAGMA page_size = 1024; |
364 CREATE TABLE t1(a, b); | 364 CREATE TABLE t1(a, b); |
365 INSERT INTO t1 VALUES(1, 2); | 365 INSERT INTO t1 VALUES(1, 2); |
366 } | 366 } |
367 list [file size test.db] [file size test.db-wal] | 367 list [file size test.db] [file size test.db-wal] |
368 } [list 1024 [wal_file_size 3 1024]] | 368 } [list 1024 [wal_file_size 3 1024]] |
369 do_test wal-7.2 { | 369 do_test wal-7.2 { |
370 execsql { PRAGMA wal_checkpoint } | 370 execsql { PRAGMA wal_checkpoint } |
371 list [file size test.db] [file size test.db-wal] | 371 list [file size test.db] [file size test.db-wal] |
372 } [list 2048 [wal_file_size 3 1024]] | 372 } [list 2048 [wal_file_size 3 1024]] |
373 | 373 |
374 # Execute some transactions in auto-vacuum mode to test database file | 374 # Execute some transactions in auto-vacuum mode to test database file |
375 # truncation. | 375 # truncation. |
376 # | 376 # |
377 do_test wal-8.1 { | 377 do_test wal-8.1 { |
378 reopen_db | 378 reopen_db |
379 catch { db close } | 379 catch { db close } |
380 file delete -force test.db test.db-wal | 380 forcedelete test.db test.db-wal |
381 | 381 |
382 sqlite3 db test.db | 382 sqlite3 db test.db |
383 db function blob blob | 383 db function blob blob |
384 execsql { | 384 execsql { |
385 PRAGMA auto_vacuum = 1; | 385 PRAGMA auto_vacuum = 1; |
386 PRAGMA journal_mode = wal; | 386 PRAGMA journal_mode = wal; |
387 PRAGMA auto_vacuum; | 387 PRAGMA auto_vacuum; |
388 } | 388 } |
389 } {wal 1} | 389 } {wal 1} |
390 do_test wal-8.2 { | 390 do_test wal-8.2 { |
(...skipping 18 matching lines...) Expand all Loading... |
409 } | 409 } |
410 file size test.db | 410 file size test.db |
411 } [expr 14*1024] | 411 } [expr 14*1024] |
412 | 412 |
413 # Run some "warm-body" tests to ensure that log-summary files with more | 413 # Run some "warm-body" tests to ensure that log-summary files with more |
414 # than 256 entries (log summaries that contain index blocks) work Ok. | 414 # than 256 entries (log summaries that contain index blocks) work Ok. |
415 # | 415 # |
416 do_test wal-9.1 { | 416 do_test wal-9.1 { |
417 reopen_db | 417 reopen_db |
418 execsql { | 418 execsql { |
| 419 PRAGMA cache_size=2000; |
419 CREATE TABLE t1(x PRIMARY KEY); | 420 CREATE TABLE t1(x PRIMARY KEY); |
420 INSERT INTO t1 VALUES(blob(900)); | 421 INSERT INTO t1 VALUES(blob(900)); |
421 INSERT INTO t1 VALUES(blob(900)); | 422 INSERT INTO t1 VALUES(blob(900)); |
422 INSERT INTO t1 SELECT blob(900) FROM t1; /* 4 */ | 423 INSERT INTO t1 SELECT blob(900) FROM t1; /* 4 */ |
423 INSERT INTO t1 SELECT blob(900) FROM t1; /* 8 */ | 424 INSERT INTO t1 SELECT blob(900) FROM t1; /* 8 */ |
424 INSERT INTO t1 SELECT blob(900) FROM t1; /* 16 */ | 425 INSERT INTO t1 SELECT blob(900) FROM t1; /* 16 */ |
425 INSERT INTO t1 SELECT blob(900) FROM t1; /* 32 */ | 426 INSERT INTO t1 SELECT blob(900) FROM t1; /* 32 */ |
426 INSERT INTO t1 SELECT blob(900) FROM t1; /* 64 */ | 427 INSERT INTO t1 SELECT blob(900) FROM t1; /* 64 */ |
427 INSERT INTO t1 SELECT blob(900) FROM t1; /* 128 */ | 428 INSERT INTO t1 SELECT blob(900) FROM t1; /* 128 */ |
428 INSERT INTO t1 SELECT blob(900) FROM t1; /* 256 */ | 429 INSERT INTO t1 SELECT blob(900) FROM t1; /* 256 */ |
429 } | 430 } |
430 file size test.db | 431 file size test.db |
431 } 1024 | 432 } 1024 |
432 do_test wal-9.2 { | 433 do_test wal-9.2 { |
433 sqlite3_wal db2 test.db | 434 sqlite3_wal db2 test.db |
434 execsql {PRAGMA integrity_check } db2 | 435 execsql {PRAGMA integrity_check } db2 |
435 } {ok} | 436 } {ok} |
436 | 437 |
437 do_test wal-9.3 { | 438 do_test wal-9.3 { |
438 file delete -force test2.db test2.db-wal | 439 forcedelete test2.db test2.db-wal |
439 file copy test.db test2.db | 440 copy_file test.db test2.db |
440 file copy test.db-wal test2.db-wal | 441 copy_file test.db-wal test2.db-wal |
441 sqlite3_wal db3 test2.db | 442 sqlite3_wal db3 test2.db |
442 execsql {PRAGMA integrity_check } db3 | 443 execsql {PRAGMA integrity_check } db3 |
443 } {ok} | 444 } {ok} |
444 db3 close | 445 db3 close |
445 | 446 |
446 do_test wal-9.4 { | 447 do_test wal-9.4 { |
447 execsql { PRAGMA wal_checkpoint } | 448 execsql { PRAGMA wal_checkpoint } |
448 db2 close | 449 db2 close |
449 sqlite3_wal db2 test.db | 450 sqlite3_wal db2 test.db |
450 execsql {PRAGMA integrity_check } db2 | 451 execsql {PRAGMA integrity_check } db2 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 } {1 2 3 4 5 6 7 8 9 10} | 539 } {1 2 3 4 5 6 7 8 9 10} |
539 | 540 |
540 # Open a read transaction with [db2]. Check that this prevents [db] from | 541 # Open a read transaction with [db2]. Check that this prevents [db] from |
541 # checkpointing the database. But not from writing to it. | 542 # checkpointing the database. But not from writing to it. |
542 # | 543 # |
543 do_test wal-10.$tn.11 { | 544 do_test wal-10.$tn.11 { |
544 sql2 { BEGIN; SELECT * FROM t1 } | 545 sql2 { BEGIN; SELECT * FROM t1 } |
545 } {1 2 3 4 5 6 7 8 9 10} | 546 } {1 2 3 4 5 6 7 8 9 10} |
546 do_test wal-10.$tn.12 { | 547 do_test wal-10.$tn.12 { |
547 catchsql { PRAGMA wal_checkpoint } | 548 catchsql { PRAGMA wal_checkpoint } |
548 } {0 {0 13 13}} ;# Reader no longer block checkpoints | 549 } {0 {0 7 7}} ;# Reader no longer block checkpoints |
549 do_test wal-10.$tn.13 { | 550 do_test wal-10.$tn.13 { |
550 execsql { INSERT INTO t1 VALUES(11, 12) } | 551 execsql { INSERT INTO t1 VALUES(11, 12) } |
551 sql2 {SELECT * FROM t1} | 552 sql2 {SELECT * FROM t1} |
552 } {1 2 3 4 5 6 7 8 9 10} | 553 } {1 2 3 4 5 6 7 8 9 10} |
553 | 554 |
554 # Writers do not block checkpoints any more either. | 555 # Writers do not block checkpoints any more either. |
555 # | 556 # |
556 do_test wal-10.$tn.14 { | 557 do_test wal-10.$tn.14 { |
557 catchsql { PRAGMA wal_checkpoint } | 558 catchsql { PRAGMA wal_checkpoint } |
558 } {0 {0 15 13}} | 559 } {0 {0 8 7}} |
559 | 560 |
560 # The following series of test cases used to verify another blocking | 561 # The following series of test cases used to verify another blocking |
561 # case in WAL - a case which no longer blocks. | 562 # case in WAL - a case which no longer blocks. |
562 # | 563 # |
563 do_test wal-10.$tn.15 { | 564 do_test wal-10.$tn.15 { |
564 sql2 { COMMIT; BEGIN; SELECT * FROM t1; } | 565 sql2 { COMMIT; BEGIN; SELECT * FROM t1; } |
565 } {1 2 3 4 5 6 7 8 9 10 11 12} | 566 } {1 2 3 4 5 6 7 8 9 10 11 12} |
566 do_test wal-10.$tn.16 { | 567 do_test wal-10.$tn.16 { |
567 catchsql { PRAGMA wal_checkpoint } | 568 catchsql { PRAGMA wal_checkpoint } |
568 } {0 {0 15 15}} | 569 } {0 {0 8 8}} |
569 do_test wal-10.$tn.17 { | 570 do_test wal-10.$tn.17 { |
570 execsql { PRAGMA wal_checkpoint } | 571 execsql { PRAGMA wal_checkpoint } |
571 } {0 15 15} | 572 } {0 8 8} |
572 do_test wal-10.$tn.18 { | 573 do_test wal-10.$tn.18 { |
573 sql3 { BEGIN; SELECT * FROM t1 } | 574 sql3 { BEGIN; SELECT * FROM t1 } |
574 } {1 2 3 4 5 6 7 8 9 10 11 12} | 575 } {1 2 3 4 5 6 7 8 9 10 11 12} |
575 do_test wal-10.$tn.19 { | 576 do_test wal-10.$tn.19 { |
576 catchsql { INSERT INTO t1 VALUES(13, 14) } | 577 catchsql { INSERT INTO t1 VALUES(13, 14) } |
577 } {0 {}} | 578 } {0 {}} |
578 do_test wal-10.$tn.20 { | 579 do_test wal-10.$tn.20 { |
579 execsql { SELECT * FROM t1 } | 580 execsql { SELECT * FROM t1 } |
580 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} | 581 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} |
581 do_test wal-10.$tn.21 { | 582 do_test wal-10.$tn.21 { |
582 sql3 COMMIT | 583 sql3 COMMIT |
583 sql2 COMMIT | 584 sql2 COMMIT |
584 } {} | 585 } {} |
585 do_test wal-10.$tn.22 { | 586 do_test wal-10.$tn.22 { |
586 execsql { SELECT * FROM t1 } | 587 execsql { SELECT * FROM t1 } |
587 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} | 588 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} |
588 | 589 |
589 # Another series of tests that used to demonstrate blocking behavior | 590 # Another series of tests that used to demonstrate blocking behavior |
590 # but which now work. | 591 # but which now work. |
591 # | 592 # |
592 do_test wal-10.$tn.23 { | 593 do_test wal-10.$tn.23 { |
593 execsql { PRAGMA wal_checkpoint } | 594 execsql { PRAGMA wal_checkpoint } |
594 } {0 17 17} | 595 } {0 9 9} |
595 do_test wal-10.$tn.24 { | 596 do_test wal-10.$tn.24 { |
596 sql2 { BEGIN; SELECT * FROM t1; } | 597 sql2 { BEGIN; SELECT * FROM t1; } |
597 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} | 598 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} |
598 do_test wal-10.$tn.25 { | 599 do_test wal-10.$tn.25 { |
599 execsql { PRAGMA wal_checkpoint } | 600 execsql { PRAGMA wal_checkpoint } |
600 } {0 17 17} | 601 } {0 9 9} |
601 do_test wal-10.$tn.26 { | 602 do_test wal-10.$tn.26 { |
602 catchsql { INSERT INTO t1 VALUES(15, 16) } | 603 catchsql { INSERT INTO t1 VALUES(15, 16) } |
603 } {0 {}} | 604 } {0 {}} |
604 do_test wal-10.$tn.27 { | 605 do_test wal-10.$tn.27 { |
605 sql3 { INSERT INTO t1 VALUES(17, 18) } | 606 sql3 { INSERT INTO t1 VALUES(17, 18) } |
606 } {} | 607 } {} |
607 do_test wal-10.$tn.28 { | 608 do_test wal-10.$tn.28 { |
608 code3 { | 609 code3 { |
609 set ::STMT [sqlite3_prepare db3 "SELECT * FROM t1" -1 TAIL] | 610 set ::STMT [sqlite3_prepare db3 "SELECT * FROM t1" -1 TAIL] |
610 sqlite3_step $::STMT | 611 sqlite3_step $::STMT |
611 } | 612 } |
612 execsql { SELECT * FROM t1 } | 613 execsql { SELECT * FROM t1 } |
613 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18} | 614 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18} |
614 do_test wal-10.$tn.29 { | 615 do_test wal-10.$tn.29 { |
615 execsql { INSERT INTO t1 VALUES(19, 20) } | 616 execsql { INSERT INTO t1 VALUES(19, 20) } |
616 catchsql { PRAGMA wal_checkpoint } | 617 catchsql { PRAGMA wal_checkpoint } |
617 } {0 {0 6 0}} | 618 } {0 {0 3 0}} |
618 do_test wal-10.$tn.30 { | 619 do_test wal-10.$tn.30 { |
619 code3 { sqlite3_finalize $::STMT } | 620 code3 { sqlite3_finalize $::STMT } |
620 execsql { PRAGMA wal_checkpoint } | 621 execsql { PRAGMA wal_checkpoint } |
621 } {0 6 0} | 622 } {0 3 0} |
622 | 623 |
623 # At one point, if a reader failed to upgrade to a writer because it | 624 # At one point, if a reader failed to upgrade to a writer because it |
624 # was reading an old snapshot, the write-locks were not being released. | 625 # was reading an old snapshot, the write-locks were not being released. |
625 # Test that this bug has been fixed. | 626 # Test that this bug has been fixed. |
626 # | 627 # |
627 do_test wal-10.$tn.31 { | 628 do_test wal-10.$tn.31 { |
628 sql2 COMMIT | 629 sql2 COMMIT |
629 execsql { BEGIN ; SELECT * FROM t1 } | 630 execsql { BEGIN ; SELECT * FROM t1 } |
630 sql2 { INSERT INTO t1 VALUES(21, 22) } | 631 sql2 { INSERT INTO t1 VALUES(21, 22) } |
631 catchsql { INSERT INTO t1 VALUES(23, 24) } | 632 catchsql { INSERT INTO t1 VALUES(23, 24) } |
(...skipping 18 matching lines...) Expand all Loading... |
650 INSERT INTO t1 VALUES('a', 'b'); | 651 INSERT INTO t1 VALUES('a', 'b'); |
651 INSERT INTO t1 VALUES('c', 'd'); | 652 INSERT INTO t1 VALUES('c', 'd'); |
652 } | 653 } |
653 sql2 { | 654 sql2 { |
654 BEGIN; | 655 BEGIN; |
655 SELECT * FROM t1; | 656 SELECT * FROM t1; |
656 } | 657 } |
657 } {a b c d} | 658 } {a b c d} |
658 do_test wal-10.$tn.36 { | 659 do_test wal-10.$tn.36 { |
659 catchsql { PRAGMA wal_checkpoint } | 660 catchsql { PRAGMA wal_checkpoint } |
660 } {0 {0 16 16}} | 661 } {0 {0 8 8}} |
661 do_test wal-10.$tn.36 { | 662 do_test wal-10.$tn.36 { |
662 sql3 { INSERT INTO t1 VALUES('e', 'f') } | 663 sql3 { INSERT INTO t1 VALUES('e', 'f') } |
663 sql2 { SELECT * FROM t1 } | 664 sql2 { SELECT * FROM t1 } |
664 } {a b c d} | 665 } {a b c d} |
665 do_test wal-10.$tn.37 { | 666 do_test wal-10.$tn.37 { |
666 sql2 COMMIT | 667 sql2 COMMIT |
667 execsql { PRAGMA wal_checkpoint } | 668 execsql { PRAGMA wal_checkpoint } |
668 } {0 18 18} | 669 } {0 9 9} |
669 } | 670 } |
670 | 671 |
671 #------------------------------------------------------------------------- | 672 #------------------------------------------------------------------------- |
672 # This block of tests, wal-11.*, test that nothing goes terribly wrong | 673 # This block of tests, wal-11.*, test that nothing goes terribly wrong |
673 # if frames must be written to the log file before a transaction is | 674 # if frames must be written to the log file before a transaction is |
674 # committed (in order to free up memory). | 675 # committed (in order to free up memory). |
675 # | 676 # |
676 do_test wal-11.1 { | 677 do_test wal-11.1 { |
677 reopen_db | 678 reopen_db |
678 execsql { | 679 execsql { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 } {16 ok} | 720 } {16 ok} |
720 do_test wal-11.8 { | 721 do_test wal-11.8 { |
721 execsql { PRAGMA wal_checkpoint } | 722 execsql { PRAGMA wal_checkpoint } |
722 list [expr [file size test.db]/1024] [file size test.db-wal] | 723 list [expr [file size test.db]/1024] [file size test.db-wal] |
723 } [list 37 [wal_file_size 41 1024]] | 724 } [list 37 [wal_file_size 41 1024]] |
724 do_test wal-11.9 { | 725 do_test wal-11.9 { |
725 db close | 726 db close |
726 list [expr [file size test.db]/1024] [log_deleted test.db-wal] | 727 list [expr [file size test.db]/1024] [log_deleted test.db-wal] |
727 } {37 1} | 728 } {37 1} |
728 sqlite3_wal db test.db | 729 sqlite3_wal db test.db |
| 730 set nWal 39 |
| 731 if {[permutation]!="mmap"} {set nWal 37} |
| 732 ifcapable !mmap {set nWal 37} |
729 do_test wal-11.10 { | 733 do_test wal-11.10 { |
730 execsql { | 734 execsql { |
731 PRAGMA cache_size = 10; | 735 PRAGMA cache_size = 10; |
732 BEGIN; | 736 BEGIN; |
733 INSERT INTO t1 SELECT blob(900) FROM t1; -- 32 | 737 INSERT INTO t1 SELECT blob(900) FROM t1; -- 32 |
734 SELECT count(*) FROM t1; | 738 SELECT count(*) FROM t1; |
735 } | 739 } |
736 list [expr [file size test.db]/1024] [file size test.db-wal] | 740 list [expr [file size test.db]/1024] [file size test.db-wal] |
737 } [list 37 [wal_file_size 37 1024]] | 741 } [list 37 [wal_file_size $nWal 1024]] |
738 do_test wal-11.11 { | 742 do_test wal-11.11 { |
739 execsql { | 743 execsql { |
740 SELECT count(*) FROM t1; | 744 SELECT count(*) FROM t1; |
741 ROLLBACK; | 745 ROLLBACK; |
742 SELECT count(*) FROM t1; | 746 SELECT count(*) FROM t1; |
743 } | 747 } |
744 } {32 16} | 748 } {32 16} |
745 do_test wal-11.12 { | 749 do_test wal-11.12 { |
746 list [expr [file size test.db]/1024] [file size test.db-wal] | 750 list [expr [file size test.db]/1024] [file size test.db-wal] |
747 } [list 37 [wal_file_size 37 1024]] | 751 } [list 37 [wal_file_size $nWal 1024]] |
748 do_test wal-11.13 { | 752 do_test wal-11.13 { |
749 execsql { | 753 execsql { |
750 INSERT INTO t1 VALUES( blob(900) ); | 754 INSERT INTO t1 VALUES( blob(900) ); |
751 SELECT count(*) FROM t1; | 755 SELECT count(*) FROM t1; |
752 PRAGMA integrity_check; | 756 PRAGMA integrity_check; |
753 } | 757 } |
754 } {17 ok} | 758 } {17 ok} |
755 do_test wal-11.14 { | 759 do_test wal-11.14 { |
756 list [expr [file size test.db]/1024] [file size test.db-wal] | 760 list [expr [file size test.db]/1024] [file size test.db-wal] |
757 } [list 37 [wal_file_size 37 1024]] | 761 } [list 37 [wal_file_size $nWal 1024]] |
758 | 762 |
759 | 763 |
760 #------------------------------------------------------------------------- | 764 #------------------------------------------------------------------------- |
761 # This block of tests, wal-12.*, tests the fix for a problem that | 765 # This block of tests, wal-12.*, tests the fix for a problem that |
762 # could occur if a log that is a prefix of an older log is written | 766 # could occur if a log that is a prefix of an older log is written |
763 # into a reused log file. | 767 # into a reused log file. |
764 # | 768 # |
765 reopen_db | 769 reopen_db |
766 do_test wal-12.1 { | 770 do_test wal-12.1 { |
767 execsql { | 771 execsql { |
(...skipping 11 matching lines...) Expand all Loading... |
779 PRAGMA synchronous = normal; | 783 PRAGMA synchronous = normal; |
780 UPDATE t1 SET y = 0 WHERE x = 'A'; | 784 UPDATE t1 SET y = 0 WHERE x = 'A'; |
781 } | 785 } |
782 list [expr [file size test.db]/1024] [expr [file size test.db-wal]/1044] | 786 list [expr [file size test.db]/1024] [expr [file size test.db-wal]/1044] |
783 } {3 1} | 787 } {3 1} |
784 do_test wal-12.3 { | 788 do_test wal-12.3 { |
785 execsql { INSERT INTO t2 VALUES('B', 1) } | 789 execsql { INSERT INTO t2 VALUES('B', 1) } |
786 list [expr [file size test.db]/1024] [expr [file size test.db-wal]/1044] | 790 list [expr [file size test.db]/1024] [expr [file size test.db-wal]/1044] |
787 } {3 2} | 791 } {3 2} |
788 do_test wal-12.4 { | 792 do_test wal-12.4 { |
789 file copy -force test.db test2.db | 793 forcecopy test.db test2.db |
790 file copy -force test.db-wal test2.db-wal | 794 forcecopy test.db-wal test2.db-wal |
791 sqlite3_wal db2 test2.db | 795 sqlite3_wal db2 test2.db |
792 execsql { SELECT * FROM t2 } db2 | 796 execsql { SELECT * FROM t2 } db2 |
793 } {B 1} | 797 } {B 1} |
794 db2 close | 798 db2 close |
795 do_test wal-12.5 { | 799 do_test wal-12.5 { |
796 execsql { | 800 execsql { |
797 PRAGMA wal_checkpoint; | 801 PRAGMA wal_checkpoint; |
798 UPDATE t2 SET y = 2 WHERE x = 'B'; | 802 UPDATE t2 SET y = 2 WHERE x = 'B'; |
799 PRAGMA wal_checkpoint; | 803 PRAGMA wal_checkpoint; |
800 UPDATE t1 SET y = 1 WHERE x = 'A'; | 804 UPDATE t1 SET y = 1 WHERE x = 'A'; |
801 PRAGMA wal_checkpoint; | 805 PRAGMA wal_checkpoint; |
802 UPDATE t1 SET y = 0 WHERE x = 'A'; | 806 UPDATE t1 SET y = 0 WHERE x = 'A'; |
803 } | 807 } |
804 execsql { SELECT * FROM t2 } | 808 execsql { SELECT * FROM t2 } |
805 } {B 2} | 809 } {B 2} |
806 do_test wal-12.6 { | 810 do_test wal-12.6 { |
807 file copy -force test.db test2.db | 811 forcecopy test.db test2.db |
808 file copy -force test.db-wal test2.db-wal | 812 forcecopy test.db-wal test2.db-wal |
809 sqlite3_wal db2 test2.db | 813 sqlite3_wal db2 test2.db |
810 execsql { SELECT * FROM t2 } db2 | 814 execsql { SELECT * FROM t2 } db2 |
811 } {B 2} | 815 } {B 2} |
812 db2 close | 816 db2 close |
813 db close | 817 db close |
814 | 818 |
815 #------------------------------------------------------------------------- | 819 #------------------------------------------------------------------------- |
816 # Test large log summaries. | 820 # Test large log summaries. |
817 # | 821 # |
818 # In this case "large" usually means a log file that requires a wal-index | 822 # In this case "large" usually means a log file that requires a wal-index |
(...skipping 22 matching lines...) Expand all Loading... |
841 list [file exists test.db] [file exists test.db-wal] | 845 list [file exists test.db] [file exists test.db-wal] |
842 } {1 0} | 846 } {1 0} |
843 do_test wal-13.1.2 { | 847 do_test wal-13.1.2 { |
844 set fd [open test.db-wal w] | 848 set fd [open test.db-wal w] |
845 seek $fd [expr 200*1024*1024] | 849 seek $fd [expr 200*1024*1024] |
846 puts $fd "" | 850 puts $fd "" |
847 close $fd | 851 close $fd |
848 sqlite3 db test.db | 852 sqlite3 db test.db |
849 execsql { SELECT * FROM t2 } | 853 execsql { SELECT * FROM t2 } |
850 } {B 2} | 854 } {B 2} |
851 breakpoint | |
852 do_test wal-13.1.3 { | 855 do_test wal-13.1.3 { |
853 db close | 856 db close |
854 file exists test.db-wal | 857 file exists test.db-wal |
855 } {0} | 858 } {0} |
856 | 859 |
857 do_test wal-13.2.1 { | 860 do_test wal-13.2.1 { |
858 sqlite3 db test.db | 861 sqlite3 db test.db |
859 execsql { SELECT count(*) FROM t2 } | 862 execsql { SELECT count(*) FROM t2 } |
860 } {1} | 863 } {1} |
861 do_test wal-13.2.2 { | 864 do_test wal-13.2.2 { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 # Check a fun corruption case has been fixed. | 905 # Check a fun corruption case has been fixed. |
903 # | 906 # |
904 # The problem was that after performing a checkpoint using a connection | 907 # The problem was that after performing a checkpoint using a connection |
905 # that had an out-of-date pager-cache, the next time the connection was | 908 # that had an out-of-date pager-cache, the next time the connection was |
906 # used it did not realize the cache was out-of-date and proceeded to | 909 # used it did not realize the cache was out-of-date and proceeded to |
907 # operate with an inconsistent cache. Leading to corruption. | 910 # operate with an inconsistent cache. Leading to corruption. |
908 # | 911 # |
909 catch { db close } | 912 catch { db close } |
910 catch { db2 close } | 913 catch { db2 close } |
911 catch { db3 close } | 914 catch { db3 close } |
912 file delete -force test.db test.db-wal | 915 forcedelete test.db test.db-wal |
913 sqlite3 db test.db | 916 sqlite3 db test.db |
914 sqlite3 db2 test.db | 917 sqlite3 db2 test.db |
915 do_test wal-14 { | 918 do_test wal-14 { |
916 execsql { | 919 execsql { |
917 PRAGMA journal_mode = WAL; | 920 PRAGMA journal_mode = WAL; |
918 CREATE TABLE t1(a PRIMARY KEY, b); | 921 CREATE TABLE t1(a PRIMARY KEY, b); |
919 INSERT INTO t1 VALUES(randomblob(10), randomblob(100)); | 922 INSERT INTO t1 VALUES(randomblob(10), randomblob(100)); |
920 INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1; | 923 INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1; |
921 INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1; | 924 INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1; |
922 INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1; | 925 INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1; |
(...skipping 17 matching lines...) Expand all Loading... |
940 db2 eval { PRAGMA integrity_check } | 943 db2 eval { PRAGMA integrity_check } |
941 } {ok} | 944 } {ok} |
942 | 945 |
943 catch { db close } | 946 catch { db close } |
944 catch { db2 close } | 947 catch { db2 close } |
945 | 948 |
946 #------------------------------------------------------------------------- | 949 #------------------------------------------------------------------------- |
947 # The following block of tests - wal-15.* - focus on testing the | 950 # The following block of tests - wal-15.* - focus on testing the |
948 # implementation of the sqlite3_wal_checkpoint() interface. | 951 # implementation of the sqlite3_wal_checkpoint() interface. |
949 # | 952 # |
950 file delete -force test.db test.db-wal | 953 forcedelete test.db test.db-wal |
951 sqlite3 db test.db | 954 sqlite3 db test.db |
952 do_test wal-15.1 { | 955 do_test wal-15.1 { |
953 execsql { | 956 execsql { |
954 PRAGMA auto_vacuum = 0; | 957 PRAGMA auto_vacuum = 0; |
955 PRAGMA page_size = 1024; | 958 PRAGMA page_size = 1024; |
956 PRAGMA journal_mode = WAL; | 959 PRAGMA journal_mode = WAL; |
957 } | 960 } |
958 execsql { | 961 execsql { |
959 CREATE TABLE t1(a, b); | 962 CREATE TABLE t1(a, b); |
960 INSERT INTO t1 VALUES(1, 2); | 963 INSERT INTO t1 VALUES(1, 2); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 # | 1035 # |
1033 foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { | 1036 foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { |
1034 1 {sqlite3_wal_checkpoint db} SQLITE_OK 1 1 | 1037 1 {sqlite3_wal_checkpoint db} SQLITE_OK 1 1 |
1035 2 {sqlite3_wal_checkpoint db ""} SQLITE_OK 1 1 | 1038 2 {sqlite3_wal_checkpoint db ""} SQLITE_OK 1 1 |
1036 3 {db eval "PRAGMA wal_checkpoint"} {0 10 10} 1 1 | 1039 3 {db eval "PRAGMA wal_checkpoint"} {0 10 10} 1 1 |
1037 | 1040 |
1038 4 {sqlite3_wal_checkpoint db main} SQLITE_OK 1 0 | 1041 4 {sqlite3_wal_checkpoint db main} SQLITE_OK 1 0 |
1039 5 {sqlite3_wal_checkpoint db aux} SQLITE_OK 0 1 | 1042 5 {sqlite3_wal_checkpoint db aux} SQLITE_OK 0 1 |
1040 6 {sqlite3_wal_checkpoint db temp} SQLITE_OK 0 0 | 1043 6 {sqlite3_wal_checkpoint db temp} SQLITE_OK 0 0 |
1041 7 {db eval "PRAGMA main.wal_checkpoint"} {0 10 10} 1 0 | 1044 7 {db eval "PRAGMA main.wal_checkpoint"} {0 10 10} 1 0 |
1042 8 {db eval "PRAGMA aux.wal_checkpoint"} {0 16 16} 0 1 | 1045 8 {db eval "PRAGMA aux.wal_checkpoint"} {0 13 13} 0 1 |
1043 9 {db eval "PRAGMA temp.wal_checkpoint"} {0 -1 -1} 0 0 | 1046 9 {db eval "PRAGMA temp.wal_checkpoint"} {0 -1 -1} 0 0 |
1044 } { | 1047 } { |
1045 do_test wal-16.$tn.1 { | 1048 do_test wal-16.$tn.1 { |
1046 file delete -force test2.db test2.db-wal test2.db-journal | 1049 forcedelete test2.db test2.db-wal test2.db-journal |
1047 file delete -force test.db test.db-wal test.db-journal | 1050 forcedelete test.db test.db-wal test.db-journal |
1048 | 1051 |
1049 sqlite3 db test.db | 1052 sqlite3 db test.db |
1050 execsql { | 1053 execsql { |
1051 ATTACH 'test2.db' AS aux; | 1054 ATTACH 'test2.db' AS aux; |
1052 PRAGMA main.auto_vacuum = 0; | 1055 PRAGMA main.auto_vacuum = 0; |
1053 PRAGMA aux.auto_vacuum = 0; | 1056 PRAGMA aux.auto_vacuum = 0; |
1054 PRAGMA main.journal_mode = WAL; | 1057 PRAGMA main.journal_mode = WAL; |
1055 PRAGMA aux.journal_mode = WAL; | 1058 PRAGMA aux.journal_mode = WAL; |
1056 PRAGMA synchronous = NORMAL; | 1059 PRAGMA main.synchronous = NORMAL; |
| 1060 PRAGMA aux.synchronous = NORMAL; |
1057 } | 1061 } |
1058 } {wal wal} | 1062 } {wal wal} |
1059 | 1063 |
1060 do_test wal-16.$tn.2 { | 1064 do_test wal-16.$tn.2 { |
1061 execsql { | 1065 execsql { |
1062 CREATE TABLE main.t1(a, b, PRIMARY KEY(a, b)); | 1066 CREATE TABLE main.t1(a, b, PRIMARY KEY(a, b)); |
1063 CREATE TABLE aux.t2(a, b, PRIMARY KEY(a, b)); | 1067 CREATE TABLE aux.t2(a, b, PRIMARY KEY(a, b)); |
1064 | 1068 |
1065 INSERT INTO t2 VALUES(1, randomblob(1000)); | 1069 INSERT INTO t2 VALUES(1, randomblob(1000)); |
1066 INSERT INTO t2 VALUES(2, randomblob(1000)); | 1070 INSERT INTO t2 VALUES(2, randomblob(1000)); |
1067 INSERT INTO t1 SELECT * FROM t2; | 1071 INSERT INTO t1 SELECT * FROM t2; |
1068 } | 1072 } |
1069 | 1073 |
1070 list [file size test.db] [file size test.db-wal] | 1074 list [file size test.db] [file size test.db-wal] |
1071 } [list [expr 1*1024] [wal_file_size 10 1024]] | 1075 } [list [expr 1*1024] [wal_file_size 10 1024]] |
1072 do_test wal-16.$tn.3 { | 1076 do_test wal-16.$tn.3 { |
1073 list [file size test2.db] [file size test2.db-wal] | 1077 list [file size test2.db] [file size test2.db-wal] |
1074 } [list [expr 1*1024] [wal_file_size 16 1024]] | 1078 } [list [expr 1*1024] [wal_file_size 13 1024]] |
1075 | 1079 |
1076 do_test wal-16.$tn.4 [list eval $ckpt_cmd] $ckpt_res | 1080 do_test wal-16.$tn.4 [list eval $ckpt_cmd] $ckpt_res |
1077 | 1081 |
1078 do_test wal-16.$tn.5 { | 1082 do_test wal-16.$tn.5 { |
1079 list [file size test.db] [file size test.db-wal] | 1083 list [file size test.db] [file size test.db-wal] |
1080 } [list [expr ($ckpt_main ? 7 : 1)*1024] [wal_file_size 10 1024]] | 1084 } [list [expr ($ckpt_main ? 7 : 1)*1024] [wal_file_size 10 1024]] |
1081 | 1085 |
1082 do_test wal-16.$tn.6 { | 1086 do_test wal-16.$tn.6 { |
1083 list [file size test2.db] [file size test2.db-wal] | 1087 list [file size test2.db] [file size test2.db-wal] |
1084 } [list [expr ($ckpt_aux ? 7 : 1)*1024] [wal_file_size 16 1024]] | 1088 } [list [expr ($ckpt_aux ? 7 : 1)*1024] [wal_file_size 13 1024]] |
1085 | 1089 |
1086 catch { db close } | 1090 catch { db close } |
1087 } | 1091 } |
1088 | 1092 |
1089 #------------------------------------------------------------------------- | 1093 #------------------------------------------------------------------------- |
1090 # The following tests - wal-17.* - attempt to verify that the correct | 1094 # The following tests - wal-17.* - attempt to verify that the correct |
1091 # number of "padding" frames are appended to the log file when a transaction | 1095 # number of "padding" frames are appended to the log file when a transaction |
1092 # is committed in synchronous=FULL mode. | 1096 # is committed in synchronous=FULL mode. |
1093 # | 1097 # |
1094 # Do this by creating a database that uses 512 byte pages. Then writing | 1098 # Do this by creating a database that uses 512 byte pages. Then writing |
(...skipping 14 matching lines...) Expand all Loading... |
1109 catch { db close } | 1113 catch { db close } |
1110 foreach {tn sectorsize logsize} " | 1114 foreach {tn sectorsize logsize} " |
1111 1 128 [wal_file_size 172 512] | 1115 1 128 [wal_file_size 172 512] |
1112 2 256 [wal_file_size 172 512] | 1116 2 256 [wal_file_size 172 512] |
1113 3 512 [wal_file_size 172 512] | 1117 3 512 [wal_file_size 172 512] |
1114 4 1024 [wal_file_size 172 512] | 1118 4 1024 [wal_file_size 172 512] |
1115 5 2048 [wal_file_size 172 512] | 1119 5 2048 [wal_file_size 172 512] |
1116 6 4096 [wal_file_size 176 512] | 1120 6 4096 [wal_file_size 176 512] |
1117 7 8192 [wal_file_size 184 512] | 1121 7 8192 [wal_file_size 184 512] |
1118 " { | 1122 " { |
1119 file delete -force test.db test.db-wal test.db-journal | 1123 forcedelete test.db test.db-wal test.db-journal |
1120 sqlite3_simulate_device -sectorsize $sectorsize | 1124 sqlite3_simulate_device -sectorsize $sectorsize |
1121 sqlite3 db test.db -vfs devsym | 1125 sqlite3 db test.db -vfs devsym |
1122 | 1126 |
1123 do_test wal-17.$tn.1 { | 1127 do_test wal-17.$tn.1 { |
1124 execsql { | 1128 execsql { |
1125 PRAGMA auto_vacuum = 0; | 1129 PRAGMA auto_vacuum = 0; |
1126 PRAGMA page_size = 512; | 1130 PRAGMA page_size = 512; |
| 1131 PRAGMA cache_size = -2000; |
1127 PRAGMA journal_mode = WAL; | 1132 PRAGMA journal_mode = WAL; |
1128 PRAGMA synchronous = FULL; | 1133 PRAGMA synchronous = FULL; |
1129 } | 1134 } |
1130 execsql { | 1135 execsql { |
1131 BEGIN; | 1136 BEGIN; |
1132 CREATE TABLE t(x); | 1137 CREATE TABLE t(x); |
1133 } | 1138 } |
1134 for {set i 0} {$i<166} {incr i} { | 1139 for {set i 0} {$i<166} {incr i} { |
1135 execsql { INSERT INTO t VALUES(randomblob(400)) } | 1140 execsql { INSERT INTO t VALUES(randomblob(400)) } |
1136 } | 1141 } |
(...skipping 16 matching lines...) Expand all Loading... |
1153 #------------------------------------------------------------------------- | 1158 #------------------------------------------------------------------------- |
1154 # This test - wal-18.* - verifies a couple of specific conditions that | 1159 # This test - wal-18.* - verifies a couple of specific conditions that |
1155 # may be encountered while recovering a log file are handled correctly: | 1160 # may be encountered while recovering a log file are handled correctly: |
1156 # | 1161 # |
1157 # wal-18.1.* When the first 32-bits of a frame checksum is correct but | 1162 # wal-18.1.* When the first 32-bits of a frame checksum is correct but |
1158 # the second 32-bits are false, and | 1163 # the second 32-bits are false, and |
1159 # | 1164 # |
1160 # wal-18.2.* When the page-size field that occurs at the start of a log | 1165 # wal-18.2.* When the page-size field that occurs at the start of a log |
1161 # file is a power of 2 greater than 16384 or smaller than 512. | 1166 # file is a power of 2 greater than 16384 or smaller than 512. |
1162 # | 1167 # |
1163 file delete -force test.db test.db-wal test.db-journal | 1168 forcedelete test.db test.db-wal test.db-journal |
1164 do_test wal-18.0 { | 1169 do_test wal-18.0 { |
1165 sqlite3 db test.db | 1170 sqlite3 db test.db |
1166 execsql { | 1171 execsql { |
1167 PRAGMA page_size = 1024; | 1172 PRAGMA page_size = 1024; |
1168 PRAGMA auto_vacuum = 0; | 1173 PRAGMA auto_vacuum = 0; |
1169 PRAGMA journal_mode = WAL; | 1174 PRAGMA journal_mode = WAL; |
1170 PRAGMA synchronous = OFF; | 1175 PRAGMA synchronous = OFF; |
1171 | 1176 |
1172 CREATE TABLE t1(a, b, UNIQUE(a, b)); | 1177 CREATE TABLE t1(a, b, UNIQUE(a, b)); |
1173 INSERT INTO t1 VALUES(0, 0); | 1178 INSERT INTO t1 VALUES(0, 0); |
1174 PRAGMA wal_checkpoint; | 1179 PRAGMA wal_checkpoint; |
1175 | 1180 |
1176 INSERT INTO t1 VALUES(1, 2); -- frames 1 and 2 | 1181 INSERT INTO t1 VALUES(1, 2); -- frames 1 and 2 |
1177 INSERT INTO t1 VALUES(3, 4); -- frames 3 and 4 | 1182 INSERT INTO t1 VALUES(3, 4); -- frames 3 and 4 |
1178 INSERT INTO t1 VALUES(5, 6); -- frames 5 and 6 | 1183 INSERT INTO t1 VALUES(5, 6); -- frames 5 and 6 |
1179 } | 1184 } |
1180 | 1185 |
1181 file copy -force test.db testX.db | 1186 forcecopy test.db testX.db |
1182 file copy -force test.db-wal testX.db-wal | 1187 forcecopy test.db-wal testX.db-wal |
1183 db close | 1188 db close |
1184 list [file size testX.db] [file size testX.db-wal] | 1189 list [file size testX.db] [file size testX.db-wal] |
1185 } [list [expr 3*1024] [wal_file_size 6 1024]] | 1190 } [list [expr 3*1024] [wal_file_size 6 1024]] |
1186 | 1191 |
1187 unset -nocomplain nFrame result | 1192 unset -nocomplain nFrame result |
1188 foreach {nFrame result} { | 1193 foreach {nFrame result} { |
1189 0 {0 0} | 1194 0 {0 0} |
1190 1 {0 0} | 1195 1 {0 0} |
1191 2 {0 0 1 2} | 1196 2 {0 0 1 2} |
1192 3 {0 0 1 2} | 1197 3 {0 0 1 2} |
1193 4 {0 0 1 2 3 4} | 1198 4 {0 0 1 2 3 4} |
1194 5 {0 0 1 2 3 4} | 1199 5 {0 0 1 2 3 4} |
1195 6 {0 0 1 2 3 4 5 6} | 1200 6 {0 0 1 2 3 4 5 6} |
1196 } { | 1201 } { |
1197 do_test wal-18.1.$nFrame { | 1202 do_test wal-18.1.$nFrame { |
1198 file copy -force testX.db test.db | 1203 forcecopy testX.db test.db |
1199 file copy -force testX.db-wal test.db-wal | 1204 forcecopy testX.db-wal test.db-wal |
1200 | 1205 |
1201 hexio_write test.db-wal [expr 24 + $nFrame*(24+1024) + 20] 00000000 | 1206 hexio_write test.db-wal [expr 24 + $nFrame*(24+1024) + 20] 00000000 |
1202 | 1207 |
1203 sqlite3 db test.db | 1208 sqlite3 db test.db |
1204 execsql { | 1209 execsql { |
1205 SELECT * FROM t1; | 1210 SELECT * FROM t1; |
1206 PRAGMA integrity_check; | 1211 PRAGMA integrity_check; |
1207 } | 1212 } |
1208 } [concat $result ok] | 1213 } [concat $result ok] |
1209 db close | 1214 db close |
1210 } | 1215 } |
1211 | 1216 |
1212 proc randomblob {pgsz} { | 1217 proc randomblob {pgsz} { |
1213 sqlite3 rbdb :memory: | 1218 sqlite3 rbdb :memory: |
1214 set blob [rbdb one {SELECT randomblob($pgsz)}] | 1219 set blob [rbdb one {SELECT randomblob($pgsz)}] |
1215 rbdb close | 1220 rbdb close |
1216 set blob | 1221 set blob |
1217 } | 1222 } |
1218 | 1223 |
1219 proc logcksum {ckv1 ckv2 blob} { | 1224 proc logcksum {ckv1 ckv2 blob} { |
1220 upvar $ckv1 c1 | 1225 upvar $ckv1 c1 |
1221 upvar $ckv2 c2 | 1226 upvar $ckv2 c2 |
1222 | 1227 |
1223 set scanpattern I* | 1228 # Since the magic number at the start of the -wal file header is |
1224 if {$::tcl_platform(byteOrder) eq "littleEndian"} { | 1229 # 931071618 that indicates that the content should always be read as |
1225 set scanpattern i* | 1230 # little-endian. |
1226 } | 1231 # |
| 1232 set scanpattern i* |
1227 | 1233 |
1228 binary scan $blob $scanpattern values | 1234 binary scan $blob $scanpattern values |
1229 foreach {v1 v2} $values { | 1235 foreach {v1 v2} $values { |
1230 set c1 [expr {($c1 + $v1 + $c2)&0xFFFFFFFF}] | 1236 set c1 [expr {($c1 + $v1 + $c2)&0xFFFFFFFF}] |
1231 set c2 [expr {($c2 + $v2 + $c1)&0xFFFFFFFF}] | 1237 set c2 [expr {($c2 + $v2 + $c1)&0xFFFFFFFF}] |
1232 } | 1238 } |
1233 } | 1239 } |
1234 | 1240 |
1235 file copy -force test.db testX.db | 1241 forcecopy test.db testX.db |
1236 foreach {tn pgsz works} { | 1242 foreach {tn pgsz works} { |
1237 1 128 0 | 1243 1 128 0 |
1238 2 256 0 | 1244 2 256 0 |
1239 3 512 1 | 1245 3 512 1 |
1240 4 1024 1 | 1246 4 1024 1 |
1241 5 2048 1 | 1247 5 2048 1 |
1242 6 4096 1 | 1248 6 4096 1 |
1243 7 8192 1 | 1249 7 8192 1 |
1244 8 16384 1 | 1250 8 16384 1 |
1245 9 32768 1 | 1251 9 32768 1 |
1246 10 65536 1 | 1252 10 65536 1 |
1247 11 131072 0 | 1253 11 131072 0 |
1248 11 1016 0 | 1254 11 1016 0 |
1249 } { | 1255 } { |
1250 | 1256 |
1251 if {$::SQLITE_MAX_PAGE_SIZE < $pgsz} { | 1257 if {$::SQLITE_MAX_PAGE_SIZE < $pgsz} { |
1252 set works 0 | 1258 set works 0 |
1253 } | 1259 } |
1254 | 1260 |
1255 for {set pg 1} {$pg <= 3} {incr pg} { | 1261 for {set pg 1} {$pg <= 3} {incr pg} { |
1256 file copy -force testX.db test.db | 1262 forcecopy testX.db test.db |
1257 file delete -force test.db-wal | 1263 forcedelete test.db-wal |
1258 | 1264 |
1259 # Check that the database now exists and consists of three pages. And | 1265 # Check that the database now exists and consists of three pages. And |
1260 # that there is no associated wal file. | 1266 # that there is no associated wal file. |
1261 # | 1267 # |
1262 do_test wal-18.2.$tn.$pg.1 { file exists test.db-wal } 0 | 1268 do_test wal-18.2.$tn.$pg.1 { file exists test.db-wal } 0 |
1263 do_test wal-18.2.$tn.$pg.2 { file exists test.db } 1 | 1269 do_test wal-18.2.$tn.$pg.2 { file exists test.db } 1 |
1264 do_test wal-18.2.$tn.$pg.3 { file size test.db } [expr 1024*3] | 1270 do_test wal-18.2.$tn.$pg.3 { file size test.db } [expr 1024*3] |
1265 | 1271 |
1266 do_test wal-18.2.$tn.$pg.4 { | 1272 do_test wal-18.2.$tn.$pg.4 { |
1267 | 1273 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1314 # | 1320 # |
1315 # When a database connection in WAL mode is closed, it attempts an | 1321 # When a database connection in WAL mode is closed, it attempts an |
1316 # EXCLUSIVE lock on the database file. If the lock is obtained, the | 1322 # EXCLUSIVE lock on the database file. If the lock is obtained, the |
1317 # connection knows that it is the last connection to disconnect from | 1323 # connection knows that it is the last connection to disconnect from |
1318 # the database, so it runs a checkpoint operation. The bug was that | 1324 # the database, so it runs a checkpoint operation. The bug was that |
1319 # the connection was not updating its private copy of the wal-index | 1325 # the connection was not updating its private copy of the wal-index |
1320 # header before doing so, meaning that it could checkpoint an old | 1326 # header before doing so, meaning that it could checkpoint an old |
1321 # snapshot. | 1327 # snapshot. |
1322 # | 1328 # |
1323 do_test wal-19.1 { | 1329 do_test wal-19.1 { |
1324 file delete -force test.db test.db-wal test.db-journal | 1330 forcedelete test.db test.db-wal test.db-journal |
1325 sqlite3 db test.db | 1331 sqlite3 db test.db |
1326 sqlite3 db2 test.db | 1332 sqlite3 db2 test.db |
1327 execsql { | 1333 execsql { |
1328 PRAGMA journal_mode = WAL; | 1334 PRAGMA journal_mode = WAL; |
1329 CREATE TABLE t1(a, b); | 1335 CREATE TABLE t1(a, b); |
1330 INSERT INTO t1 VALUES(1, 2); | 1336 INSERT INTO t1 VALUES(1, 2); |
1331 INSERT INTO t1 VALUES(3, 4); | 1337 INSERT INTO t1 VALUES(3, 4); |
1332 } | 1338 } |
1333 execsql { SELECT * FROM t1 } db2 | 1339 execsql { SELECT * FROM t1 } db2 |
1334 } {1 2 3 4} | 1340 } {1 2 3 4} |
(...skipping 28 matching lines...) Expand all Loading... |
1363 # larger than 64KB is required. | 1369 # larger than 64KB is required. |
1364 # | 1370 # |
1365 # 3. Using connection 1, checkpoint the database. Make sure all | 1371 # 3. Using connection 1, checkpoint the database. Make sure all |
1366 # the data is present and the database is not corrupt. | 1372 # the data is present and the database is not corrupt. |
1367 # | 1373 # |
1368 # At one point, SQLite was failing to grow the mapping of the wal-index | 1374 # At one point, SQLite was failing to grow the mapping of the wal-index |
1369 # file in step 3 and the checkpoint was corrupting the database file. | 1375 # file in step 3 and the checkpoint was corrupting the database file. |
1370 # | 1376 # |
1371 do_test wal-20.1 { | 1377 do_test wal-20.1 { |
1372 catch {db close} | 1378 catch {db close} |
1373 file delete -force test.db test.db-wal test.db-journal | 1379 forcedelete test.db test.db-wal test.db-journal |
1374 sqlite3 db test.db | 1380 sqlite3 db test.db |
1375 execsql { | 1381 execsql { |
1376 PRAGMA journal_mode = WAL; | 1382 PRAGMA journal_mode = WAL; |
1377 CREATE TABLE t1(x); | 1383 CREATE TABLE t1(x); |
1378 INSERT INTO t1 VALUES(randomblob(900)); | 1384 INSERT INTO t1 VALUES(randomblob(900)); |
1379 SELECT count(*) FROM t1; | 1385 SELECT count(*) FROM t1; |
1380 } | 1386 } |
1381 } {wal 1} | 1387 } {wal 1} |
1382 do_test wal-20.2 { | 1388 do_test wal-20.2 { |
1383 set ::buddy [launch_testfixture] | 1389 set ::buddy [launch_testfixture] |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 sql1 {PRAGMA wal_checkpoint} | 1473 sql1 {PRAGMA wal_checkpoint} |
1468 expr {[file size test.db] % %PGSZ%} | 1474 expr {[file size test.db] % %PGSZ%} |
1469 } {0} | 1475 } {0} |
1470 }] | 1476 }] |
1471 } | 1477 } |
1472 | 1478 |
1473 #------------------------------------------------------------------------- | 1479 #------------------------------------------------------------------------- |
1474 # Test that when 1 or more pages are recovered from a WAL file, | 1480 # Test that when 1 or more pages are recovered from a WAL file, |
1475 # sqlite3_log() is invoked to report this to the user. | 1481 # sqlite3_log() is invoked to report this to the user. |
1476 # | 1482 # |
1477 set walfile [file nativename [file join [pwd] test.db-wal]] | 1483 ifcapable curdir { |
| 1484 set walfile [file nativename [file join [get_pwd] test.db-wal]] |
| 1485 } else { |
| 1486 set walfile test.db-wal |
| 1487 } |
1478 catch {db close} | 1488 catch {db close} |
1479 file delete -force test.db | 1489 forcedelete test.db |
1480 do_test wal-23.1 { | 1490 do_test wal-23.1 { |
1481 faultsim_delete_and_reopen | 1491 faultsim_delete_and_reopen |
1482 execsql { | 1492 execsql { |
1483 CREATE TABLE t1(a, b); | 1493 CREATE TABLE t1(a, b); |
1484 PRAGMA journal_mode = WAL; | 1494 PRAGMA journal_mode = WAL; |
1485 INSERT INTO t1 VALUES(1, 2); | 1495 INSERT INTO t1 VALUES(1, 2); |
1486 INSERT INTO t1 VALUES(3, 4); | 1496 INSERT INTO t1 VALUES(3, 4); |
1487 } | 1497 } |
1488 faultsim_save_and_close | 1498 faultsim_save_and_close |
1489 | 1499 |
1490 sqlite3_shutdown | 1500 sqlite3_shutdown |
1491 test_sqlite3_log [list lappend ::log] | 1501 test_sqlite3_log [list lappend ::log] |
1492 set ::log [list] | 1502 set ::log [list] |
1493 sqlite3 db test.db | 1503 sqlite3 db test.db |
1494 execsql { SELECT * FROM t1 } | 1504 execsql { SELECT * FROM t1 } |
1495 } {1 2 3 4} | 1505 } {1 2 3 4} |
1496 do_test wal-23.2 { set ::log } {} | 1506 do_test wal-23.2 { set ::log } {} |
1497 | 1507 |
1498 do_test wal-23.3 { | 1508 do_test wal-23.3 { |
1499 db close | 1509 db close |
1500 set ::log [list] | 1510 set ::log [list] |
1501 faultsim_restore_and_reopen | 1511 faultsim_restore_and_reopen |
1502 execsql { SELECT * FROM t1 } | 1512 execsql { SELECT * FROM t1 } |
1503 } {1 2 3 4} | 1513 } {1 2 3 4} |
1504 set nPage [expr 2+$AUTOVACUUM] | |
1505 do_test wal-23.4 { | 1514 do_test wal-23.4 { |
1506 set ::log | 1515 set ::log |
1507 } [list SQLITE_OK "Recovered $nPage frames from WAL file $walfile"] | 1516 } [list SQLITE_NOTICE_RECOVER_WAL \ |
| 1517 "recovered 2 frames from WAL file $walfile"] |
1508 | 1518 |
1509 | 1519 |
1510 ifcapable autovacuum { | 1520 ifcapable autovacuum { |
1511 # This block tests that if the size of a database is reduced by a | 1521 # This block tests that if the size of a database is reduced by a |
1512 # transaction (because of an incremental or auto-vacuum), that no | 1522 # transaction (because of an incremental or auto-vacuum), that no |
1513 # data is written to the WAL file for the truncated pages as part | 1523 # data is written to the WAL file for the truncated pages as part |
1514 # of the commit. e.g. if a transaction reduces the size of a database | 1524 # of the commit. e.g. if a transaction reduces the size of a database |
1515 # to N pages, data for page N+1 should not be written to the WAL file | 1525 # to N pages, data for page N+1 should not be written to the WAL file |
1516 # when committing the transaction. At one point such data was being | 1526 # when committing the transaction. At one point such data was being |
1517 # written. | 1527 # written. |
(...skipping 25 matching lines...) Expand all Loading... |
1543 file size test.db | 1553 file size test.db |
1544 } [expr 84 * 1024] | 1554 } [expr 84 * 1024] |
1545 do_test 24.4 { | 1555 do_test 24.4 { |
1546 execsql { | 1556 execsql { |
1547 PRAGMA cache_size = 200; | 1557 PRAGMA cache_size = 200; |
1548 PRAGMA incremental_vacuum; | 1558 PRAGMA incremental_vacuum; |
1549 PRAGMA wal_checkpoint; | 1559 PRAGMA wal_checkpoint; |
1550 } | 1560 } |
1551 file size test.db | 1561 file size test.db |
1552 } [expr 3 * 1024] | 1562 } [expr 3 * 1024] |
| 1563 |
| 1564 # WAL file now contains a single frame - the new root page for table t1. |
| 1565 # It would be two frames (the new root page and a padding frame) if the |
| 1566 # ZERO_DAMAGE flag were not set. |
1553 do_test 24.5 { | 1567 do_test 24.5 { |
1554 file size test.db-wal | 1568 file size test.db-wal |
1555 } 2128 | 1569 } [wal_file_size 1 1024] |
1556 } | 1570 } |
1557 | 1571 |
1558 db close | 1572 db close |
1559 sqlite3_shutdown | 1573 sqlite3_shutdown |
1560 test_sqlite3_log | 1574 test_sqlite3_log |
1561 sqlite3_initialize | 1575 sqlite3_initialize |
1562 | 1576 |
| 1577 # Make sure PRAGMA journal_mode=WAL works with ATTACHED databases in |
| 1578 # all journal modes. |
| 1579 # |
| 1580 foreach mode {OFF MEMORY PERSIST DELETE TRUNCATE WAL} { |
| 1581 delete_file test.db test2.db |
| 1582 sqlite3 db test.db |
| 1583 do_test wal-25.$mode { |
| 1584 db eval "PRAGMA journal_mode=$mode" |
| 1585 db eval {ATTACH 'test2.db' AS t2; PRAGMA journal_mode=WAL;} |
| 1586 } {wal} |
| 1587 db close |
| 1588 } |
| 1589 |
1563 finish_test | 1590 finish_test |
OLD | NEW |