dan | d3f8f94 | 2010-04-13 11:35:01 +0000 | [diff] [blame] | 1 | # 2010 April 13 |
| 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 | # This file implements regression tests for SQLite library. The |
| 12 | # focus of this file is testing the operation of the library in |
| 13 | # "PRAGMA journal_mode=WAL" mode. |
| 14 | # |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 15 | |
| 16 | set testdir [file dirname $argv0] |
| 17 | source $testdir/tester.tcl |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 18 | source $testdir/lock_common.tcl |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 19 | |
dan | 5cf5353 | 2010-05-01 16:40:20 +0000 | [diff] [blame] | 20 | ifcapable !wal {finish_test ; return } |
| 21 | |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 22 | proc reopen_db {} { |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 23 | catch { db close } |
dan | 31f98fc | 2010-04-27 05:42:32 +0000 | [diff] [blame] | 24 | file delete -force test.db test.db-wal test.db-wal-summary |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 25 | sqlite3_wal db test.db |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 26 | } |
| 27 | |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 28 | set ::blobcnt 0 |
| 29 | proc blob {nByte} { |
| 30 | incr ::blobcnt |
| 31 | return [string range [string repeat "${::blobcnt}x" $nByte] 1 $nByte] |
| 32 | } |
| 33 | |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 34 | proc sqlite3_wal {args} { |
| 35 | eval sqlite3 $args |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 36 | [lindex $args 0] eval { PRAGMA page_size = 1024 } |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 37 | [lindex $args 0] eval { PRAGMA journal_mode = wal } |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 38 | [lindex $args 0] eval { PRAGMA synchronous = normal } |
| 39 | [lindex $args 0] function blob blob |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 40 | } |
| 41 | |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 42 | proc log_file_size {nFrame pgsz} { |
| 43 | expr {12 + ($pgsz+16)*$nFrame} |
| 44 | } |
| 45 | |
dan | 3de777f | 2010-04-17 12:31:37 +0000 | [diff] [blame] | 46 | proc log_deleted {logfile} { |
| 47 | return [expr [file exists $logfile]==0] |
| 48 | } |
| 49 | |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 50 | # |
| 51 | # These are 'warm-body' tests used while developing the WAL code. They |
| 52 | # serve to prove that a few really simple cases work: |
| 53 | # |
| 54 | # wal-1.*: Read and write the database. |
| 55 | # wal-2.*: Test MVCC with one reader, one writer. |
| 56 | # wal-3.*: Test transaction rollback. |
| 57 | # wal-4.*: Test savepoint/statement rollback. |
| 58 | # wal-5.*: Test the temp database. |
| 59 | # wal-6.*: Test creating databases with different page sizes. |
| 60 | # |
| 61 | |
| 62 | do_test wal-0.1 { |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 63 | execsql { PRAGMA synchronous = normal } |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 64 | execsql { PRAGMA journal_mode = wal } |
| 65 | } {wal} |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 66 | do_test wal-0.2 { |
| 67 | file size test.db |
| 68 | } {1024} |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 69 | |
| 70 | do_test wal-1.0 { |
| 71 | execsql { |
| 72 | BEGIN; |
| 73 | CREATE TABLE t1(a, b); |
| 74 | } |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 75 | list [file exists test.db-journal] \ |
| 76 | [file exists test.db-wal] \ |
| 77 | [file size test.db] |
| 78 | } {0 1 1024} |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 79 | do_test wal-1.1 { |
| 80 | execsql COMMIT |
| 81 | list [file exists test.db-journal] [file exists test.db-wal] |
| 82 | } {0 1} |
| 83 | do_test wal-1.2 { |
| 84 | # There are now two pages in the log. |
| 85 | file size test.db-wal |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 86 | } [log_file_size 2 1024] |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 87 | |
| 88 | do_test wal-1.3 { |
| 89 | execsql { SELECT * FROM sqlite_master } |
| 90 | } {table t1 t1 2 {CREATE TABLE t1(a, b)}} |
| 91 | |
| 92 | do_test wal-1.4 { |
| 93 | execsql { INSERT INTO t1 VALUES(1, 2) } |
| 94 | execsql { INSERT INTO t1 VALUES(3, 4) } |
| 95 | execsql { INSERT INTO t1 VALUES(5, 6) } |
| 96 | execsql { INSERT INTO t1 VALUES(7, 8) } |
| 97 | execsql { INSERT INTO t1 VALUES(9, 10) } |
| 98 | } {} |
| 99 | |
| 100 | do_test wal-1.5 { |
| 101 | execsql { SELECT * FROM t1 } |
| 102 | } {1 2 3 4 5 6 7 8 9 10} |
| 103 | |
| 104 | do_test wal-2.1 { |
| 105 | sqlite3_wal db2 ./test.db |
| 106 | execsql { BEGIN; SELECT * FROM t1 } db2 |
| 107 | } {1 2 3 4 5 6 7 8 9 10} |
| 108 | |
| 109 | do_test wal-2.2 { |
| 110 | execsql { INSERT INTO t1 VALUES(11, 12) } |
| 111 | execsql { SELECT * FROM t1 } |
| 112 | } {1 2 3 4 5 6 7 8 9 10 11 12} |
| 113 | |
| 114 | do_test wal-2.3 { |
| 115 | execsql { SELECT * FROM t1 } db2 |
| 116 | } {1 2 3 4 5 6 7 8 9 10} |
| 117 | |
| 118 | do_test wal-2.4 { |
| 119 | execsql { INSERT INTO t1 VALUES(13, 14) } |
| 120 | execsql { SELECT * FROM t1 } |
| 121 | } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} |
| 122 | |
| 123 | do_test wal-2.5 { |
| 124 | execsql { SELECT * FROM t1 } db2 |
| 125 | } {1 2 3 4 5 6 7 8 9 10} |
| 126 | |
| 127 | do_test wal-2.6 { |
| 128 | execsql { COMMIT; SELECT * FROM t1 } db2 |
| 129 | } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} |
| 130 | |
| 131 | do_test wal-3.1 { |
| 132 | execsql { BEGIN; DELETE FROM t1 } |
| 133 | execsql { SELECT * FROM t1 } |
| 134 | } {} |
| 135 | do_test wal-3.2 { |
| 136 | execsql { SELECT * FROM t1 } db2 |
| 137 | } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} |
| 138 | do_test wal-3.3 { |
| 139 | execsql { ROLLBACK } |
| 140 | execsql { SELECT * FROM t1 } |
| 141 | } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} |
| 142 | db2 close |
| 143 | |
dan | 74d6cd8 | 2010-04-24 18:44:05 +0000 | [diff] [blame] | 144 | #------------------------------------------------------------------------- |
| 145 | # The following tests, wal-4.*, test that savepoints work with WAL |
| 146 | # databases. |
| 147 | # |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 148 | do_test wal-4.1 { |
| 149 | execsql { |
| 150 | DELETE FROM t1; |
| 151 | BEGIN; |
| 152 | INSERT INTO t1 VALUES('a', 'b'); |
| 153 | SAVEPOINT sp; |
| 154 | INSERT INTO t1 VALUES('c', 'd'); |
| 155 | SELECT * FROM t1; |
| 156 | } |
| 157 | } {a b c d} |
| 158 | do_test wal-4.2 { |
| 159 | execsql { |
| 160 | ROLLBACK TO sp; |
| 161 | SELECT * FROM t1; |
| 162 | } |
| 163 | } {a b} |
| 164 | do_test wal-4.3 { |
| 165 | execsql { |
| 166 | COMMIT; |
| 167 | SELECT * FROM t1; |
| 168 | } |
| 169 | } {a b} |
| 170 | |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 171 | do_test wal-4.4.1 { |
dan | 74d6cd8 | 2010-04-24 18:44:05 +0000 | [diff] [blame] | 172 | db close |
| 173 | sqlite3 db test.db |
| 174 | db func blob blob |
| 175 | list [execsql { SELECT * FROM t1 }] [file size test.db-wal] |
| 176 | } {{a b} 0} |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 177 | do_test wal-4.4.2 { |
dan | 74d6cd8 | 2010-04-24 18:44:05 +0000 | [diff] [blame] | 178 | execsql { PRAGMA cache_size = 10 } |
| 179 | execsql { |
| 180 | CREATE TABLE t2(a, b); |
| 181 | INSERT INTO t2 VALUES(blob(400), blob(400)); |
| 182 | SAVEPOINT tr; |
| 183 | INSERT INTO t2 SELECT blob(400), blob(400) FROM t2; /* 2 */ |
| 184 | INSERT INTO t2 SELECT blob(400), blob(400) FROM t2; /* 4 */ |
| 185 | INSERT INTO t2 SELECT blob(400), blob(400) FROM t2; /* 8 */ |
| 186 | INSERT INTO t2 SELECT blob(400), blob(400) FROM t2; /* 16 */ |
| 187 | INSERT INTO t2 SELECT blob(400), blob(400) FROM t2; /* 32 */ |
| 188 | INSERT INTO t1 SELECT blob(400), blob(400) FROM t1; /* 2 */ |
| 189 | INSERT INTO t1 SELECT blob(400), blob(400) FROM t1; /* 4 */ |
| 190 | INSERT INTO t1 SELECT blob(400), blob(400) FROM t1; /* 8 */ |
| 191 | INSERT INTO t1 SELECT blob(400), blob(400) FROM t1; /* 16 */ |
| 192 | INSERT INTO t1 SELECT blob(400), blob(400) FROM t1; /* 32 */ |
| 193 | SELECT count(*) FROM t2; |
| 194 | } |
| 195 | } {32} |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 196 | do_test wal-4.4.3 { |
dan | 74d6cd8 | 2010-04-24 18:44:05 +0000 | [diff] [blame] | 197 | execsql { ROLLBACK TO tr } |
| 198 | } {} |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 199 | do_test wal-4.4.4 { |
dan | 74d6cd8 | 2010-04-24 18:44:05 +0000 | [diff] [blame] | 200 | set logsize [file size test.db-wal] |
| 201 | execsql { |
| 202 | INSERT INTO t1 VALUES('x', 'y'); |
| 203 | RELEASE tr; |
| 204 | } |
| 205 | expr { $logsize == [file size test.db-wal] } |
| 206 | } {1} |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 207 | do_test wal-4.4.5 { |
dan | 74d6cd8 | 2010-04-24 18:44:05 +0000 | [diff] [blame] | 208 | execsql { SELECT count(*) FROM t2 } |
| 209 | } {1} |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 210 | do_test wal-4.4.6 { |
dan | 74d6cd8 | 2010-04-24 18:44:05 +0000 | [diff] [blame] | 211 | file copy -force test.db test2.db |
| 212 | file copy -force test.db-wal test2.db-wal |
| 213 | sqlite3 db2 test2.db |
| 214 | execsql { SELECT count(*) FROM t2 ; SELECT count(*) FROM t1 } db2 |
| 215 | } {1 2} |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 216 | do_test wal-4.4.7 { |
dan | 74d6cd8 | 2010-04-24 18:44:05 +0000 | [diff] [blame] | 217 | execsql { PRAGMA integrity_check } db2 |
| 218 | } {ok} |
| 219 | db2 close |
| 220 | |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 221 | do_test wal-4.5.1 { |
| 222 | reopen_db |
| 223 | db func blob blob |
| 224 | execsql { |
| 225 | PRAGMA journal_mode = WAL; |
| 226 | CREATE TABLE t1(a, b); |
| 227 | INSERT INTO t1 VALUES('a', 'b'); |
| 228 | } |
| 229 | sqlite3 db test.db |
| 230 | db func blob blob |
| 231 | list [execsql { SELECT * FROM t1 }] [file size test.db-wal] |
| 232 | } {{a b} 0} |
| 233 | do_test wal-4.5.2 { |
| 234 | execsql { PRAGMA cache_size = 10 } |
| 235 | execsql { |
| 236 | CREATE TABLE t2(a, b); |
| 237 | BEGIN; |
| 238 | INSERT INTO t2 VALUES(blob(400), blob(400)); |
| 239 | SAVEPOINT tr; |
| 240 | INSERT INTO t2 SELECT blob(400), blob(400) FROM t2; /* 2 */ |
| 241 | INSERT INTO t2 SELECT blob(400), blob(400) FROM t2; /* 4 */ |
| 242 | INSERT INTO t2 SELECT blob(400), blob(400) FROM t2; /* 8 */ |
| 243 | INSERT INTO t2 SELECT blob(400), blob(400) FROM t2; /* 16 */ |
| 244 | INSERT INTO t2 SELECT blob(400), blob(400) FROM t2; /* 32 */ |
| 245 | INSERT INTO t1 SELECT blob(400), blob(400) FROM t1; /* 2 */ |
| 246 | INSERT INTO t1 SELECT blob(400), blob(400) FROM t1; /* 4 */ |
| 247 | INSERT INTO t1 SELECT blob(400), blob(400) FROM t1; /* 8 */ |
| 248 | INSERT INTO t1 SELECT blob(400), blob(400) FROM t1; /* 16 */ |
| 249 | INSERT INTO t1 SELECT blob(400), blob(400) FROM t1; /* 32 */ |
| 250 | SELECT count(*) FROM t2; |
| 251 | } |
| 252 | } {32} |
| 253 | do_test wal-4.5.3 { |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 254 | execsql { ROLLBACK TO tr } |
| 255 | } {} |
| 256 | do_test wal-4.5.4 { |
| 257 | set logsize [file size test.db-wal] |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 258 | execsql { |
| 259 | INSERT INTO t1 VALUES('x', 'y'); |
| 260 | RELEASE tr; |
| 261 | COMMIT; |
| 262 | } |
| 263 | expr { $logsize == [file size test.db-wal] } |
| 264 | } {1} |
| 265 | do_test wal-4.5.5 { |
| 266 | execsql { SELECT count(*) FROM t2 ; SELECT count(*) FROM t1 } |
| 267 | } {1 2} |
| 268 | do_test wal-4.5.6 { |
| 269 | file copy -force test.db test2.db |
| 270 | file copy -force test.db-wal test2.db-wal |
| 271 | sqlite3 db2 test2.db |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 272 | execsql { SELECT count(*) FROM t2 ; SELECT count(*) FROM t1 } db2 |
| 273 | } {1 2} |
| 274 | do_test wal-4.5.7 { |
| 275 | execsql { PRAGMA integrity_check } db2 |
| 276 | } {ok} |
| 277 | db2 close |
| 278 | |
| 279 | |
dan | 74d6cd8 | 2010-04-24 18:44:05 +0000 | [diff] [blame] | 280 | reopen_db |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 281 | do_test wal-5.1 { |
| 282 | execsql { |
| 283 | CREATE TEMP TABLE t2(a, b); |
| 284 | INSERT INTO t2 VALUES(1, 2); |
| 285 | } |
| 286 | } {} |
| 287 | do_test wal-5.2 { |
| 288 | execsql { |
| 289 | BEGIN; |
| 290 | INSERT INTO t2 VALUES(3, 4); |
| 291 | SELECT * FROM t2; |
| 292 | } |
| 293 | } {1 2 3 4} |
| 294 | do_test wal-5.3 { |
| 295 | execsql { |
| 296 | ROLLBACK; |
| 297 | SELECT * FROM t2; |
| 298 | } |
| 299 | } {1 2} |
| 300 | do_test wal-5.4 { |
| 301 | execsql { |
| 302 | CREATE TEMP TABLE t3(x UNIQUE); |
| 303 | BEGIN; |
| 304 | INSERT INTO t2 VALUES(3, 4); |
| 305 | INSERT INTO t3 VALUES('abc'); |
| 306 | } |
| 307 | catchsql { INSERT INTO t3 VALUES('abc') } |
| 308 | } {1 {column x is not unique}} |
| 309 | do_test wal-5.5 { |
| 310 | execsql { |
| 311 | COMMIT; |
| 312 | SELECT * FROM t2; |
| 313 | } |
| 314 | } {1 2 3 4} |
| 315 | db close |
| 316 | |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 317 | foreach sector {512 4096} { |
| 318 | sqlite3_simulate_device -sectorsize $sector |
| 319 | foreach pgsz {512 1024 2048 4096} { |
| 320 | file delete -force test.db test.db-wal |
| 321 | do_test wal-6.$sector.$pgsz.1 { |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 322 | sqlite3 db test.db -vfs devsym |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 323 | execsql " |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 324 | PRAGMA page_size = $pgsz; |
| 325 | PRAGMA journal_mode = wal; |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 326 | " |
| 327 | execsql " |
| 328 | CREATE TABLE t1(a, b); |
| 329 | INSERT INTO t1 VALUES(1, 2); |
| 330 | " |
| 331 | db close |
| 332 | file size test.db |
| 333 | } [expr $pgsz*2] |
| 334 | |
| 335 | do_test wal-6.$sector.$pgsz.2 { |
dan | 3de777f | 2010-04-17 12:31:37 +0000 | [diff] [blame] | 336 | log_deleted test.db-wal |
| 337 | } {1} |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 338 | } |
| 339 | } |
| 340 | |
| 341 | do_test wal-7.1 { |
| 342 | file delete -force test.db test.db-wal |
| 343 | sqlite3_wal db test.db |
| 344 | execsql { |
| 345 | PRAGMA page_size = 1024; |
| 346 | CREATE TABLE t1(a, b); |
| 347 | INSERT INTO t1 VALUES(1, 2); |
| 348 | } |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 349 | list [file size test.db] [file size test.db-wal] |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 350 | } [list 1024 [log_file_size 3 1024]] |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 351 | do_test wal-7.2 { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 352 | execsql { PRAGMA wal_checkpoint } |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 353 | list [file size test.db] [file size test.db-wal] |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 354 | } [list 2048 [log_file_size 3 1024]] |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 355 | |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 356 | # Execute some transactions in auto-vacuum mode to test database file |
| 357 | # truncation. |
| 358 | # |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 359 | do_test wal-8.1 { |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 360 | reopen_db |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 361 | catch { db close } |
| 362 | file delete -force test.db test.db-wal |
| 363 | |
| 364 | sqlite3 db test.db |
| 365 | db function blob blob |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 366 | execsql { |
| 367 | PRAGMA auto_vacuum = 1; |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 368 | PRAGMA journal_mode = wal; |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 369 | PRAGMA auto_vacuum; |
| 370 | } |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 371 | } {wal 1} |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 372 | do_test wal-8.2 { |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 373 | execsql { |
| 374 | PRAGMA page_size = 1024; |
| 375 | CREATE TABLE t1(x); |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 376 | INSERT INTO t1 VALUES(blob(900)); |
| 377 | INSERT INTO t1 VALUES(blob(900)); |
| 378 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 4 */ |
| 379 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 8 */ |
| 380 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 16 */ |
| 381 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 32 */ |
| 382 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 64 */ |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 383 | PRAGMA wal_checkpoint; |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 384 | } |
| 385 | file size test.db |
dan | 80a1526 | 2010-04-13 11:45:31 +0000 | [diff] [blame] | 386 | } [expr 68*1024] |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 387 | do_test wal-8.3 { |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 388 | execsql { |
| 389 | DELETE FROM t1 WHERE rowid<54; |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 390 | PRAGMA wal_checkpoint; |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 391 | } |
| 392 | file size test.db |
| 393 | } [expr 14*1024] |
| 394 | |
| 395 | # Run some "warm-body" tests to ensure that log-summary files with more |
| 396 | # than 256 entries (log summaries that contain index blocks) work Ok. |
| 397 | # |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 398 | do_test wal-9.1 { |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 399 | reopen_db |
| 400 | execsql { |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 401 | CREATE TABLE t1(x PRIMARY KEY); |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 402 | INSERT INTO t1 VALUES(blob(900)); |
| 403 | INSERT INTO t1 VALUES(blob(900)); |
| 404 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 4 */ |
| 405 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 8 */ |
| 406 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 16 */ |
| 407 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 32 */ |
| 408 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 64 */ |
| 409 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 128 */ |
| 410 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 256 */ |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 411 | } |
| 412 | file size test.db |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 413 | } 1024 |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 414 | do_test wal-9.2 { |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 415 | sqlite3_wal db2 test.db |
| 416 | execsql {PRAGMA integrity_check } db2 |
| 417 | } {ok} |
| 418 | |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 419 | do_test wal-9.3 { |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 420 | file delete -force test2.db test2.db-wal |
| 421 | file copy test.db test2.db |
| 422 | file copy test.db-wal test2.db-wal |
| 423 | sqlite3_wal db3 test2.db |
| 424 | execsql {PRAGMA integrity_check } db3 |
| 425 | } {ok} |
| 426 | db3 close |
| 427 | |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 428 | do_test wal-9.4 { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 429 | execsql { PRAGMA wal_checkpoint } |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 430 | db2 close |
| 431 | sqlite3_wal db2 test.db |
| 432 | execsql {PRAGMA integrity_check } db2 |
| 433 | } {ok} |
| 434 | |
dan | 80a1526 | 2010-04-13 11:45:31 +0000 | [diff] [blame] | 435 | foreach handle {db db2 db3} { catch { $handle close } } |
| 436 | unset handle |
| 437 | |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 438 | #------------------------------------------------------------------------- |
| 439 | # The following block of tests - wal-10.* - test that the WAL locking |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 440 | # scheme works in simple cases. This block of tests is run twice. Once |
| 441 | # using multiple connections in the address space of the current process, |
| 442 | # and once with all connections except one running in external processes. |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 443 | # |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 444 | foreach code [list { |
| 445 | set ::code2_chan [launch_testfixture] |
| 446 | set ::code3_chan [launch_testfixture] |
| 447 | proc code2 {tcl} { testfixture $::code2_chan $tcl } |
| 448 | proc code3 {tcl} { testfixture $::code3_chan $tcl } |
| 449 | set tn 1 |
| 450 | } { |
| 451 | proc code2 {tcl} { uplevel #0 $tcl } |
| 452 | proc code3 {tcl} { uplevel #0 $tcl } |
| 453 | set tn 2 |
| 454 | }] { |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 455 | |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 456 | eval $code |
| 457 | reopen_db |
| 458 | |
| 459 | # Open connections [db2] and [db3]. Depending on which iteration this |
| 460 | # is, the connections may be created in this interpreter, or in |
| 461 | # interpreters running in other OS processes. As such, the [db2] and [db3] |
| 462 | # commands should only be accessed within [code2] and [code3] blocks, |
| 463 | # respectively. |
| 464 | # |
| 465 | code2 { sqlite3 db2 test.db ; db2 eval { PRAGMA journal_mode = WAL } } |
| 466 | code3 { sqlite3 db3 test.db ; db3 eval { PRAGMA journal_mode = WAL } } |
| 467 | |
| 468 | # Shorthand commands. Execute SQL using database connection [db2] or |
| 469 | # [db3]. Return the results. |
| 470 | # |
| 471 | proc sql2 {sql} { code2 [list db2 eval $sql] } |
| 472 | proc sql3 {sql} { code3 [list db3 eval $sql] } |
| 473 | |
| 474 | # Initialize the database schema and contents. |
| 475 | # |
| 476 | do_test wal-10.$tn.1 { |
| 477 | execsql { |
| 478 | CREATE TABLE t1(a, b); |
| 479 | INSERT INTO t1 VALUES(1, 2); |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 480 | SELECT * FROM t1; |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 481 | } |
| 482 | } {1 2} |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 483 | |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 484 | # Open a transaction and write to the database using [db]. Check that [db2] |
| 485 | # is still able to read the snapshot before the transaction was opened. |
| 486 | # |
| 487 | do_test wal-10.$tn.2 { |
| 488 | execsql { BEGIN; INSERT INTO t1 VALUES(3, 4); } |
| 489 | sql2 {SELECT * FROM t1} |
| 490 | } {1 2} |
| 491 | |
| 492 | # Have [db] commit the transaction. Check that [db2] is now seeing the |
| 493 | # new, updated snapshot. |
| 494 | # |
| 495 | do_test wal-10.$tn.3 { |
| 496 | execsql { COMMIT } |
| 497 | sql2 {SELECT * FROM t1} |
| 498 | } {1 2 3 4} |
| 499 | |
| 500 | # Have [db2] open a read transaction. Then write to the db via [db]. Check |
| 501 | # that [db2] is still seeing the original snapshot. Then read with [db3]. |
| 502 | # [db3] should see the newly committed data. |
| 503 | # |
| 504 | do_test wal-10.$tn.4 { |
| 505 | sql2 { BEGIN ; SELECT * FROM t1} |
| 506 | } {1 2 3 4} |
| 507 | do_test wal-10.$tn.5 { |
| 508 | execsql { INSERT INTO t1 VALUES(5, 6); } |
| 509 | sql2 {SELECT * FROM t1} |
| 510 | } {1 2 3 4} |
| 511 | do_test wal-10.$tn.6 { |
| 512 | sql3 {SELECT * FROM t1} |
| 513 | } {1 2 3 4 5 6} |
| 514 | do_test wal-10.$tn.7 { |
| 515 | sql2 COMMIT |
| 516 | } {} |
| 517 | |
| 518 | # Have [db2] open a write transaction. Then attempt to write to the |
| 519 | # database via [db]. This should fail (writer lock cannot be obtained). |
| 520 | # |
| 521 | # Then open a read-transaction with [db]. Commit the [db2] transaction |
| 522 | # to disk. Verify that [db] still cannot write to the database (because |
| 523 | # it is reading an old snapshot). |
| 524 | # |
| 525 | # Close the current [db] transaction. Open a new one. [db] can now write |
| 526 | # to the database (as it is not locked and [db] is reading the latest |
| 527 | # snapshot). |
| 528 | # |
| 529 | do_test wal-10.$tn.7 { |
| 530 | sql2 { BEGIN; INSERT INTO t1 VALUES(7, 8) ; } |
| 531 | catchsql { INSERT INTO t1 VALUES(9, 10) } |
| 532 | } {1 {database is locked}} |
| 533 | do_test wal-10.$tn.8 { |
| 534 | execsql { BEGIN ; SELECT * FROM t1 } |
| 535 | } {1 2 3 4 5 6} |
| 536 | do_test wal-10.$tn.9 { |
| 537 | sql2 COMMIT |
| 538 | catchsql { INSERT INTO t1 VALUES(9, 10) } |
| 539 | } {1 {database is locked}} |
| 540 | do_test wal-10.$tn.10 { |
| 541 | execsql { COMMIT; BEGIN; INSERT INTO t1 VALUES(9, 10); COMMIT; } |
| 542 | execsql { SELECT * FROM t1 } |
| 543 | } {1 2 3 4 5 6 7 8 9 10} |
| 544 | |
| 545 | # Open a read transaction with [db2]. Check that this prevents [db] from |
| 546 | # checkpointing the database. But not from writing to it. |
| 547 | # |
| 548 | do_test wal-10.$tn.11 { |
| 549 | sql2 { BEGIN; SELECT * FROM t1 } |
| 550 | } {1 2 3 4 5 6 7 8 9 10} |
| 551 | do_test wal-10.$tn.12 { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 552 | catchsql { PRAGMA wal_checkpoint } |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 553 | } {1 {database is locked}} |
| 554 | do_test wal-10.$tn.13 { |
| 555 | execsql { INSERT INTO t1 VALUES(11, 12) } |
| 556 | sql2 {SELECT * FROM t1} |
| 557 | } {1 2 3 4 5 6 7 8 9 10} |
| 558 | |
| 559 | # Connection [db2] is holding a lock on a snapshot, preventing [db] from |
| 560 | # checkpointing the database. Add a busy-handler to [db]. If [db2] completes |
| 561 | # its transaction from within the busy-handler, [db] is able to complete |
| 562 | # the checkpoint operation. |
| 563 | # |
| 564 | proc busyhandler x { |
| 565 | if {$x==4} { sql2 COMMIT } |
| 566 | if {$x<5} { return 0 } |
| 567 | return 1 |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 568 | } |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 569 | db busy busyhandler |
| 570 | do_test wal-10.$tn.14 { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 571 | execsql { PRAGMA wal_checkpoint } |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 572 | } {} |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 573 | |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 574 | # Similar to the test above. Except this time, a new read transaction is |
| 575 | # started (db3) while the checkpointer is waiting for an old one (db2) to |
| 576 | # finish. The checkpointer can finish, but any subsequent write operations |
| 577 | # must wait until after db3 has closed the read transaction, as db3 is a |
| 578 | # "region D" writer. |
| 579 | # |
| 580 | db busy {} |
| 581 | do_test wal-10.$tn.15 { |
| 582 | sql2 { BEGIN; SELECT * FROM t1; } |
| 583 | } {1 2 3 4 5 6 7 8 9 10 11 12} |
| 584 | do_test wal-10.$tn.16 { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 585 | catchsql { PRAGMA wal_checkpoint } |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 586 | } {1 {database is locked}} |
| 587 | proc busyhandler x { |
| 588 | if {$x==3} { sql3 { BEGIN; SELECT * FROM t1 } } |
| 589 | if {$x==4} { sql2 COMMIT } |
| 590 | if {$x<5} { return 0 } |
| 591 | return 1 |
| 592 | } |
| 593 | db busy busyhandler |
dan | 49320f8 | 2010-04-14 18:50:08 +0000 | [diff] [blame] | 594 | do_test wal-10.$tn.17 { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 595 | execsql { PRAGMA wal_checkpoint } |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 596 | } {} |
dan | 49320f8 | 2010-04-14 18:50:08 +0000 | [diff] [blame] | 597 | do_test wal-10.$tn.18 { |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 598 | sql3 { SELECT * FROM t1 } |
| 599 | } {1 2 3 4 5 6 7 8 9 10 11 12} |
dan | 49320f8 | 2010-04-14 18:50:08 +0000 | [diff] [blame] | 600 | do_test wal-10.$tn.19 { |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 601 | catchsql { INSERT INTO t1 VALUES(13, 14) } |
| 602 | } {1 {database is locked}} |
dan | 49320f8 | 2010-04-14 18:50:08 +0000 | [diff] [blame] | 603 | do_test wal-10.$tn.20 { |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 604 | execsql { SELECT * FROM t1 } |
| 605 | } {1 2 3 4 5 6 7 8 9 10 11 12} |
dan | 49320f8 | 2010-04-14 18:50:08 +0000 | [diff] [blame] | 606 | do_test wal-10.$tn.21 { |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 607 | sql3 COMMIT |
| 608 | } {} |
dan | 49320f8 | 2010-04-14 18:50:08 +0000 | [diff] [blame] | 609 | do_test wal-10.$tn.22 { |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 610 | execsql { INSERT INTO t1 VALUES(13, 14) } |
| 611 | execsql { SELECT * FROM t1 } |
| 612 | } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} |
dan | b9bf16b | 2010-04-14 11:23:30 +0000 | [diff] [blame] | 613 | |
dan | 49320f8 | 2010-04-14 18:50:08 +0000 | [diff] [blame] | 614 | # Set [db3] up as a "region D" reader again. Then upgrade it to a writer |
| 615 | # and back down to a reader. Then, check that a checkpoint is not possible |
| 616 | # (as [db3] still has a snapshot locked). |
| 617 | # |
| 618 | do_test wal-10.$tn.23 { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 619 | execsql { PRAGMA wal_checkpoint } |
dan | 49320f8 | 2010-04-14 18:50:08 +0000 | [diff] [blame] | 620 | } {} |
| 621 | do_test wal-10.$tn.24 { |
| 622 | sql2 { BEGIN; SELECT * FROM t1; } |
| 623 | } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} |
| 624 | do_test wal-10.$tn.25 { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 625 | execsql { PRAGMA wal_checkpoint } |
dan | 49320f8 | 2010-04-14 18:50:08 +0000 | [diff] [blame] | 626 | } {} |
| 627 | do_test wal-10.$tn.26 { |
| 628 | catchsql { INSERT INTO t1 VALUES(15, 16) } |
| 629 | } {1 {database is locked}} |
| 630 | do_test wal-10.$tn.27 { |
| 631 | sql3 { INSERT INTO t1 VALUES(15, 16) } |
| 632 | } {} |
| 633 | do_test wal-10.$tn.28 { |
| 634 | code3 { |
| 635 | set ::STMT [sqlite3_prepare db3 "SELECT * FROM t1" -1 TAIL] |
| 636 | sqlite3_step $::STMT |
| 637 | } |
| 638 | sql3 COMMIT |
| 639 | execsql { SELECT * FROM t1 } |
| 640 | } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16} |
| 641 | db busy {} |
| 642 | do_test wal-10.$tn.29 { |
| 643 | execsql { INSERT INTO t1 VALUES(17, 18) } |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 644 | catchsql { PRAGMA wal_checkpoint } |
dan | 49320f8 | 2010-04-14 18:50:08 +0000 | [diff] [blame] | 645 | } {1 {database is locked}} |
| 646 | do_test wal-10.$tn.30 { |
| 647 | code3 { sqlite3_finalize $::STMT } |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 648 | execsql { PRAGMA wal_checkpoint } |
dan | 49320f8 | 2010-04-14 18:50:08 +0000 | [diff] [blame] | 649 | } {} |
| 650 | |
| 651 | # At one point, if a reader failed to upgrade to a writer because it |
| 652 | # was reading an old snapshot, the write-locks were not being released. |
| 653 | # Test that this bug has been fixed. |
| 654 | # |
| 655 | do_test wal-10.$tn.31 { |
| 656 | execsql { BEGIN ; SELECT * FROM t1 } |
| 657 | sql2 { INSERT INTO t1 VALUES(19, 20) } |
| 658 | catchsql { INSERT INTO t1 VALUES(21, 22) } |
| 659 | } {1 {database is locked}} |
| 660 | do_test wal-10.$tn.32 { |
| 661 | # This statement would fail when the bug was present. |
| 662 | sql2 { INSERT INTO t1 VALUES(21, 22) } |
| 663 | } {} |
| 664 | do_test wal-10.$tn.33 { |
| 665 | execsql { SELECT * FROM t1 ; COMMIT } |
| 666 | } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18} |
| 667 | do_test wal-10.$tn.34 { |
| 668 | execsql { SELECT * FROM t1 } |
| 669 | } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22} |
| 670 | |
dan | 8b348af | 2010-04-27 18:43:16 +0000 | [diff] [blame] | 671 | # Test that if a checkpointer cannot obtain the required locks, it |
| 672 | # releases all locks before returning a busy error. |
| 673 | # |
| 674 | do_test wal-10.$tn.35 { |
| 675 | execsql { |
| 676 | DELETE FROM t1; |
| 677 | INSERT INTO t1 VALUES('a', 'b'); |
| 678 | INSERT INTO t1 VALUES('c', 'd'); |
| 679 | } |
| 680 | sql2 { |
| 681 | BEGIN; |
| 682 | SELECT * FROM t1; |
| 683 | } |
| 684 | } {a b c d} |
| 685 | proc busyhandler x { return 1 } |
| 686 | db busy busyhandler |
| 687 | do_test wal-10.$tn.36 { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 688 | catchsql { PRAGMA wal_checkpoint } |
dan | 8b348af | 2010-04-27 18:43:16 +0000 | [diff] [blame] | 689 | } {1 {database is locked}} |
| 690 | do_test wal-10.$tn.36 { |
| 691 | sql3 { INSERT INTO t1 VALUES('e', 'f') } |
| 692 | sql2 { SELECT * FROM t1 } |
| 693 | } {a b c d} |
| 694 | do_test wal-10.$tn.37 { |
| 695 | sql2 COMMIT |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 696 | execsql { PRAGMA wal_checkpoint } |
dan | 8b348af | 2010-04-27 18:43:16 +0000 | [diff] [blame] | 697 | } {} |
| 698 | |
dan | e264d98 | 2010-04-14 18:06:50 +0000 | [diff] [blame] | 699 | catch { db close } |
| 700 | catch { code2 { db2 close } } |
| 701 | catch { code3 { db3 close } } |
| 702 | catch { close $::code2_chan } |
| 703 | catch { close $::code3_chan } |
| 704 | } |
| 705 | |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 706 | #------------------------------------------------------------------------- |
| 707 | # This block of tests, wal-11.*, test that nothing goes terribly wrong |
| 708 | # if frames must be written to the log file before a transaction is |
| 709 | # committed (in order to free up memory). |
| 710 | # |
| 711 | do_test wal-11.1 { |
| 712 | reopen_db |
| 713 | execsql { |
| 714 | PRAGMA cache_size = 10; |
| 715 | PRAGMA page_size = 1024; |
| 716 | CREATE TABLE t1(x PRIMARY KEY); |
| 717 | } |
| 718 | list [expr [file size test.db]/1024] [expr [file size test.db-wal]/1044] |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 719 | } {1 3} |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 720 | do_test wal-11.2 { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 721 | execsql { PRAGMA wal_checkpoint } |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 722 | list [expr [file size test.db]/1024] [file size test.db-wal] |
| 723 | } [list 3 [log_file_size 3 1024]] |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 724 | do_test wal-11.3 { |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 725 | execsql { INSERT INTO t1 VALUES( blob(900) ) } |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 726 | list [expr [file size test.db]/1024] [file size test.db-wal] |
| 727 | } [list 3 [log_file_size 4 1024]] |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 728 | |
| 729 | do_test wal-11.4 { |
| 730 | execsql { |
| 731 | BEGIN; |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 732 | INSERT INTO t1 SELECT blob(900) FROM t1; -- 2 |
| 733 | INSERT INTO t1 SELECT blob(900) FROM t1; -- 4 |
| 734 | INSERT INTO t1 SELECT blob(900) FROM t1; -- 8 |
| 735 | INSERT INTO t1 SELECT blob(900) FROM t1; -- 16 |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 736 | } |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 737 | list [expr [file size test.db]/1024] [file size test.db-wal] |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 738 | } [list 3 [log_file_size 32 1024]] |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 739 | do_test wal-11.5 { |
| 740 | execsql { |
| 741 | SELECT count(*) FROM t1; |
| 742 | PRAGMA integrity_check; |
| 743 | } |
| 744 | } {16 ok} |
| 745 | do_test wal-11.6 { |
| 746 | execsql COMMIT |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 747 | list [expr [file size test.db]/1024] [file size test.db-wal] |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 748 | } [list 3 [log_file_size 41 1024]] |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 749 | do_test wal-11.7 { |
| 750 | execsql { |
| 751 | SELECT count(*) FROM t1; |
| 752 | PRAGMA integrity_check; |
| 753 | } |
| 754 | } {16 ok} |
| 755 | do_test wal-11.8 { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 756 | execsql { PRAGMA wal_checkpoint } |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 757 | list [expr [file size test.db]/1024] [file size test.db-wal] |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 758 | } [list 37 [log_file_size 41 1024]] |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 759 | do_test wal-11.9 { |
| 760 | db close |
dan | 3de777f | 2010-04-17 12:31:37 +0000 | [diff] [blame] | 761 | list [expr [file size test.db]/1024] [log_deleted test.db-wal] |
| 762 | } {37 1} |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 763 | sqlite3_wal db test.db |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 764 | do_test wal-11.10 { |
| 765 | execsql { |
| 766 | PRAGMA cache_size = 10; |
| 767 | BEGIN; |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 768 | INSERT INTO t1 SELECT blob(900) FROM t1; -- 32 |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 769 | SELECT count(*) FROM t1; |
| 770 | } |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 771 | list [expr [file size test.db]/1024] [file size test.db-wal] |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 772 | } [list 37 [log_file_size 37 1024]] |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 773 | do_test wal-11.11 { |
| 774 | execsql { |
| 775 | SELECT count(*) FROM t1; |
| 776 | ROLLBACK; |
| 777 | SELECT count(*) FROM t1; |
| 778 | } |
| 779 | } {32 16} |
| 780 | do_test wal-11.12 { |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 781 | list [expr [file size test.db]/1024] [file size test.db-wal] |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 782 | } [list 37 [log_file_size 37 1024]] |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 783 | do_test wal-11.13 { |
| 784 | execsql { |
dan | 6703239 | 2010-04-17 15:42:43 +0000 | [diff] [blame] | 785 | INSERT INTO t1 VALUES( blob(900) ); |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 786 | SELECT count(*) FROM t1; |
| 787 | PRAGMA integrity_check; |
| 788 | } |
| 789 | } {17 ok} |
| 790 | do_test wal-11.14 { |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 791 | list [expr [file size test.db]/1024] [file size test.db-wal] |
dan | 4cd78b4 | 2010-04-26 16:57:10 +0000 | [diff] [blame] | 792 | } [list 37 [log_file_size 37 1024]] |
dan | 4cc6fb6 | 2010-04-15 16:45:34 +0000 | [diff] [blame] | 793 | |
| 794 | |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 795 | #------------------------------------------------------------------------- |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 796 | # This block of tests, wal-12.*, tests the fix for a problem that |
| 797 | # could occur if a log that is a prefix of an older log is written |
| 798 | # into a reused log file. |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 799 | # |
| 800 | reopen_db |
| 801 | do_test wal-12.1 { |
| 802 | execsql { |
| 803 | PRAGMA page_size = 1024; |
| 804 | CREATE TABLE t1(x, y); |
| 805 | CREATE TABLE t2(x, y); |
| 806 | INSERT INTO t1 VALUES('A', 1); |
| 807 | } |
dan | 97a3135 | 2010-04-16 13:59:31 +0000 | [diff] [blame] | 808 | list [expr [file size test.db]/1024] [file size test.db-wal] |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 809 | } [list 1 [log_file_size 5 1024]] |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 810 | do_test wal-12.2 { |
| 811 | db close |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 812 | sqlite3 db test.db |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 813 | execsql { |
dan | e04dc88 | 2010-04-20 18:53:15 +0000 | [diff] [blame] | 814 | PRAGMA synchronous = normal; |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 815 | UPDATE t1 SET y = 0 WHERE x = 'A'; |
| 816 | } |
| 817 | list [expr [file size test.db]/1024] [expr [file size test.db-wal]/1044] |
| 818 | } {3 1} |
| 819 | do_test wal-12.3 { |
| 820 | execsql { INSERT INTO t2 VALUES('B', 1) } |
| 821 | list [expr [file size test.db]/1024] [expr [file size test.db-wal]/1044] |
| 822 | } {3 2} |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 823 | do_test wal-12.4 { |
| 824 | file copy -force test.db test2.db |
| 825 | file copy -force test.db-wal test2.db-wal |
| 826 | sqlite3_wal db2 test2.db |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 827 | execsql { SELECT * FROM t2 } db2 |
| 828 | } {B 1} |
| 829 | db2 close |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 830 | do_test wal-12.5 { |
| 831 | execsql { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 832 | PRAGMA wal_checkpoint; |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 833 | UPDATE t2 SET y = 2 WHERE x = 'B'; |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 834 | PRAGMA wal_checkpoint; |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 835 | UPDATE t1 SET y = 1 WHERE x = 'A'; |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 836 | PRAGMA wal_checkpoint; |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 837 | UPDATE t1 SET y = 0 WHERE x = 'A'; |
| 838 | SELECT * FROM t2; |
| 839 | } |
| 840 | } {B 2} |
dan | ce4f05f | 2010-04-22 19:14:13 +0000 | [diff] [blame] | 841 | do_test wal-12.6 { |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 842 | file copy -force test.db test2.db |
| 843 | file copy -force test.db-wal test2.db-wal |
| 844 | sqlite3_wal db2 test2.db |
| 845 | execsql { SELECT * FROM t2 } db2 |
| 846 | } {B 2} |
| 847 | db2 close |
dan | ce4f05f | 2010-04-22 19:14:13 +0000 | [diff] [blame] | 848 | db close |
| 849 | |
| 850 | #------------------------------------------------------------------------- |
| 851 | # Test large log summaries. |
| 852 | # |
dan | 31f98fc | 2010-04-27 05:42:32 +0000 | [diff] [blame] | 853 | do_test wal-13.1.1 { |
dan | ce4f05f | 2010-04-22 19:14:13 +0000 | [diff] [blame] | 854 | list [file exists test.db] [file exists test.db-wal] |
| 855 | } {1 0} |
dan | 31f98fc | 2010-04-27 05:42:32 +0000 | [diff] [blame] | 856 | do_test wal-13.1.2 { |
dan | ce4f05f | 2010-04-22 19:14:13 +0000 | [diff] [blame] | 857 | set fd [open test.db-wal w] |
| 858 | seek $fd [expr 200*1024*1024] |
| 859 | puts $fd "" |
| 860 | close $fd |
| 861 | sqlite3 db test.db |
| 862 | execsql { SELECT * FROM t2 } |
| 863 | } {B 2} |
dan | 31f98fc | 2010-04-27 05:42:32 +0000 | [diff] [blame] | 864 | do_test wal-13.1.3 { |
dan | ce4f05f | 2010-04-22 19:14:13 +0000 | [diff] [blame] | 865 | db close |
| 866 | file exists test.db-wal |
| 867 | } {0} |
dan | 31f98fc | 2010-04-27 05:42:32 +0000 | [diff] [blame] | 868 | do_test wal-13.1.4 { |
dan | ce4f05f | 2010-04-22 19:14:13 +0000 | [diff] [blame] | 869 | sqlite3 db test.db |
| 870 | execsql { SELECT count(*) FROM t2 } |
| 871 | } {1} |
dan | 31f98fc | 2010-04-27 05:42:32 +0000 | [diff] [blame] | 872 | do_test wal-13.1.5 { |
| 873 | for {set i 0} {$i < 6} {incr i} { |
dan | ce4f05f | 2010-04-22 19:14:13 +0000 | [diff] [blame] | 874 | execsql { INSERT INTO t2 SELECT randomblob(400), randomblob(400) FROM t2 } |
| 875 | } |
| 876 | execsql { SELECT count(*) FROM t2 } |
dan | 31f98fc | 2010-04-27 05:42:32 +0000 | [diff] [blame] | 877 | } [expr int(pow(2, 6))] |
| 878 | do_test wal-13.1.6 { |
| 879 | file size test.db-wal |
| 880 | } [log_file_size 80 1024] |
dan | ce4f05f | 2010-04-22 19:14:13 +0000 | [diff] [blame] | 881 | |
dan | 31f98fc | 2010-04-27 05:42:32 +0000 | [diff] [blame] | 882 | foreach code [list { |
| 883 | set tn 2 |
| 884 | proc buddy {tcl} { uplevel #0 $tcl } |
| 885 | } { |
| 886 | set tn 3 |
| 887 | set ::buddy [launch_testfixture] |
| 888 | proc buddy {tcl} { testfixture $::buddy $tcl } |
| 889 | }] { |
| 890 | |
| 891 | eval $code |
| 892 | reopen_db |
| 893 | |
| 894 | do_test wal-13.$tn.0 { |
| 895 | buddy { sqlite3 db2 test.db } |
| 896 | execsql { |
| 897 | PRAGMA journal_mode = WAL; |
| 898 | CREATE TABLE t1(x); |
| 899 | INSERT INTO t1 SELECT randomblob(400); |
| 900 | } |
| 901 | execsql { SELECT count(*) FROM t1 } |
| 902 | } {1} |
| 903 | |
| 904 | for {set ii 1} {$ii<16} {incr ii} { |
| 905 | do_test wal-13.$tn.$ii.a { |
| 906 | buddy { db2 eval { INSERT INTO t1 SELECT randomblob(400) FROM t1 } } |
| 907 | buddy { db2 eval { SELECT count(*) FROM t1 } } |
| 908 | } [expr (1<<$ii)] |
| 909 | do_test wal-13.$tn.$ii.b { |
| 910 | db eval { SELECT count(*) FROM t1 } |
| 911 | } [expr (1<<$ii)] |
| 912 | do_test wal-13.$tn.$ii.c { |
| 913 | db eval { SELECT count(*) FROM t1 } |
| 914 | } [expr (1<<$ii)] |
drh | 1b48aa4 | 2010-04-30 17:28:35 +0000 | [diff] [blame] | 915 | do_test wal-13.$tn.$ii.d { |
| 916 | db eval { PRAGMA integrity_check } |
| 917 | } {ok} |
dan | 31f98fc | 2010-04-27 05:42:32 +0000 | [diff] [blame] | 918 | } |
| 919 | |
| 920 | catch { db2 close } |
| 921 | catch { close $::buddy } |
| 922 | db close |
| 923 | } |
dan | 4a4b01d | 2010-04-16 11:30:18 +0000 | [diff] [blame] | 924 | |
dan | 31c0390 | 2010-04-29 14:51:33 +0000 | [diff] [blame] | 925 | #------------------------------------------------------------------------- |
| 926 | # Check a fun corruption case has been fixed. |
| 927 | # |
| 928 | # The problem was that after performing a checkpoint using a connection |
| 929 | # that had an out-of-date pager-cache, the next time the connection was |
| 930 | # used it did not realize the cache was out-of-date and proceeded to |
| 931 | # operate with an inconsistent cache. Leading to corruption. |
| 932 | # |
| 933 | |
| 934 | catch { db close } |
| 935 | catch { db2 close } |
| 936 | catch { db3 close } |
| 937 | file delete -force test.db test.db-wal |
| 938 | sqlite3 db test.db |
| 939 | sqlite3 db2 test.db |
| 940 | |
| 941 | do_test wal-14 { |
| 942 | execsql { |
| 943 | PRAGMA journal_mode = WAL; |
| 944 | CREATE TABLE t1(a PRIMARY KEY, b); |
| 945 | INSERT INTO t1 VALUES(randomblob(10), randomblob(100)); |
| 946 | INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1; |
| 947 | INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1; |
| 948 | INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1; |
| 949 | } |
| 950 | |
| 951 | db2 eval { |
| 952 | INSERT INTO t1 SELECT randomblob(10), randomblob(100); |
| 953 | INSERT INTO t1 SELECT randomblob(10), randomblob(100); |
| 954 | INSERT INTO t1 SELECT randomblob(10), randomblob(100); |
| 955 | INSERT INTO t1 SELECT randomblob(10), randomblob(100); |
| 956 | } |
| 957 | |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 958 | # After executing the "PRAGMA wal_checkpoint", connection [db] was being |
dan | 31c0390 | 2010-04-29 14:51:33 +0000 | [diff] [blame] | 959 | # left with an inconsistent cache. Running the CREATE INDEX statement |
| 960 | # in this state led to database corruption. |
| 961 | catchsql { |
dan | 5a299f9 | 2010-05-03 11:05:08 +0000 | [diff] [blame] | 962 | PRAGMA wal_checkpoint; |
dan | 31c0390 | 2010-04-29 14:51:33 +0000 | [diff] [blame] | 963 | CREATE INDEX i1 on t1(b); |
| 964 | } |
| 965 | |
| 966 | db2 eval { PRAGMA integrity_check } |
| 967 | } {ok} |
| 968 | |
dan | 185cca6 | 2010-04-29 14:58:53 +0000 | [diff] [blame] | 969 | catch { db close } |
| 970 | catch { db2 close } |
dan | 87c1fe1 | 2010-05-03 12:14:15 +0000 | [diff] [blame] | 971 | |
| 972 | #------------------------------------------------------------------------- |
| 973 | # The following block of tests - wal-15.* - focus on testing the |
| 974 | # implementation of the sqlite3_wal_checkpoint() interface. |
| 975 | # |
| 976 | file delete -force test.db test.db-wal |
| 977 | sqlite3 db test.db |
| 978 | do_test wal-15.1 { |
| 979 | execsql { |
| 980 | PRAGMA page_size = 1024; |
| 981 | PRAGMA journal_mode = WAL; |
| 982 | } |
| 983 | execsql { |
| 984 | CREATE TABLE t1(a, b); |
| 985 | INSERT INTO t1 VALUES(1, 2); |
| 986 | } |
| 987 | } {} |
| 988 | |
| 989 | # Test that an error is returned if the database name is not recognized |
| 990 | # |
| 991 | do_test wal-15.2.1 { |
| 992 | sqlite3_wal_checkpoint db aux |
| 993 | } {SQLITE_ERROR} |
| 994 | do_test wal-15.2.2 { |
| 995 | sqlite3_errcode db |
| 996 | } {SQLITE_ERROR} |
| 997 | do_test wal-15.2.3 { |
| 998 | sqlite3_errmsg db |
| 999 | } {unknown database: aux} |
| 1000 | |
| 1001 | # Test that an error is returned if an attempt is made to checkpoint |
| 1002 | # if a transaction is open on the database. |
| 1003 | # |
| 1004 | do_test wal-15.3.1 { |
| 1005 | execsql { |
| 1006 | BEGIN; |
| 1007 | INSERT INTO t1 VALUES(3, 4); |
| 1008 | } |
| 1009 | sqlite3_wal_checkpoint db main |
| 1010 | } {SQLITE_LOCKED} |
| 1011 | do_test wal-15.3.2 { |
| 1012 | sqlite3_errcode db |
| 1013 | } {SQLITE_LOCKED} |
| 1014 | do_test wal-15.3.3 { |
| 1015 | sqlite3_errmsg db |
| 1016 | } {database table is locked} |
| 1017 | |
| 1018 | # Also test that an error is returned if the db cannot be checkpointed |
| 1019 | # because of locks held by another connection. |
| 1020 | # |
| 1021 | sqlite3 db2 test.db |
| 1022 | do_test wal-15.4.1 { |
| 1023 | execsql { |
| 1024 | BEGIN; |
| 1025 | SELECT * FROM t1; |
| 1026 | } db2 |
| 1027 | } {1 2} |
| 1028 | do_test wal-15.4.2 { |
| 1029 | execsql { COMMIT } |
| 1030 | sqlite3_wal_checkpoint db |
| 1031 | } {SQLITE_BUSY} |
| 1032 | do_test wal-15.4.3 { |
| 1033 | sqlite3_errmsg db |
| 1034 | } {database is locked} |
| 1035 | |
| 1036 | # After [db2] drops its lock, [db] may checkpoint the db. |
| 1037 | # |
| 1038 | do_test wal-15.4.4 { |
| 1039 | execsql { COMMIT } db2 |
| 1040 | sqlite3_wal_checkpoint db |
| 1041 | } {SQLITE_OK} |
| 1042 | do_test wal-15.4.5 { |
| 1043 | sqlite3_errmsg db |
| 1044 | } {not an error} |
| 1045 | do_test wal-15.4.6 { |
| 1046 | file size test.db |
| 1047 | } [expr 1024*2] |
| 1048 | |
| 1049 | catch { db2 close } |
| 1050 | catch { db close } |
dan | af0cfd3 | 2010-05-03 15:58:50 +0000 | [diff] [blame^] | 1051 | |
| 1052 | #------------------------------------------------------------------------- |
| 1053 | # The following block of tests - wal-16.* - test that if a NULL pointer or |
| 1054 | # an empty string is passed as the second argument of the wal_checkpoint() |
| 1055 | # API, an attempt is made to checkpoint all attached databases. |
| 1056 | # |
| 1057 | foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { |
| 1058 | 1 {sqlite3_wal_checkpoint db} SQLITE_OK 1 1 |
| 1059 | 2 {sqlite3_wal_checkpoint db ""} SQLITE_OK 1 1 |
| 1060 | 3 {db eval "PRAGMA wal_checkpoint"} {} 1 1 |
| 1061 | |
| 1062 | 4 {sqlite3_wal_checkpoint db main} SQLITE_OK 1 0 |
| 1063 | 5 {sqlite3_wal_checkpoint db aux} SQLITE_OK 0 1 |
| 1064 | 6 {sqlite3_wal_checkpoint db temp} SQLITE_OK 0 0 |
| 1065 | 7 {db eval "PRAGMA main.wal_checkpoint"} {} 1 0 |
| 1066 | 8 {db eval "PRAGMA aux.wal_checkpoint"} {} 0 1 |
| 1067 | 9 {db eval "PRAGMA temp.wal_checkpoint"} {} 0 0 |
| 1068 | } { |
| 1069 | do_test wal-16.$tn.1 { |
| 1070 | file delete -force test2.db test2.db-wal test2.db-journal |
| 1071 | file delete -force test.db test.db-wal test.db-journal |
| 1072 | |
| 1073 | sqlite3 db test.db |
| 1074 | execsql { |
| 1075 | ATTACH 'test2.db' AS aux; |
| 1076 | PRAGMA main.journal_mode = WAL; |
| 1077 | PRAGMA aux.journal_mode = WAL; |
| 1078 | PRAGMA synchronous = NORMAL; |
| 1079 | } |
| 1080 | } {wal wal} |
| 1081 | |
| 1082 | do_test wal-16.$tn.2 { |
| 1083 | execsql { |
| 1084 | CREATE TABLE main.t1(a, b, PRIMARY KEY(a, b)); |
| 1085 | CREATE TABLE aux.t2(a, b, PRIMARY KEY(a, b)); |
| 1086 | |
| 1087 | INSERT INTO t2 VALUES(1, randomblob(1000)); |
| 1088 | INSERT INTO t2 VALUES(2, randomblob(1000)); |
| 1089 | INSERT INTO t1 SELECT * FROM t2; |
| 1090 | } |
| 1091 | |
| 1092 | list [file size test.db] [file size test.db-wal] |
| 1093 | } [list [expr 1*1024] [log_file_size 10 1024]] |
| 1094 | do_test wal-16.$tn.3 { |
| 1095 | list [file size test2.db] [file size test2.db-wal] |
| 1096 | } [list [expr 1*1024] [log_file_size 16 1024]] |
| 1097 | |
| 1098 | do_test wal-16.$tn.4 [list eval $ckpt_cmd] $ckpt_res |
| 1099 | |
| 1100 | do_test wal-16.$tn.5 { |
| 1101 | list [file size test.db] [file size test.db-wal] |
| 1102 | } [list [expr ($ckpt_main ? 7 : 1)*1024] [log_file_size 10 1024]] |
| 1103 | |
| 1104 | do_test wal-16.$tn.6 { |
| 1105 | list [file size test2.db] [file size test2.db-wal] |
| 1106 | } [list [expr ($ckpt_aux ? 7 : 1)*1024] [log_file_size 16 1024]] |
| 1107 | |
| 1108 | catch { db close } |
| 1109 | } |
| 1110 | |
| 1111 | catch { db2 close } |
| 1112 | catch { db close } |
dan | 7c24610 | 2010-04-12 19:00:29 +0000 | [diff] [blame] | 1113 | finish_test |
dan | 87c1fe1 | 2010-05-03 12:14:15 +0000 | [diff] [blame] | 1114 | |
| 1115 | |