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 |