| OLD | NEW |
| 1 # 2010 May 24 | 1 # 2010 May 24 |
| 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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 # file occurs using native byte-order checksums. | 146 # file occurs using native byte-order checksums. |
| 147 # | 147 # |
| 148 set native "big" | 148 set native "big" |
| 149 if {$::tcl_platform(byteOrder) == "littleEndian"} { set native "little" } | 149 if {$::tcl_platform(byteOrder) == "littleEndian"} { set native "little" } |
| 150 foreach endian {big little} { | 150 foreach endian {big little} { |
| 151 | 151 |
| 152 # Create a database. Leave some data in the log file. | 152 # Create a database. Leave some data in the log file. |
| 153 # | 153 # |
| 154 do_test walcksum-1.$endian.1 { | 154 do_test walcksum-1.$endian.1 { |
| 155 catch { db close } | 155 catch { db close } |
| 156 file delete -force test.db test.db-wal test.db-journal | 156 forcedelete test.db test.db-wal test.db-journal |
| 157 sqlite3 db test.db | 157 sqlite3 db test.db |
| 158 execsql { | 158 execsql { |
| 159 PRAGMA page_size = 1024; | 159 PRAGMA page_size = 1024; |
| 160 PRAGMA auto_vacuum = 0; | 160 PRAGMA auto_vacuum = 0; |
| 161 PRAGMA synchronous = NORMAL; | 161 PRAGMA synchronous = NORMAL; |
| 162 | 162 |
| 163 CREATE TABLE t1(a PRIMARY KEY, b); | 163 CREATE TABLE t1(a PRIMARY KEY, b); |
| 164 INSERT INTO t1 VALUES(1, 'one'); | 164 INSERT INTO t1 VALUES(1, 'one'); |
| 165 INSERT INTO t1 VALUES(2, 'two'); | 165 INSERT INTO t1 VALUES(2, 'two'); |
| 166 INSERT INTO t1 VALUES(3, 'three'); | 166 INSERT INTO t1 VALUES(3, 'three'); |
| 167 INSERT INTO t1 VALUES(5, 'five'); | 167 INSERT INTO t1 VALUES(5, 'five'); |
| 168 | 168 |
| 169 PRAGMA journal_mode = WAL; | 169 PRAGMA journal_mode = WAL; |
| 170 INSERT INTO t1 VALUES(8, 'eight'); | 170 INSERT INTO t1 VALUES(8, 'eight'); |
| 171 INSERT INTO t1 VALUES(13, 'thirteen'); | 171 INSERT INTO t1 VALUES(13, 'thirteen'); |
| 172 INSERT INTO t1 VALUES(21, 'twentyone'); | 172 INSERT INTO t1 VALUES(21, 'twentyone'); |
| 173 } | 173 } |
| 174 | 174 |
| 175 file copy -force test.db test2.db | 175 forcecopy test.db test2.db |
| 176 file copy -force test.db-wal test2.db-wal | 176 forcecopy test.db-wal test2.db-wal |
| 177 db close | 177 db close |
| 178 | 178 |
| 179 list [file size test2.db] [file size test2.db-wal] | 179 list [file size test2.db] [file size test2.db-wal] |
| 180 } [list [expr 1024*3] [wal_file_size 6 1024]] | 180 } [list [expr 1024*3] [wal_file_size 6 1024]] |
| 181 | 181 |
| 182 # Verify that the checksums are valid for all frames and that they | 182 # Verify that the checksums are valid for all frames and that they |
| 183 # are calculated by interpreting data in native byte-order. | 183 # are calculated by interpreting data in native byte-order. |
| 184 # | 184 # |
| 185 for {set f 1} {$f <= 6} {incr f} { | 185 for {set f 1} {$f <= 6} {incr f} { |
| 186 do_test walcksum-1.$endian.2.$f { | 186 do_test walcksum-1.$endian.2.$f { |
| 187 log_checksum_verify test2.db-wal $f $native | 187 log_checksum_verify test2.db-wal $f $native |
| 188 } 1 | 188 } 1 |
| 189 } | 189 } |
| 190 | 190 |
| 191 # Replace all checksums in the current WAL file with $endian versions. | 191 # Replace all checksums in the current WAL file with $endian versions. |
| 192 # Then check that it is still possible to recover and read the database. | 192 # Then check that it is still possible to recover and read the database. |
| 193 # | 193 # |
| 194 log_checksum_writemagic test2.db-wal $endian | 194 log_checksum_writemagic test2.db-wal $endian |
| 195 for {set f 1} {$f <= 6} {incr f} { | 195 for {set f 1} {$f <= 6} {incr f} { |
| 196 do_test walcksum-1.$endian.3.$f { | 196 do_test walcksum-1.$endian.3.$f { |
| 197 log_checksum_write test2.db-wal $f $endian | 197 log_checksum_write test2.db-wal $f $endian |
| 198 log_checksum_verify test2.db-wal $f $endian | 198 log_checksum_verify test2.db-wal $f $endian |
| 199 } {1} | 199 } {1} |
| 200 } | 200 } |
| 201 do_test walcksum-1.$endian.4.1 { | 201 do_test walcksum-1.$endian.4.1 { |
| 202 file copy -force test2.db test.db | 202 forcecopy test2.db test.db |
| 203 file copy -force test2.db-wal test.db-wal | 203 forcecopy test2.db-wal test.db-wal |
| 204 sqlite3 db test.db | 204 sqlite3 db test.db |
| 205 execsql { SELECT a FROM t1 } | 205 execsql { SELECT a FROM t1 } |
| 206 } {1 2 3 5 8 13 21} | 206 } {1 2 3 5 8 13 21} |
| 207 | 207 |
| 208 # Following recovery, any frames written to the log should use the same | 208 # Following recovery, any frames written to the log should use the same |
| 209 # endianness as the existing frames. Check that this is the case. | 209 # endianness as the existing frames. Check that this is the case. |
| 210 # | 210 # |
| 211 do_test walcksum-1.$endian.5.0 { | 211 do_test walcksum-1.$endian.5.0 { |
| 212 execsql { | 212 execsql { |
| 213 PRAGMA synchronous = NORMAL; | 213 PRAGMA synchronous = NORMAL; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 241 } [list [expr 1024*3] [wal_file_size 10 1024]] | 241 } [list [expr 1024*3] [wal_file_size 10 1024]] |
| 242 for {set f 1} {$f <= 10} {incr f} { | 242 for {set f 1} {$f <= 10} {incr f} { |
| 243 do_test walcksum-1.$endian.7.$f { | 243 do_test walcksum-1.$endian.7.$f { |
| 244 log_checksum_verify test.db-wal $f $endian | 244 log_checksum_verify test.db-wal $f $endian |
| 245 } {1} | 245 } {1} |
| 246 } | 246 } |
| 247 | 247 |
| 248 # Now that both the recoverer and non-recoverer have added frames to the | 248 # Now that both the recoverer and non-recoverer have added frames to the |
| 249 # log file, check that it can still be recovered. | 249 # log file, check that it can still be recovered. |
| 250 # | 250 # |
| 251 file copy -force test.db test2.db | 251 forcecopy test.db test2.db |
| 252 file copy -force test.db-wal test2.db-wal | 252 forcecopy test.db-wal test2.db-wal |
| 253 do_test walcksum-1.$endian.7.11 { | 253 do_test walcksum-1.$endian.7.11 { |
| 254 sqlite3 db3 test2.db | 254 sqlite3 db3 test2.db |
| 255 execsql { | 255 execsql { |
| 256 PRAGMA integrity_check; | 256 PRAGMA integrity_check; |
| 257 SELECT a FROM t1; | 257 SELECT a FROM t1; |
| 258 } db3 | 258 } db3 |
| 259 } {ok 1 2 3 5 8 13 21 34 55} | 259 } {ok 1 2 3 5 8 13 21 34 55} |
| 260 db3 close | 260 db3 close |
| 261 | 261 |
| 262 # Run a checkpoint on the database file. Then, check that any frames written | 262 # Run a checkpoint on the database file. Then, check that any frames written |
| (...skipping 24 matching lines...) Expand all Loading... |
| 287 catch { db2 close } | 287 catch { db2 close } |
| 288 } | 288 } |
| 289 | 289 |
| 290 #------------------------------------------------------------------------- | 290 #------------------------------------------------------------------------- |
| 291 # Test case walcksum-2.* tests that if a statement transaction is rolled | 291 # Test case walcksum-2.* tests that if a statement transaction is rolled |
| 292 # back after frames are written to the WAL, and then (after writing some | 292 # back after frames are written to the WAL, and then (after writing some |
| 293 # more) the outer transaction is committed, the WAL file is still correctly | 293 # more) the outer transaction is committed, the WAL file is still correctly |
| 294 # formatted (and can be recovered by a second process if required). | 294 # formatted (and can be recovered by a second process if required). |
| 295 # | 295 # |
| 296 do_test walcksum-2.1 { | 296 do_test walcksum-2.1 { |
| 297 file delete -force test.db test.db-wal test.db-journal | 297 forcedelete test.db test.db-wal test.db-journal |
| 298 sqlite3 db test.db | 298 sqlite3 db test.db |
| 299 execsql { | 299 execsql { |
| 300 PRAGMA synchronous = NORMAL; | 300 PRAGMA synchronous = NORMAL; |
| 301 PRAGMA page_size = 1024; | 301 PRAGMA page_size = 1024; |
| 302 PRAGMA journal_mode = WAL; | 302 PRAGMA journal_mode = WAL; |
| 303 PRAGMA cache_size = 10; | 303 PRAGMA cache_size = 10; |
| 304 CREATE TABLE t1(x PRIMARY KEY); | 304 CREATE TABLE t1(x PRIMARY KEY); |
| 305 PRAGMA wal_checkpoint; | 305 PRAGMA wal_checkpoint; |
| 306 INSERT INTO t1 VALUES(randomblob(800)); | 306 INSERT INTO t1 VALUES(randomblob(800)); |
| 307 BEGIN; | 307 BEGIN; |
| 308 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 2 */ | 308 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 2 */ |
| 309 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 4 */ | 309 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 4 */ |
| 310 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 8 */ | 310 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 8 */ |
| 311 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 16 */ | 311 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 16 */ |
| 312 SAVEPOINT one; | 312 SAVEPOINT one; |
| 313 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 32 */ | 313 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 32 */ |
| 314 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 64 */ | 314 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 64 */ |
| 315 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 128 */ | 315 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 128 */ |
| 316 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 256 */ | 316 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 256 */ |
| 317 ROLLBACK TO one; | 317 ROLLBACK TO one; |
| 318 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 32 */ | 318 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 32 */ |
| 319 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 64 */ | 319 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 64 */ |
| 320 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 128 */ | 320 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 128 */ |
| 321 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 256 */ | 321 INSERT INTO t1 SELECT randomblob(800) FROM t1; /* 256 */ |
| 322 COMMIT; | 322 COMMIT; |
| 323 } | 323 } |
| 324 | 324 |
| 325 file copy -force test.db test2.db | 325 forcecopy test.db test2.db |
| 326 file copy -force test.db-wal test2.db-wal | 326 forcecopy test.db-wal test2.db-wal |
| 327 | 327 |
| 328 sqlite3 db2 test2.db | 328 sqlite3 db2 test2.db |
| 329 execsql { | 329 execsql { |
| 330 PRAGMA integrity_check; | 330 PRAGMA integrity_check; |
| 331 SELECT count(*) FROM t1; | 331 SELECT count(*) FROM t1; |
| 332 } db2 | 332 } db2 |
| 333 } {ok 256} | 333 } {ok 256} |
| 334 catch { db close } | 334 catch { db close } |
| 335 catch { db2 close } | 335 catch { db2 close } |
| 336 | 336 |
| 337 #------------------------------------------------------------------------- | 337 #------------------------------------------------------------------------- |
| 338 # Test case walcksum-3.* tests that the checksum calculation detects single | 338 # Test case walcksum-3.* tests that the checksum calculation detects single |
| 339 # byte changes to frame or frame-header data and considers the frame | 339 # byte changes to frame or frame-header data and considers the frame |
| 340 # invalid as a result. | 340 # invalid as a result. |
| 341 # | 341 # |
| 342 do_test walcksum-3.1 { | 342 do_test walcksum-3.1 { |
| 343 file delete -force test.db test.db-wal test.db-journal | 343 forcedelete test.db test.db-wal test.db-journal |
| 344 sqlite3 db test.db | 344 sqlite3 db test.db |
| 345 | 345 |
| 346 execsql { | 346 execsql { |
| 347 PRAGMA synchronous = NORMAL; | 347 PRAGMA synchronous = NORMAL; |
| 348 PRAGMA page_size = 1024; | 348 PRAGMA page_size = 1024; |
| 349 CREATE TABLE t1(a, b); | 349 CREATE TABLE t1(a, b); |
| 350 INSERT INTO t1 VALUES(1, randomblob(300)); | 350 INSERT INTO t1 VALUES(1, randomblob(300)); |
| 351 INSERT INTO t1 VALUES(2, randomblob(300)); | 351 INSERT INTO t1 VALUES(2, randomblob(300)); |
| 352 PRAGMA journal_mode = WAL; | 352 PRAGMA journal_mode = WAL; |
| 353 INSERT INTO t1 VALUES(3, randomblob(300)); | 353 INSERT INTO t1 VALUES(3, randomblob(300)); |
| 354 } | 354 } |
| 355 | 355 |
| 356 file size test.db-wal | 356 file size test.db-wal |
| 357 } [wal_file_size 1 1024] | 357 } [wal_file_size 1 1024] |
| 358 do_test walcksum-3.2 { | 358 do_test walcksum-3.2 { |
| 359 file copy -force test.db-wal test2.db-wal | 359 forcecopy test.db-wal test2.db-wal |
| 360 file copy -force test.db test2.db | 360 forcecopy test.db test2.db |
| 361 sqlite3 db2 test2.db | 361 sqlite3 db2 test2.db |
| 362 execsql { SELECT a FROM t1 } db2 | 362 execsql { SELECT a FROM t1 } db2 |
| 363 } {1 2 3} | 363 } {1 2 3} |
| 364 db2 close | 364 db2 close |
| 365 file copy -force test.db test2.db | 365 forcecopy test.db test2.db |
| 366 | 366 |
| 367 | 367 |
| 368 foreach incr {1 2 3 20 40 60 80 100 120 140 160 180 200 220 240 253 254 255} { | 368 foreach incr {1 2 3 20 40 60 80 100 120 140 160 180 200 220 240 253 254 255} { |
| 369 do_test walcksum-3.3.$incr { | 369 do_test walcksum-3.3.$incr { |
| 370 set FAIL 0 | 370 set FAIL 0 |
| 371 for {set iOff 0} {$iOff < [wal_file_size 1 1024]} {incr iOff} { | 371 for {set iOff 0} {$iOff < [wal_file_size 1 1024]} {incr iOff} { |
| 372 | 372 |
| 373 file copy -force test.db-wal test2.db-wal | 373 forcecopy test.db-wal test2.db-wal |
| 374 set fd [open test2.db-wal r+] | 374 set fd [open test2.db-wal r+] |
| 375 fconfigure $fd -encoding binary | 375 fconfigure $fd -encoding binary |
| 376 fconfigure $fd -translation binary | 376 fconfigure $fd -translation binary |
| 377 | 377 |
| 378 seek $fd $iOff | 378 seek $fd $iOff |
| 379 binary scan [read $fd 1] c x | 379 binary scan [read $fd 1] c x |
| 380 seek $fd $iOff | 380 seek $fd $iOff |
| 381 puts -nonewline $fd [binary format c [expr {($x+$incr)&0xFF}]] | 381 puts -nonewline $fd [binary format c [expr {($x+$incr)&0xFF}]] |
| 382 close $fd | 382 close $fd |
| 383 | 383 |
| 384 sqlite3 db2 test2.db | 384 sqlite3 db2 test2.db |
| 385 if { [execsql { SELECT a FROM t1 } db2] != "1 2" } {set FAIL 1} | 385 if { [execsql { SELECT a FROM t1 } db2] != "1 2" } {set FAIL 1} |
| 386 db2 close | 386 db2 close |
| 387 } | 387 } |
| 388 set FAIL | 388 set FAIL |
| 389 } {0} | 389 } {0} |
| 390 } | 390 } |
| 391 | 391 |
| 392 finish_test | 392 finish_test |
| 393 | |
| OLD | NEW |