github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/e_walauto.test (about) 1 # 2014 December 04 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 13 set testdir [file dirname $argv0] 14 source $testdir/tester.tcl 15 source $testdir/wal_common.tcl 16 set testprefix e_walauto 17 18 # Do not run this test on OpenBSD, as it depends on read() and mmap both 19 # accessing the same coherent view of the "test.db-shm" file. This doesn't 20 # work on OpenBSD. 21 # 22 if {$tcl_platform(os) == "OpenBSD"} { 23 finish_test 24 return 25 } 26 27 # This module uses hard-coded offsets which do not work if the reserved_bytes 28 # value is nonzero. 29 if {[nonzero_reserved_bytes]} {finish_test; return;} 30 31 32 proc read_nbackfill {} { 33 seek $::shmfd 96 34 binary scan [read $::shmfd 4] n nBackfill 35 set nBackfill 36 } 37 proc read_mxframe {} { 38 seek $::shmfd 16 39 binary scan [read $::shmfd 4] n mxFrame 40 set mxFrame 41 } 42 43 # Assuming that the main db for database handle 44 # 45 proc do_autocommit_threshold_test {tn value} { 46 47 set nBackfillSaved [read_nbackfill] 48 while {1} { 49 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 50 if {[read_mxframe] >= $value} break 51 } 52 53 set nBackfillNew [read_nbackfill] 54 uplevel [list do_test $tn "expr $nBackfillNew > $nBackfillSaved" 1] 55 } 56 57 # EVIDENCE-OF: R-30135-06439 The wal_autocheckpoint pragma can be used 58 # to invoke this interface from SQL. 59 # 60 # All tests in this file are run twice - once using the 61 # sqlite3_wal_autocheckpoint() API, and once using "PRAGMA 62 # wal_autocheckpoint". 63 # 64 foreach {tn code} { 65 1 { 66 proc autocheckpoint {db value} { 67 uplevel [list $db eval "PRAGMA wal_autocheckpoint = $value"] 68 } 69 } 70 71 2 { 72 proc autocheckpoint {db value} { 73 uplevel [list sqlite3_wal_autocheckpoint $db $value] 74 return $value 75 } 76 } 77 } { 78 79 eval $code 80 81 reset_db 82 execsql { PRAGMA auto_vacuum = 0 } 83 do_execsql_test 1.$tn.0 { PRAGMA journal_mode = WAL } {wal} 84 do_execsql_test 1.$tn.1 { CREATE TABLE t1(a, b) } 85 set shmfd [open "test.db-shm" rb] 86 87 # EVIDENCE-OF: R-41531-51083 Every new database connection defaults to 88 # having the auto-checkpoint enabled with a threshold of 1000 or 89 # SQLITE_DEFAULT_WAL_AUTOCHECKPOINT pages. 90 # 91 do_autocommit_threshold_test 1.$tn.2 1000 92 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 93 do_autocommit_threshold_test 1.$tn.3 1000 94 95 # EVIDENCE-OF: R-38128-34102 The sqlite3_wal_autocheckpoint(D,N) is a 96 # wrapper around sqlite3_wal_hook() that causes any database on database 97 # connection D to automatically checkpoint after committing a 98 # transaction if there are N or more frames in the write-ahead log file. 99 # 100 do_test 1.$tn.4 { 101 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 102 autocheckpoint db 100 103 } {100} 104 do_autocommit_threshold_test 1.$tn.5 100 105 106 do_test 1.$tn.6 { 107 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 108 autocheckpoint db 500 109 } {500} 110 do_autocommit_threshold_test 1.$tn.7 500 111 112 # EVIDENCE-OF: R-26993-43540 Passing zero or a negative value as the 113 # nFrame parameter disables automatic checkpoints entirely. 114 # 115 do_test 1.$tn.7 { 116 autocheckpoint db 0 ;# Set to zero 117 for {set i 0} {$i < 10000} {incr i} { 118 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 119 } 120 expr {[file size test.db-wal] > (5 * 1024 * 1024)} 121 } 1 122 do_test 1.$tn.8 { 123 sqlite3_wal_checkpoint_v2 db truncate 124 file size test.db-wal 125 } 0 126 do_test 1.$tn.9 { 127 autocheckpoint db -4 ;# Set to a negative value 128 for {set i 0} {$i < 10000} {incr i} { 129 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 130 } 131 expr {[file size test.db-wal] > (5 * 1024 * 1024)} 132 } 1 133 134 # EVIDENCE-OF: R-10203-42688 The callback registered by this function 135 # replaces any existing callback registered using sqlite3_wal_hook(). 136 # 137 set ::wal_hook_callback 0 138 proc wal_hook_callback {args} { incr ::wal_hook_callback ; return 0 } 139 do_test 1.$tn.10.1 { 140 db wal_hook wal_hook_callback 141 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 142 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 143 set ::wal_hook_callback 144 } 2 145 do_test 1.$tn.10.2 { 146 autocheckpoint db 100 147 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 148 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 149 set ::wal_hook_callback 150 } 2 151 152 # EVIDENCE-OF: R-17497-43474 Likewise, registering a callback using 153 # sqlite3_wal_hook() disables the automatic checkpoint mechanism 154 # configured by this function. 155 do_test 1.$tn.11.1 { 156 sqlite3_wal_checkpoint_v2 db truncate 157 file size test.db-wal 158 } 0 159 do_test 1.$tn.11.2 { 160 autocheckpoint db 100 161 for {set i 0} {$i < 1000} {incr i} { 162 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 163 } 164 expr {[file size test.db-wal] < (1 * 1024 * 1024)} 165 } 1 166 do_test 1.$tn.11.3 { 167 db wal_hook wal_hook_callback 168 for {set i 0} {$i < 1000} {incr i} { 169 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 170 } 171 expr {[file size test.db-wal] < (1 * 1024 * 1024)} 172 } 0 173 174 # EVIDENCE-OF: R-33080-59193 Checkpoints initiated by this mechanism 175 # are PASSIVE. 176 # 177 set ::busy_callback_count 0 178 proc busy_callback {args} { 179 incr ::busy_callback_count 180 return 0 181 } 182 do_test 1.$tn.12.1 { 183 sqlite3_wal_checkpoint_v2 db truncate 184 autocheckpoint db 100 185 db busy busy_callback 186 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 187 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 188 } {} 189 do_test 1.$tn.12.2 { 190 sqlite3 db2 test.db 191 db2 eval { BEGIN; SELECT * FROM t1 LIMIT 10; } 192 read_nbackfill 193 } {0} 194 do_test 1.$tn.12.3 { 195 for {set i 0} {$i < 1000} {incr i} { 196 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 197 } 198 read_nbackfill 199 } {2} 200 do_test 1.$tn.12.4 { 201 set ::busy_callback_count 202 } {0} 203 db2 close 204 205 do_test 1.$tn.12.5 { 206 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) } 207 read_nbackfill 208 } {1559} 209 210 db close 211 close $shmfd 212 } 213 214 finish_test