1a58f26f9Sdan# 2010 April 13 2a58f26f9Sdan# 3a58f26f9Sdan# The author disclaims copyright to this source code. In place of 4a58f26f9Sdan# a legal notice, here is a blessing: 5a58f26f9Sdan# 6a58f26f9Sdan# May you do good and not evil. 7a58f26f9Sdan# May you find forgiveness for yourself and forgive others. 8a58f26f9Sdan# May you share freely, never taking more than you give. 9a58f26f9Sdan# 10a58f26f9Sdan#*********************************************************************** 11a58f26f9Sdan# This file implements regression tests for SQLite library. The 12a58f26f9Sdan# focus of this file is testing the operation of "blocking-checkpoint" 13a58f26f9Sdan# operations. 14a58f26f9Sdan# 15a58f26f9Sdan 16a58f26f9Sdanset testdir [file dirname $argv0] 17a58f26f9Sdansource $testdir/tester.tcl 18a58f26f9Sdansource $testdir/lock_common.tcl 19a58f26f9Sdansource $testdir/wal_common.tcl 20a58f26f9Sdanifcapable !wal {finish_test ; return } 217da56b4fSdrhdo_not_use_codec 22a58f26f9Sdan 23a58f26f9Sdanset testprefix wal5 24a58f26f9Sdan 25f2b8dd58Sdanproc db_page_count {{file test.db}} { expr [file size $file] / 1024 } 26f2b8dd58Sdanproc wal_page_count {{file test.db}} { wal_frame_count ${file}-wal 1024 } 27f2b8dd58Sdan 28f2b8dd58Sdan 299c5e3680Sdan# A checkpoint may be requested either using the C API or by executing 309c5e3680Sdan# an SQL PRAGMA command. To test both methods, all tests in this file are 319c5e3680Sdan# run twice - once using each method to request checkpoints. 329c5e3680Sdan# 339c5e3680Sdanforeach {testprefix do_wal_checkpoint} { 34a58f26f9Sdan 359c5e3680Sdan wal5-pragma { 369c5e3680Sdan proc do_wal_checkpoint { dbhandle args } { 379c5e3680Sdan array set a $args 389c5e3680Sdan foreach key [array names a] { 399c5e3680Sdan if {[lsearch {-mode -db} $key]<0} { error "unknown switch: $key" } 409c5e3680Sdan } 419c5e3680Sdan 429c5e3680Sdan set sql "PRAGMA " 439c5e3680Sdan if {[info exists a(-db)]} { append sql "$a(-db)." } 449c5e3680Sdan append sql "wal_checkpoint" 459c5e3680Sdan if {[info exists a(-mode)]} { append sql " = $a(-mode)" } 469c5e3680Sdan 479c5e3680Sdan uplevel [list $dbhandle eval $sql] 489c5e3680Sdan } 499c5e3680Sdan } 509c5e3680Sdan 519c5e3680Sdan wal5-capi { 529c5e3680Sdan proc do_wal_checkpoint { dbhandle args } { 539c5e3680Sdan set a(-mode) passive 549c5e3680Sdan array set a $args 559c5e3680Sdan foreach key [array names a] { 569c5e3680Sdan if {[lsearch {-mode -db} $key]<0} { error "unknown switch: $key" } 579c5e3680Sdan } 589c5e3680Sdan 59f26a1549Sdan set vals {restart full truncate} 60f26a1549Sdan if {[lsearch -exact $vals $a(-mode)]<0} { set a(-mode) passive } 619c5e3680Sdan 629c5e3680Sdan set cmd [list sqlite3_wal_checkpoint_v2 $dbhandle $a(-mode)] 639c5e3680Sdan if {[info exists a(-db)]} { lappend sql $a(-db) } 649c5e3680Sdan 659c5e3680Sdan uplevel $cmd 669c5e3680Sdan } 679c5e3680Sdan } 689c5e3680Sdan} { 699c5e3680Sdan 709c5e3680Sdan eval $do_wal_checkpoint 719c5e3680Sdan 729c5e3680Sdan do_multiclient_test tn { 73a58f26f9Sdan 74a58f26f9Sdan set ::nBusyHandler 0 75a58f26f9Sdan set ::busy_handler_script "" 76a58f26f9Sdan proc busyhandler {n} { 77a58f26f9Sdan incr ::nBusyHandler 78a58f26f9Sdan eval $::busy_handler_script 79a58f26f9Sdan return 0 80a58f26f9Sdan } 81a58f26f9Sdan 82a58f26f9Sdan proc reopen_all {} { 83a58f26f9Sdan code1 {db close} 84a58f26f9Sdan code2 {db2 close} 85a58f26f9Sdan code3 {db3 close} 869c5e3680Sdan 87a58f26f9Sdan code1 {sqlite3 db test.db} 88a58f26f9Sdan code2 {sqlite3 db2 test.db} 89a58f26f9Sdan code3 {sqlite3 db3 test.db} 909c5e3680Sdan 91a58f26f9Sdan sql1 { PRAGMA synchronous = NORMAL } 92a58f26f9Sdan code1 { db busy busyhandler } 93a58f26f9Sdan } 94a58f26f9Sdan 95a58f26f9Sdan do_test 1.$tn.1 { 96a58f26f9Sdan reopen_all 97a58f26f9Sdan sql1 { 98a58f26f9Sdan PRAGMA page_size = 1024; 99a58f26f9Sdan PRAGMA auto_vacuum = 0; 100a58f26f9Sdan CREATE TABLE t1(x, y); 101a58f26f9Sdan PRAGMA journal_mode = WAL; 102a58f26f9Sdan INSERT INTO t1 VALUES(1, zeroblob(1200)); 103a58f26f9Sdan INSERT INTO t1 VALUES(2, zeroblob(1200)); 104a58f26f9Sdan INSERT INTO t1 VALUES(3, zeroblob(1200)); 105a58f26f9Sdan } 106a58f26f9Sdan expr [file size test.db] / 1024 107a58f26f9Sdan } {2} 108a58f26f9Sdan 109a58f26f9Sdan # Have connection 2 grab a read-lock on the current snapshot. 110a58f26f9Sdan do_test 1.$tn.2 { sql2 { BEGIN; SELECT x FROM t1 } } {1 2 3} 111a58f26f9Sdan 112a58f26f9Sdan # Attempt a checkpoint. 113a58f26f9Sdan do_test 1.$tn.3 { 1149c5e3680Sdan code1 { do_wal_checkpoint db } 115a58f26f9Sdan list [db_page_count] [wal_page_count] 116a58f26f9Sdan } {5 9} 117a58f26f9Sdan 118a58f26f9Sdan # Write to the db again. The log cannot wrap because of the lock still 119a58f26f9Sdan # held by connection 2. The busy-handler has not yet been invoked. 120a58f26f9Sdan do_test 1.$tn.4 { 121a58f26f9Sdan sql1 { INSERT INTO t1 VALUES(4, zeroblob(1200)) } 122a58f26f9Sdan list [db_page_count] [wal_page_count] $::nBusyHandler 123a58f26f9Sdan } {5 12 0} 124a58f26f9Sdan 125a58f26f9Sdan # Now do a blocking-checkpoint. Set the busy-handler up so that connection 126a58f26f9Sdan # 2 releases its lock on the 6th invocation. The checkpointer should then 127a58f26f9Sdan # proceed to checkpoint the entire log file. Next write should go to the 128a58f26f9Sdan # start of the log file. 129a58f26f9Sdan # 130a58f26f9Sdan set ::busy_handler_script { if {$n==5} { sql2 COMMIT } } 131a58f26f9Sdan do_test 1.$tn.5 { 1329c5e3680Sdan code1 { do_wal_checkpoint db -mode restart } 133a58f26f9Sdan list [db_page_count] [wal_page_count] $::nBusyHandler 134a58f26f9Sdan } {6 12 6} 135a58f26f9Sdan do_test 1.$tn.6 { 136a58f26f9Sdan set ::nBusyHandler 0 137a58f26f9Sdan sql1 { INSERT INTO t1 VALUES(5, zeroblob(1200)) } 138a58f26f9Sdan list [db_page_count] [wal_page_count] $::nBusyHandler 139a58f26f9Sdan } {6 12 0} 140a58f26f9Sdan 141a58f26f9Sdan do_test 1.$tn.7 { 142a58f26f9Sdan reopen_all 143a58f26f9Sdan list [db_page_count] [wal_page_count] $::nBusyHandler 144*82f52540Sdrh } [expr {[nonzero_reserved_bytes]?"/# # 0/":"7 0 0"}] 145a58f26f9Sdan 146a58f26f9Sdan do_test 1.$tn.8 { sql2 { BEGIN ; SELECT x FROM t1 } } {1 2 3 4 5} 147a58f26f9Sdan do_test 1.$tn.9 { 148a58f26f9Sdan sql1 { INSERT INTO t1 VALUES(6, zeroblob(1200)) } 149a58f26f9Sdan list [db_page_count] [wal_page_count] $::nBusyHandler 150*82f52540Sdrh } [expr {[nonzero_reserved_bytes]?"/# # #/":"7 5 0"}] 151a58f26f9Sdan do_test 1.$tn.10 { sql3 { BEGIN ; SELECT x FROM t1 } } {1 2 3 4 5 6} 152a58f26f9Sdan 153a58f26f9Sdan set ::busy_handler_script { 154a58f26f9Sdan if {$n==5} { sql2 COMMIT } 155a58f26f9Sdan if {$n==6} { set ::db_file_size [db_page_count] } 156a58f26f9Sdan if {$n==7} { sql3 COMMIT } 157a58f26f9Sdan } 158a58f26f9Sdan do_test 1.$tn.11 { 1599c5e3680Sdan code1 { do_wal_checkpoint db -mode restart } 160a58f26f9Sdan list [db_page_count] [wal_page_count] $::nBusyHandler 161*82f52540Sdrh } [expr {[nonzero_reserved_bytes]?"/# # #/":"10 5 8"}] 162a58f26f9Sdan do_test 1.$tn.12 { set ::db_file_size } 10 163a58f26f9Sdan } 164a58f26f9Sdan 165f2b8dd58Sdan #------------------------------------------------------------------------- 166f2b8dd58Sdan # This block of tests explores checkpoint operations on more than one 167f2b8dd58Sdan # database file. 168f2b8dd58Sdan # 169f2b8dd58Sdan proc setup_and_attach_aux {} { 170f2b8dd58Sdan sql1 { ATTACH 'test.db2' AS aux } 171f2b8dd58Sdan sql2 { ATTACH 'test.db2' AS aux } 172f2b8dd58Sdan sql3 { ATTACH 'test.db2' AS aux } 173f2b8dd58Sdan sql1 { 1747fa65fbfSdan PRAGMA aux.auto_vacuum = 0; 1757fa65fbfSdan PRAGMA main.auto_vacuum = 0; 176f2b8dd58Sdan PRAGMA main.page_size=1024; PRAGMA main.journal_mode=WAL; 177f2b8dd58Sdan PRAGMA aux.page_size=1024; PRAGMA aux.journal_mode=WAL; 178f2b8dd58Sdan } 179f2b8dd58Sdan } 180f2b8dd58Sdan 181f2b8dd58Sdan proc file_page_counts {} { 182f2b8dd58Sdan list [db_page_count test.db ] \ 183f2b8dd58Sdan [wal_page_count test.db ] \ 184f2b8dd58Sdan [db_page_count test.db2] \ 185f2b8dd58Sdan [wal_page_count test.db2] 186f2b8dd58Sdan } 187f2b8dd58Sdan 18808756372Sdan # Test that executing "PRAGMA wal_checkpoint" checkpoints all attached 1899c5e3680Sdan # databases, not just the main db. In capi mode, check that this is 1909c5e3680Sdan # true if a NULL pointer is passed to wal_checkpoint_v2() in place of a 1919c5e3680Sdan # database name. 192f2b8dd58Sdan do_multiclient_test tn { 193f2b8dd58Sdan setup_and_attach_aux 194f2b8dd58Sdan do_test 2.1.$tn.1 { 195f2b8dd58Sdan sql1 { 196f2b8dd58Sdan CREATE TABLE t1(a, b); 197f2b8dd58Sdan INSERT INTO t1 VALUES(1, 2); 198f2b8dd58Sdan CREATE TABLE aux.t2(a, b); 199f2b8dd58Sdan INSERT INTO t2 VALUES(1, 2); 200f2b8dd58Sdan } 201f2b8dd58Sdan } {} 2020774bb59Sdan do_test 2.2.$tn.2 { file_page_counts } {1 3 1 3} 2030774bb59Sdan do_test 2.1.$tn.3 { code1 { do_wal_checkpoint db } } {0 3 3} 2040774bb59Sdan do_test 2.1.$tn.4 { file_page_counts } {2 3 2 3} 205f2b8dd58Sdan } 206f2b8dd58Sdan 207f2b8dd58Sdan do_multiclient_test tn { 208f2b8dd58Sdan setup_and_attach_aux 209f2b8dd58Sdan do_test 2.2.$tn.1 { 210f2b8dd58Sdan execsql { 211f2b8dd58Sdan CREATE TABLE t1(a, b); 212f2b8dd58Sdan INSERT INTO t1 VALUES(1, 2); 213f2b8dd58Sdan CREATE TABLE aux.t2(a, b); 214f2b8dd58Sdan INSERT INTO t2 VALUES(1, 2); 215f2b8dd58Sdan INSERT INTO t2 VALUES(3, 4); 216f2b8dd58Sdan } 217f2b8dd58Sdan } {} 2180774bb59Sdan do_test 2.2.$tn.2 { file_page_counts } {1 3 1 4} 219f2b8dd58Sdan do_test 2.2.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2} 2200774bb59Sdan do_test 2.2.$tn.4 { code1 { do_wal_checkpoint db -mode restart } } {1 3 3} 2210774bb59Sdan do_test 2.2.$tn.5 { file_page_counts } {2 3 2 4} 222f2b8dd58Sdan } 223f2b8dd58Sdan 224f2b8dd58Sdan do_multiclient_test tn { 225f2b8dd58Sdan setup_and_attach_aux 226f2b8dd58Sdan do_test 2.3.$tn.1 { 227f2b8dd58Sdan execsql { 228f2b8dd58Sdan CREATE TABLE t1(a, b); 229f2b8dd58Sdan INSERT INTO t1 VALUES(1, 2); 230f2b8dd58Sdan CREATE TABLE aux.t2(a, b); 231f2b8dd58Sdan INSERT INTO t2 VALUES(1, 2); 232f2b8dd58Sdan } 233f2b8dd58Sdan } {} 2340774bb59Sdan do_test 2.3.$tn.2 { file_page_counts } {1 3 1 3} 235f2b8dd58Sdan do_test 2.3.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2} 236f2b8dd58Sdan do_test 2.3.$tn.4 { sql1 { INSERT INTO t1 VALUES(3, 4) } } {} 237f2b8dd58Sdan do_test 2.3.$tn.5 { sql1 { INSERT INTO t2 VALUES(3, 4) } } {} 2380774bb59Sdan do_test 2.3.$tn.6 { file_page_counts } {1 4 1 4} 2390774bb59Sdan do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 4 3} 2407909e54aSdan 2417909e54aSdan # The checkpoint above only writes page 1 of the db file. The other 2427909e54aSdan # page (page 2) is locked by the read-transaction opened by the 2437909e54aSdan # [sql2] commmand above. So normally, the db is 1 page in size here. 2447909e54aSdan # However, in mmap() mode, the db is pre-allocated to 2 pages at the 2457909e54aSdan # start of the checkpoint, even though page 2 cannot be written. 2460d0614bdSdrh set nDb 2 2479b4c59faSdrh if {[permutation]!="mmap"} {set nDb 1} 248188d4884Sdrh ifcapable !mmap {set nDb 1} 2497909e54aSdan do_test 2.3.$tn.8 { file_page_counts } [list $nDb 4 2 4] 250f2b8dd58Sdan } 251f2b8dd58Sdan 25208756372Sdan # Check that checkpoints block on the correct locks. And respond correctly 25308756372Sdan # if they cannot obtain those locks. There are three locks that a checkpoint 25408756372Sdan # may block on (in the following order): 25508756372Sdan # 25608756372Sdan # 1. The writer lock: FULL and RESTART checkpoints block until any writer 25708756372Sdan # process releases its lock. 25808756372Sdan # 25908756372Sdan # 2. Readers using part of the log file. FULL and RESTART checkpoints block 26008756372Sdan # until readers using part (but not all) of the log file have finished. 26108756372Sdan # 26208756372Sdan # 3. Readers using any of the log file. After copying data into the 26308756372Sdan # database file, RESTART checkpoints block until readers using any part 26408756372Sdan # of the log file have finished. 26508756372Sdan # 26624cd616eSdan # This test case involves running a checkpoint while there exist other 26724cd616eSdan # processes holding all three types of locks. 26824cd616eSdan # 26908756372Sdan foreach {tn1 checkpoint busy_on ckpt_expected expected} { 2700774bb59Sdan 1 PASSIVE - {0 3 3} - 2710774bb59Sdan 2 TYPO - {0 3 3} - 27208756372Sdan 2730774bb59Sdan 3 FULL - {0 4 4} 2 2740774bb59Sdan 4 FULL 1 {1 3 3} 1 2750774bb59Sdan 5 FULL 2 {1 4 3} 2 2760774bb59Sdan 6 FULL 3 {0 4 4} 2 27708756372Sdan 2780774bb59Sdan 7 RESTART - {0 4 4} 3 2790774bb59Sdan 8 RESTART 1 {1 3 3} 1 2800774bb59Sdan 9 RESTART 2 {1 4 3} 2 2810774bb59Sdan 10 RESTART 3 {1 4 4} 3 28208756372Sdan 283f26a1549Sdan 11 TRUNCATE - {0 0 0} 3 284f26a1549Sdan 12 TRUNCATE 1 {1 3 3} 1 285f26a1549Sdan 13 TRUNCATE 2 {1 4 3} 2 286f26a1549Sdan 14 TRUNCATE 3 {1 4 4} 3 287f26a1549Sdan 28808756372Sdan } { 28908756372Sdan do_multiclient_test tn { 29008756372Sdan setup_and_attach_aux 29108756372Sdan 29208756372Sdan proc busyhandler {x} { 29308756372Sdan set ::max_busyhandler $x 29408756372Sdan if {$::busy_on!="-" && $x==$::busy_on} { return 1 } 29508756372Sdan switch -- $x { 29608756372Sdan 1 { sql2 "COMMIT ; BEGIN ; SELECT * FROM t1" } 29708756372Sdan 2 { sql3 "COMMIT" } 29808756372Sdan 3 { sql2 "COMMIT" } 29908756372Sdan } 30008756372Sdan return 0 30108756372Sdan } 30208756372Sdan set ::max_busyhandler - 30308756372Sdan 30408756372Sdan do_test 2.4.$tn1.$tn.1 { 30508756372Sdan sql1 { 30608756372Sdan CREATE TABLE t1(a, b); 30708756372Sdan INSERT INTO t1 VALUES(1, 2); 30808756372Sdan } 30908756372Sdan sql2 { BEGIN; INSERT INTO t1 VALUES(3, 4) } 31008756372Sdan sql3 { BEGIN; SELECT * FROM t1 } 31108756372Sdan } {1 2} 31208756372Sdan 31308756372Sdan do_test 2.4.$tn1.$tn.2 { 31408756372Sdan code1 { db busy busyhandler } 3159c5e3680Sdan code1 { do_wal_checkpoint db -mode [string tolower $checkpoint] } 31608756372Sdan } $ckpt_expected 31708756372Sdan do_test 2.4.$tn1.$tn.3 { set ::max_busyhandler } $expected 31808756372Sdan } 31908756372Sdan } 320f2b8dd58Sdan 321f2b8dd58Sdan 3229c5e3680Sdan do_multiclient_test tn { 3239c5e3680Sdan 3249c5e3680Sdan code1 $do_wal_checkpoint 3259c5e3680Sdan code2 $do_wal_checkpoint 3269c5e3680Sdan code3 $do_wal_checkpoint 3279c5e3680Sdan 3289c5e3680Sdan do_test 3.$tn.1 { 3299c5e3680Sdan sql1 { 3307fa65fbfSdan PRAGMA auto_vacuum = 0; 3319c5e3680Sdan PRAGMA journal_mode = WAL; 3329c5e3680Sdan PRAGMA synchronous = normal; 3339c5e3680Sdan CREATE TABLE t1(x, y); 3349c5e3680Sdan } 3359c5e3680Sdan 3369c5e3680Sdan sql2 { PRAGMA journal_mode } 3379c5e3680Sdan sql3 { PRAGMA journal_mode } 3389c5e3680Sdan } {wal} 3399c5e3680Sdan 3409c5e3680Sdan do_test 3.$tn.2 { code2 { do_wal_checkpoint db2 } } {0 2 2} 3419c5e3680Sdan 3429c5e3680Sdan do_test 3.$tn.3 { code2 { do_wal_checkpoint db2 } } {0 2 2} 3439c5e3680Sdan 3449c5e3680Sdan do_test 3.$tn.4 { code3 { do_wal_checkpoint db3 } } {0 2 2} 3459c5e3680Sdan 3469c5e3680Sdan code1 {db close} 3479c5e3680Sdan code2 {db2 close} 3489c5e3680Sdan code3 {db3 close} 3499c5e3680Sdan 3509c5e3680Sdan code1 {sqlite3 db test.db} 3519c5e3680Sdan code2 {sqlite3 db2 test.db} 3529c5e3680Sdan code3 {sqlite3 db3 test.db} 3539c5e3680Sdan 3549c5e3680Sdan do_test 3.$tn.5 { sql3 { PRAGMA journal_mode } } {wal} 3559c5e3680Sdan 3569c5e3680Sdan do_test 3.$tn.6 { code3 { do_wal_checkpoint db3 } } {0 0 0} 3579c5e3680Sdan } 358f26a1549Sdan 359f26a1549Sdan # Test SQLITE_CHECKPOINT_TRUNCATE. 360f26a1549Sdan # 361f26a1549Sdan do_multiclient_test tn { 362f26a1549Sdan 363f26a1549Sdan code1 $do_wal_checkpoint 364f26a1549Sdan code2 $do_wal_checkpoint 365f26a1549Sdan code3 $do_wal_checkpoint 366f26a1549Sdan 36762031584Sdan do_test 4.$tn.1 { 368f26a1549Sdan sql1 { 369f26a1549Sdan PRAGMA page_size = 1024; 37062031584Sdan PRAGMA auto_vacuum = 0; 371f26a1549Sdan PRAGMA journal_mode = WAL; 372f26a1549Sdan PRAGMA synchronous = normal; 373f26a1549Sdan CREATE TABLE t1(x, y); 374f26a1549Sdan CREATE INDEX i1 ON t1(x, y); 375f26a1549Sdan INSERT INTO t1 VALUES(1, 2); 376f26a1549Sdan INSERT INTO t1 VALUES(3, 4); 377f26a1549Sdan } 378f26a1549Sdan file size test.db-wal 379f26a1549Sdan } [wal_file_size 8 1024] 380f26a1549Sdan 38162031584Sdan do_test 4.$tn.2 { do_wal_checkpoint db -mode truncate } {0 0 0} 38262031584Sdan do_test 4.$tn.3 { file size test.db-wal } 0 383f26a1549Sdan 38462031584Sdan do_test 4.$tn.4 { 385f26a1549Sdan sql2 { SELECT * FROM t1 } 386f26a1549Sdan } {1 2 3 4} 387f26a1549Sdan 38862031584Sdan do_test 4.$tn.5 { 389f26a1549Sdan sql2 { INSERT INTO t1 VALUES('a', 'b') } 390f26a1549Sdan file size test.db-wal 391f26a1549Sdan } [wal_file_size 2 1024] 392f26a1549Sdan 393f26a1549Sdan } 394976b0033Sdan 395976b0033Sdan # Test that FULL, RESTART and TRUNCATE callbacks block on other clients 396976b0033Sdan # and truncate the wal file as required even if the entire wal file has 397976b0033Sdan # already been checkpointed when they are invoked. 398976b0033Sdan # 399976b0033Sdan do_multiclient_test tn { 400976b0033Sdan 401976b0033Sdan code1 $do_wal_checkpoint 402976b0033Sdan code2 $do_wal_checkpoint 403976b0033Sdan code3 $do_wal_checkpoint 404976b0033Sdan 405976b0033Sdan do_test 5.$tn.1 { 406976b0033Sdan sql1 { 407976b0033Sdan PRAGMA page_size = 1024; 408976b0033Sdan PRAGMA auto_vacuum = 0; 409976b0033Sdan PRAGMA journal_mode = WAL; 410976b0033Sdan PRAGMA synchronous = normal; 411976b0033Sdan CREATE TABLE t1(x, y); 412976b0033Sdan CREATE INDEX i1 ON t1(x, y); 413976b0033Sdan INSERT INTO t1 VALUES(1, 2); 414976b0033Sdan INSERT INTO t1 VALUES(3, 4); 415976b0033Sdan INSERT INTO t1 VALUES(5, 6); 416976b0033Sdan } 417976b0033Sdan file size test.db-wal 418976b0033Sdan } [wal_file_size 10 1024] 419976b0033Sdan 420976b0033Sdan do_test 5.$tn.2 { 421976b0033Sdan sql2 { BEGIN; SELECT * FROM t1 } 422976b0033Sdan } {1 2 3 4 5 6} 423976b0033Sdan 424976b0033Sdan do_test 5.$tn.3 { do_wal_checkpoint db -mode passive } {0 10 10} 425976b0033Sdan 426976b0033Sdan do_test 5.$tn.4 { 427976b0033Sdan sql3 { BEGIN; INSERT INTO t1 VALUES(7, 8); } 428976b0033Sdan } {} 429976b0033Sdan 430976b0033Sdan do_test 5.$tn.5 { do_wal_checkpoint db -mode passive } {0 10 10} 431976b0033Sdan do_test 5.$tn.6 { do_wal_checkpoint db -mode full } {1 10 10} 432976b0033Sdan 433976b0033Sdan do_test 5.$tn.7 { sql3 { ROLLBACK } } {} 434976b0033Sdan 435976b0033Sdan do_test 5.$tn.8 { do_wal_checkpoint db -mode full } {0 10 10} 436976b0033Sdan do_test 5.$tn.9 { do_wal_checkpoint db -mode truncate } {1 10 10} 437976b0033Sdan 438976b0033Sdan do_test 5.$tn.10 { 439976b0033Sdan file size test.db-wal 440976b0033Sdan } [wal_file_size 10 1024] 441976b0033Sdan 442976b0033Sdan proc xBusyHandler {n} { sql2 { COMMIT } ; return 0 } 443976b0033Sdan db busy xBusyHandler 444976b0033Sdan 445976b0033Sdan do_test 5.$tn.11 { do_wal_checkpoint db -mode truncate } {0 0 0} 446976b0033Sdan do_test 5.$tn.12 { file size test.db-wal } 0 447976b0033Sdan 448976b0033Sdan do_test 5.$tn.13 { 449976b0033Sdan sql1 { 450976b0033Sdan INSERT INTO t1 VALUES(7, 8); 451976b0033Sdan INSERT INTO t1 VALUES(9, 10); 452976b0033Sdan SELECT * FROM t1; 453976b0033Sdan } 454976b0033Sdan } {1 2 3 4 5 6 7 8 9 10} 455976b0033Sdan 456976b0033Sdan do_test 5.$tn.14 { 457976b0033Sdan sql2 { BEGIN; SELECT * FROM t1 } 458976b0033Sdan } {1 2 3 4 5 6 7 8 9 10} 459976b0033Sdan 460976b0033Sdan proc xBusyHandler {n} { return 1 } 461fdc2e6d3Smistachkin do_test 5.$tn.15 { do_wal_checkpoint db -mode truncate } {1 4 4} 462fdc2e6d3Smistachkin do_test 5.$tn.16 { file size test.db-wal } [wal_file_size 4 1024] 463976b0033Sdan 464fdc2e6d3Smistachkin do_test 5.$tn.17 { do_wal_checkpoint db -mode restart } {1 4 4} 465976b0033Sdan 466976b0033Sdan proc xBusyHandler {n} { sql2 { COMMIT } ; return 0 } 467976b0033Sdan db busy xBusyHandler 468fdc2e6d3Smistachkin do_test 5.$tn.18 { do_wal_checkpoint db -mode restart } {0 4 4} 469fdc2e6d3Smistachkin do_test 5.$tn.19 { file size test.db-wal } [wal_file_size 4 1024] 470976b0033Sdan 471fdc2e6d3Smistachkin do_test 5.$tn.20 { do_wal_checkpoint db -mode truncate } {0 0 0} 472fdc2e6d3Smistachkin do_test 5.$tn.21 { file size test.db-wal } 0 473976b0033Sdan } 474976b0033Sdan 4759c5e3680Sdan} 4769c5e3680Sdan 4779c5e3680Sdan 478a58f26f9Sdanfinish_test 479