OLD | NEW |
1 # 2010 June 15 | 1 # 2010 June 15 |
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 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 | 522 |
523 # Set up a VFS that snapshots the file-system just before a master journal | 523 # Set up a VFS that snapshots the file-system just before a master journal |
524 # file is deleted to commit a multi-file transaction. Specifically, the | 524 # file is deleted to commit a multi-file transaction. Specifically, the |
525 # file-system is saved just before the xDelete() call to remove the | 525 # file-system is saved just before the xDelete() call to remove the |
526 # master journal file from the file-system. | 526 # master journal file from the file-system. |
527 # | 527 # |
528 set pwd [get_pwd] | 528 set pwd [get_pwd] |
529 testvfs tv -default 1 | 529 testvfs tv -default 1 |
530 tv script copy_on_mj_delete | 530 tv script copy_on_mj_delete |
531 set ::mj_filename_length 0 | 531 set ::mj_filename_length 0 |
| 532 set ::mj_delete_cnt 0 |
532 proc copy_on_mj_delete {method filename args} { | 533 proc copy_on_mj_delete {method filename args} { |
533 if {[string match *mj* [file tail $filename]]} { | 534 if {[string match *mj* [file tail $filename]]} { |
534 # | 535 # |
535 # NOTE: Is the file name relative? If so, add the length of the current | 536 # NOTE: Is the file name relative? If so, add the length of the current |
536 # directory. | 537 # directory. |
537 # | 538 # |
538 if {[is_relative_file $filename]} { | 539 if {[is_relative_file $filename]} { |
539 set ::mj_filename_length \ | 540 set ::mj_filename_length \ |
540 [expr {[string length $filename] + [string length $::pwd]}] | 541 [expr {[string length $filename] + [string length $::pwd]}] |
541 } else { | 542 } else { |
542 set ::mj_filename_length [string length $filename] | 543 set ::mj_filename_length [string length $filename] |
543 } | 544 } |
544 faultsim_save | 545 faultsim_save |
| 546 incr ::mj_delete_cnt |
545 } | 547 } |
546 return SQLITE_OK | 548 return SQLITE_OK |
547 } | 549 } |
548 | 550 |
549 foreach {tn1 tcl} { | 551 foreach {tn1 tcl} { |
550 1 { set prefix "test.db" } | 552 1 { set prefix "test.db" } |
551 2 { | 553 2 { |
552 # This test depends on the underlying VFS being able to open paths | 554 # This test depends on the underlying VFS being able to open paths |
553 # 512 bytes in length. The idea is to create a hot-journal file that | 555 # 512 bytes in length. The idea is to create a hot-journal file that |
554 # contains a master-journal pointer so large that it could contain | 556 # contains a master-journal pointer so large that it could contain |
(...skipping 17 matching lines...) Expand all Loading... |
572 set p [string repeat $dirname $nDir] | 574 set p [string repeat $dirname $nDir] |
573 file mkdir $p | 575 file mkdir $p |
574 cd $p | 576 cd $p |
575 } | 577 } |
576 | 578 |
577 set padding [string repeat x [expr $nPadding %32]] | 579 set padding [string repeat x [expr $nPadding %32]] |
578 set prefix "test.db${padding}" | 580 set prefix "test.db${padding}" |
579 } | 581 } |
580 } { | 582 } { |
581 eval $tcl | 583 eval $tcl |
582 foreach {tn2 sql} { | 584 foreach {tn2 sql usesMJ} { |
583 o { | 585 o { |
584 PRAGMA main.synchronous=OFF; | 586 PRAGMA main.synchronous=OFF; |
585 PRAGMA aux.synchronous=OFF; | 587 PRAGMA aux.synchronous=OFF; |
586 PRAGMA journal_mode = DELETE; | 588 PRAGMA journal_mode = DELETE; |
587 } | 589 } 0 |
588 o512 { | 590 o512 { |
589 PRAGMA main.synchronous=OFF; | 591 PRAGMA main.synchronous=OFF; |
590 PRAGMA aux.synchronous=OFF; | 592 PRAGMA aux.synchronous=OFF; |
591 PRAGMA main.page_size = 512; | 593 PRAGMA main.page_size = 512; |
592 PRAGMA aux.page_size = 512; | 594 PRAGMA aux.page_size = 512; |
593 PRAGMA journal_mode = DELETE; | 595 PRAGMA journal_mode = DELETE; |
594 } | 596 } 0 |
595 n { | 597 n { |
596 PRAGMA main.synchronous=NORMAL; | 598 PRAGMA main.synchronous=NORMAL; |
597 PRAGMA aux.synchronous=NORMAL; | 599 PRAGMA aux.synchronous=NORMAL; |
598 PRAGMA journal_mode = DELETE; | 600 PRAGMA journal_mode = DELETE; |
599 } | 601 } 1 |
600 f { | 602 f { |
601 PRAGMA main.synchronous=FULL; | 603 PRAGMA main.synchronous=FULL; |
602 PRAGMA aux.synchronous=FULL; | 604 PRAGMA aux.synchronous=FULL; |
603 PRAGMA journal_mode = DELETE; | 605 PRAGMA journal_mode = DELETE; |
604 } | 606 } 1 |
| 607 w1 { |
| 608 PRAGMA main.synchronous=NORMAL; |
| 609 PRAGMA aux.synchronous=NORMAL; |
| 610 PRAGMA journal_mode = WAL; |
| 611 } 0 |
| 612 w2 { |
| 613 PRAGMA main.synchronous=NORMAL; |
| 614 PRAGMA aux.synchronous=NORMAL; |
| 615 PRAGMA main.journal_mode=DELETE; |
| 616 PRAGMA aux.journal_mode=WAL; |
| 617 } 0 |
| 618 o1a { |
| 619 PRAGMA main.synchronous=FULL; |
| 620 PRAGMA aux.synchronous=OFF; |
| 621 PRAGMA journal_mode=DELETE; |
| 622 } 0 |
| 623 o1b { |
| 624 PRAGMA main.synchronous=OFF; |
| 625 PRAGMA aux.synchronous=NORMAL; |
| 626 PRAGMA journal_mode=DELETE; |
| 627 } 0 |
| 628 m1 { |
| 629 PRAGMA main.synchronous=NORMAL; |
| 630 PRAGMA aux.synchronous=NORMAL; |
| 631 PRAGMA main.journal_mode=DELETE; |
| 632 PRAGMA aux.journal_mode = MEMORY; |
| 633 } 0 |
| 634 t1 { |
| 635 PRAGMA main.synchronous=NORMAL; |
| 636 PRAGMA aux.synchronous=NORMAL; |
| 637 PRAGMA main.journal_mode=DELETE; |
| 638 PRAGMA aux.journal_mode = TRUNCATE; |
| 639 } 1 |
| 640 p1 { |
| 641 PRAGMA main.synchronous=NORMAL; |
| 642 PRAGMA aux.synchronous=NORMAL; |
| 643 PRAGMA main.journal_mode=DELETE; |
| 644 PRAGMA aux.journal_mode = PERSIST; |
| 645 } 1 |
605 } { | 646 } { |
606 | 647 |
607 set tn "${tn1}.${tn2}" | 648 set tn "${tn1}.${tn2}" |
608 | 649 |
609 # Set up a connection to have two databases, test.db (main) and | 650 # Set up a connection to have two databases, test.db (main) and |
610 # test.db2 (aux). Then run a multi-file transaction on them. The | 651 # test.db2 (aux). Then run a multi-file transaction on them. The |
611 # VFS will snapshot the file-system just before the master-journal | 652 # VFS will snapshot the file-system just before the master-journal |
612 # file is deleted to commit the transaction. | 653 # file is deleted to commit the transaction. |
613 # | 654 # |
614 tv filter xDelete | 655 tv filter xDelete |
615 do_test pager1-4.4.$tn.1 { | 656 do_test pager1-4.4.$tn.1 { |
| 657 set ::mj_delete_cnt 0 |
616 faultsim_delete_and_reopen $prefix | 658 faultsim_delete_and_reopen $prefix |
617 execsql " | 659 execsql " |
618 ATTACH '${prefix}2' AS aux; | 660 ATTACH '${prefix}2' AS aux; |
619 $sql | 661 $sql |
620 CREATE TABLE a(x); | 662 CREATE TABLE a(x); |
621 CREATE TABLE aux.b(x); | 663 CREATE TABLE aux.b(x); |
622 INSERT INTO a VALUES('double-you'); | 664 INSERT INTO a VALUES('double-you'); |
623 INSERT INTO a VALUES('why'); | 665 INSERT INTO a VALUES('why'); |
624 INSERT INTO a VALUES('zed'); | 666 INSERT INTO a VALUES('zed'); |
625 INSERT INTO b VALUES('won'); | 667 INSERT INTO b VALUES('won'); |
626 INSERT INTO b VALUES('too'); | 668 INSERT INTO b VALUES('too'); |
627 INSERT INTO b VALUES('free'); | 669 INSERT INTO b VALUES('free'); |
628 " | 670 " |
629 execsql { | 671 execsql { |
630 BEGIN; | 672 BEGIN; |
631 INSERT INTO a SELECT * FROM b WHERE rowid<=3; | 673 INSERT INTO a SELECT * FROM b WHERE rowid<=3; |
632 INSERT INTO b SELECT * FROM a WHERE rowid<=3; | 674 INSERT INTO b SELECT * FROM a WHERE rowid<=3; |
633 COMMIT; | 675 COMMIT; |
634 } | 676 } |
635 } {} | 677 } {} |
636 tv filter {} | 678 tv filter {} |
| 679 |
| 680 # Verify that a master journal was deleted only for those cases where |
| 681 # master journals really ought to be used |
| 682 # |
| 683 do_test pager1-4.4.$tn.1b { |
| 684 set ::mj_delete_cnt |
| 685 } $usesMJ |
637 | 686 |
638 # Check that the transaction was committed successfully. | 687 # Check that the transaction was committed successfully. |
639 # | 688 # |
640 do_execsql_test pager1-4.4.$tn.2 { | 689 do_execsql_test pager1-4.4.$tn.2 { |
641 SELECT * FROM a | 690 SELECT * FROM a |
642 } {double-you why zed won too free} | 691 } {double-you why zed won too free} |
643 do_execsql_test pager1-4.4.$tn.3 { | 692 do_execsql_test pager1-4.4.$tn.3 { |
644 SELECT * FROM b | 693 SELECT * FROM b |
645 } {won too free double-you why zed} | 694 } {won too free double-you why zed} |
646 | 695 |
647 # Restore the file-system and reopen the databases. Check that it now | 696 if {$usesMJ} { |
648 # appears that the transaction was not committed (because the file-system | 697 # Restore the file-system and reopen the databases. Check that it now |
649 # was restored to the state where it had not been). | 698 # appears that the transaction was not committed (because the file-system |
650 # | 699 # was restored to the state where it had not been). |
651 do_test pager1-4.4.$tn.4 { | 700 # |
652 faultsim_restore_and_reopen $prefix | 701 do_test pager1-4.4.$tn.4 { |
653 execsql "ATTACH '${prefix}2' AS aux" | 702 faultsim_restore_and_reopen $prefix |
654 } {} | 703 execsql "ATTACH '${prefix}2' AS aux" |
655 do_execsql_test pager1-4.4.$tn.5 {SELECT * FROM a} {double-you why zed} | 704 } {} |
656 do_execsql_test pager1-4.4.$tn.6 {SELECT * FROM b} {won too free} | 705 do_execsql_test pager1-4.4.$tn.5 {SELECT * FROM a} {double-you why zed} |
| 706 do_execsql_test pager1-4.4.$tn.6 {SELECT * FROM b} {won too free} |
| 707 } |
657 | 708 |
658 # Restore the file-system again. This time, before reopening the databases, | 709 # Restore the file-system again. This time, before reopening the databases, |
659 # delete the master-journal file from the file-system. It now appears that | 710 # delete the master-journal file from the file-system. It now appears that |
660 # the transaction was committed (no master-journal file == no rollback). | 711 # the transaction was committed (no master-journal file == no rollback). |
661 # | 712 # |
662 do_test pager1-4.4.$tn.7 { | 713 do_test pager1-4.4.$tn.7 { |
663 faultsim_restore_and_reopen $prefix | 714 if {$::mj_delete_cnt>0} { |
664 foreach f [glob ${prefix}-mj*] { forcedelete $f } | 715 faultsim_restore_and_reopen $prefix |
| 716 foreach f [glob ${prefix}-mj*] { forcedelete $f } |
| 717 } else { |
| 718 db close |
| 719 sqlite3 db $prefix |
| 720 } |
665 execsql "ATTACH '${prefix}2' AS aux" | 721 execsql "ATTACH '${prefix}2' AS aux" |
| 722 glob -nocomplain ${prefix}-mj* |
666 } {} | 723 } {} |
667 do_execsql_test pager1-4.4.$tn.8 { | 724 do_execsql_test pager1-4.4.$tn.8 { |
668 SELECT * FROM a | 725 SELECT * FROM a |
669 } {double-you why zed won too free} | 726 } {double-you why zed won too free} |
670 do_execsql_test pager1-4.4.$tn.9 { | 727 do_execsql_test pager1-4.4.$tn.9 { |
671 SELECT * FROM b | 728 SELECT * FROM b |
672 } {won too free double-you why zed} | 729 } {won too free double-you why zed} |
673 } | 730 } |
674 | 731 |
675 cd $pwd | 732 cd $pwd |
676 } | 733 } |
677 db close | 734 db close |
678 tv delete | 735 tv delete |
679 forcedelete $dirname | 736 forcedelete $dirname |
680 | 737 |
681 | |
682 # Set up a VFS to make a copy of the file-system just before deleting a | 738 # Set up a VFS to make a copy of the file-system just before deleting a |
683 # journal file to commit a transaction. The transaction modifies exactly | 739 # journal file to commit a transaction. The transaction modifies exactly |
684 # two database pages (and page 1 - the change counter). | 740 # two database pages (and page 1 - the change counter). |
685 # | 741 # |
686 testvfs tv -default 1 | 742 testvfs tv -default 1 |
687 tv sectorsize 512 | 743 tv sectorsize 512 |
688 tv script copy_on_journal_delete | 744 tv script copy_on_journal_delete |
689 tv filter xDelete | 745 tv filter xDelete |
690 proc copy_on_journal_delete {method filename args} { | 746 proc copy_on_journal_delete {method filename args} { |
691 if {[string match *journal $filename]} faultsim_save | 747 if {[string match *journal $filename]} faultsim_save |
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1333 db2 close | 1389 db2 close |
1334 | 1390 |
1335 do_test pager1-9.3.1 { | 1391 do_test pager1-9.3.1 { |
1336 testvfs tv -default 1 | 1392 testvfs tv -default 1 |
1337 tv sectorsize 4096 | 1393 tv sectorsize 4096 |
1338 faultsim_delete_and_reopen | 1394 faultsim_delete_and_reopen |
1339 | 1395 |
1340 execsql { PRAGMA page_size = 1024 } | 1396 execsql { PRAGMA page_size = 1024 } |
1341 for {set ii 0} {$ii < 4} {incr ii} { execsql "CREATE TABLE t${ii}(a, b)" } | 1397 for {set ii 0} {$ii < 4} {incr ii} { execsql "CREATE TABLE t${ii}(a, b)" } |
1342 } {} | 1398 } {} |
1343 do_test pager1-9.3.2 { | 1399 if {[nonzero_reserved_bytes]} { |
1344 sqlite3 db2 test.db2 | 1400 # backup with a page size changes is not possible with the codec |
1345 | 1401 # |
1346 execsql { | 1402 do_test pager1-9.3.2codec { |
1347 PRAGMA page_size = 4096; | 1403 sqlite3 db2 test.db2 |
1348 PRAGMA synchronous = OFF; | 1404 execsql { |
1349 CREATE TABLE t1(a, b); | 1405 PRAGMA page_size = 4096; |
1350 CREATE TABLE t2(a, b); | 1406 PRAGMA synchronous = OFF; |
1351 } db2 | 1407 CREATE TABLE t1(a, b); |
1352 | 1408 CREATE TABLE t2(a, b); |
1353 sqlite3_backup B db2 main db main | 1409 } db2 |
1354 B step 30 | 1410 sqlite3_backup B db2 main db main |
1355 list [B step 10000] [B finish] | 1411 B step 30 |
1356 } {SQLITE_DONE SQLITE_OK} | 1412 list [B step 10000] [B finish] |
1357 do_test pager1-9.3.3 { | 1413 } {SQLITE_READONLY SQLITE_READONLY} |
1358 db2 close | 1414 do_test pager1-9.3.3codec { |
1359 db close | 1415 db2 close |
1360 tv delete | 1416 db close |
1361 file size test.db2 | 1417 tv delete |
1362 } [file size test.db] | 1418 file size test.db2 |
| 1419 } [file size test.db2] |
| 1420 } else { |
| 1421 do_test pager1-9.3.2 { |
| 1422 sqlite3 db2 test.db2 |
| 1423 execsql { |
| 1424 PRAGMA page_size = 4096; |
| 1425 PRAGMA synchronous = OFF; |
| 1426 CREATE TABLE t1(a, b); |
| 1427 CREATE TABLE t2(a, b); |
| 1428 } db2 |
| 1429 sqlite3_backup B db2 main db main |
| 1430 B step 30 |
| 1431 list [B step 10000] [B finish] |
| 1432 } {SQLITE_DONE SQLITE_OK} |
| 1433 do_test pager1-9.3.3 { |
| 1434 db2 close |
| 1435 db close |
| 1436 tv delete |
| 1437 file size test.db2 |
| 1438 } [file size test.db] |
| 1439 } |
1363 | 1440 |
1364 do_test pager1-9.4.1 { | 1441 do_test pager1-9.4.1 { |
1365 faultsim_delete_and_reopen | 1442 faultsim_delete_and_reopen |
1366 sqlite3 db2 test.db2 | 1443 sqlite3 db2 test.db2 |
1367 execsql { | 1444 execsql { |
1368 PRAGMA page_size = 4096; | 1445 PRAGMA page_size = 4096; |
1369 CREATE TABLE t1(a, b); | 1446 CREATE TABLE t1(a, b); |
1370 CREATE TABLE t2(a, b); | 1447 CREATE TABLE t2(a, b); |
1371 } db2 | 1448 } db2 |
1372 sqlite3_backup B db2 main db main | 1449 sqlite3_backup B db2 main db main |
(...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2384 faultsim_delete_and_reopen | 2461 faultsim_delete_and_reopen |
2385 execsql { | 2462 execsql { |
2386 PRAGMA page_size = 1024; | 2463 PRAGMA page_size = 1024; |
2387 PRAGMA auto_vacuum = full; | 2464 PRAGMA auto_vacuum = full; |
2388 PRAGMA locking_mode=exclusive; | 2465 PRAGMA locking_mode=exclusive; |
2389 CREATE TABLE t1(a, b); | 2466 CREATE TABLE t1(a, b); |
2390 INSERT INTO t1 VALUES(1, 2); | 2467 INSERT INTO t1 VALUES(1, 2); |
2391 } | 2468 } |
2392 file size test.db | 2469 file size test.db |
2393 } [expr 1024*3] | 2470 } [expr 1024*3] |
2394 do_test pager1-29.2 { | 2471 if {[nonzero_reserved_bytes]} { |
2395 execsql { | 2472 # VACUUM with size changes is not possible with the codec. |
2396 PRAGMA page_size = 4096; | 2473 do_test pager1-29.2 { |
2397 VACUUM; | 2474 catchsql { |
2398 } | 2475 PRAGMA page_size = 4096; |
2399 file size test.db | 2476 VACUUM; |
2400 } [expr 4096*3] | 2477 } |
| 2478 } {1 {attempt to write a readonly database}} |
| 2479 } else { |
| 2480 do_test pager1-29.2 { |
| 2481 execsql { |
| 2482 PRAGMA page_size = 4096; |
| 2483 VACUUM; |
| 2484 } |
| 2485 file size test.db |
| 2486 } [expr 4096*3] |
| 2487 } |
2401 | 2488 |
2402 #------------------------------------------------------------------------- | 2489 #------------------------------------------------------------------------- |
2403 # Test that if an empty database file (size 0 bytes) is opened in | 2490 # Test that if an empty database file (size 0 bytes) is opened in |
2404 # exclusive-locking mode, any journal file is deleted from the file-system | 2491 # exclusive-locking mode, any journal file is deleted from the file-system |
2405 # without being rolled back. And that the RESERVED lock obtained while | 2492 # without being rolled back. And that the RESERVED lock obtained while |
2406 # doing this is not released. | 2493 # doing this is not released. |
2407 # | 2494 # |
2408 do_test pager1-30.1 { | 2495 do_test pager1-30.1 { |
2409 db close | 2496 db close |
2410 delete_file test.db | 2497 delete_file test.db |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2808 db eval { SELECT * FROM t2 } | 2895 db eval { SELECT * FROM t2 } |
2809 sqlite3_db_status db CACHE_MISS 1 | 2896 sqlite3_db_status db CACHE_MISS 1 |
2810 } {0 3 0} | 2897 } {0 3 0} |
2811 | 2898 |
2812 do_test 43.3 { | 2899 do_test 43.3 { |
2813 db eval { SELECT * FROM t3 } | 2900 db eval { SELECT * FROM t3 } |
2814 sqlite3_db_status db CACHE_MISS 0 | 2901 sqlite3_db_status db CACHE_MISS 0 |
2815 } {0 1 0} | 2902 } {0 1 0} |
2816 | 2903 |
2817 finish_test | 2904 finish_test |
OLD | NEW |