From: dan Date: Tue, 4 May 2010 10:36:20 +0000 (+0000) Subject: Test that the correct number of padding frames are appended to the log file after... X-Git-Tag: version-3.7.2~443 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8d6ad1cc2c4ae5cdc54304891f7ac5ab6d1d4fd1;p=thirdparty%2Fsqlite.git Test that the correct number of padding frames are appended to the log file after committing a transaction in synchronous=FULL mode. FossilOrigin-Name: a60104aa7e38e7d9f2ff2eae02687dc9c5dd5d77 --- diff --git a/manifest b/manifest index ba3ac27d74..04028d8859 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Unset\ssome\sglobal\sTCL\svariables\sprior\sto\suse\sin\stest\swhere\sprior\stests\scan\nhave\sthose\ssame\svariables\sset\sto\san\sarray\svalue. -D 2010-05-03T19:20:47 +C Test\sthat\sthe\scorrect\snumber\sof\spadding\sframes\sare\sappended\sto\sthe\slog\sfile\safter\scommitting\sa\stransaction\sin\ssynchronous=FULL\smode. +D 2010-05-04T10:36:21 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in d83a0ffef3dcbfb08b410a6c6dd6c009ec9167fb F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -177,7 +174,7 @@ F src/status.c 4df6fe7dce2d256130b905847c6c60055882bdbe F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c 4de81521174fedacd8393ea7b70b730ce17f8eae F src/test1.c ff95ca772d1df51618f9f1ef7ea432cdf851f97b -F src/test2.c b6b43413d495addd039a88b87d65c839f86b18cb +F src/test2.c 31f1b9d076b4774a22d2605d0af1f34e14a9a7bd F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94 F src/test4.c ad03bb987ddedce928f4258c1e7fa4109a73497d F src/test5.c cc55900118fa4add8ec9cf69fc4225a4662f76b1 @@ -224,7 +221,7 @@ F src/vdbeblob.c 5327132a42a91e8b7acfb60b9d2c3b1c5c863e0e F src/vdbemem.c 2a82f455f6ca6f78b59fb312f96054c04ae0ead1 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2 F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda -F src/wal.c f2dd17d7edecf300a170ce1ef96a14e7edd74686 +F src/wal.c fcd2c4ce4a7d44928763966c2199e0de800fae89 F src/wal.h d6d4a6809151e30bed5b01dd05cf27858f5a7bc8 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 75fee9e255b62f773fcadd1d1f25b6f63ac7a356 @@ -761,7 +758,7 @@ F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61 F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d -F test/wal.test 0223196f4311a504b0127746613c4434054f7968 +F test/wal.test 511c630993d5adc170f56e581909b6eb580b0f53 F test/walbak.test a0e45187c7d8928df035dfea29b99b016b21ca3c F test/walcrash.test 63edc6a9e05f645b54d649186a5818fc82953e2e F test/walfault.test cdd1a27ed89bcb14596005ab2477b3724dd5f805 @@ -812,14 +809,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e7ded46b5efabe521008d9043dd72bd1ca748316 -R 743eb58d4aa3ebab274cf42a45b64c62 -U drh -Z 52a27cb9451578dbe5d554c4411d8300 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFL3yIToxKgR168RlERAngrAJwPIAkaDM8Usma0OrWE695X+1LPGgCdEAoZ -GermSXszjhToHNBo5iA+oE8= -=sr8r ------END PGP SIGNATURE----- +P 49bef00e5cda600ceb964148bf745de4aff1ab62 +R 44e8b17dd54df12e28ab0c945b738027 +U dan +Z dab97771a4b803a69cb81f43590ea234 diff --git a/manifest.uuid b/manifest.uuid index d25f2ed7c8..f380d2b82d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49bef00e5cda600ceb964148bf745de4aff1ab62 \ No newline at end of file +a60104aa7e38e7d9f2ff2eae02687dc9c5dd5d77 \ No newline at end of file diff --git a/src/test2.c b/src/test2.c index 13d36e7e95..994bc1a776 100644 --- a/src/test2.c +++ b/src/test2.c @@ -581,6 +581,7 @@ static int testPendingByte( if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PENDING-BYTE\"", (void*)0); + return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], &pbyte) ) return TCL_ERROR; rc = sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, pbyte); diff --git a/src/wal.c b/src/wal.c index 44c1026c40..04a30dedda 100644 --- a/src/wal.c +++ b/src/wal.c @@ -914,12 +914,12 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ ** or not any cached pages may be safely reused. */ int sqlite3WalOpenSnapshot(Wal *pWal, int *pChanged){ - int rc; + int rc; /* Return code */ rc = walSetLock(pWal, SQLITE_SHM_READ); - if( rc==SQLITE_OK ){ - pWal->lockState = SQLITE_SHM_READ; + assert( rc!=SQLITE_OK || pWal->lockState==SQLITE_SHM_READ ); + if( rc==SQLITE_OK ){ rc = walIndexReadHdr(pWal, pChanged); if( rc!=SQLITE_OK ){ /* An error occured while attempting log recovery. */ @@ -942,10 +942,10 @@ int sqlite3WalOpenSnapshot(Wal *pWal, int *pChanged){ ** Unlock the current snapshot. */ void sqlite3WalCloseSnapshot(Wal *pWal){ - if( pWal->lockState!=SQLITE_SHM_UNLOCK ){ - assert( pWal->lockState==SQLITE_SHM_READ ); - walSetLock(pWal, SQLITE_SHM_UNLOCK); - } + assert( pWal->lockState==SQLITE_SHM_READ + || pWal->lockState==SQLITE_SHM_UNLOCK + ); + walSetLock(pWal, SQLITE_SHM_UNLOCK); } /* diff --git a/test/wal.test b/test/wal.test index 1667f22f3f..344f0bafed 100644 --- a/test/wal.test +++ b/test/wal.test @@ -850,6 +850,28 @@ db close #------------------------------------------------------------------------- # Test large log summaries. # +# In this case "large" usually means a log file that requires a wal-index +# mapping larger than 64KB (the default initial allocation). A 64KB wal-index +# is large enough for a log file that contains approximately 13100 frames. +# So the following tests create logs containing at least this many frames. +# +# wal-13.1.*: This test case creates a very large log file within the +# file-system (around 200MB). The log file does not contain +# any valid frames. Test that the database file can still be +# opened and queried, and that the invalid log file causes no +# problems. +# +# wal-13.2.*: Test that a process may create a large log file and query +# the database (including the log file that it itself created). +# +# wal-13.3.*: Test that if a very large log file is created, and then a +# second connection is opened on the database file, it is possible +# to query the database (and the very large log) using the +# second connection. +# +# wal-13.4.*: Same test as wal-13.3.*. Except in this case the second +# connection is opened by an external process. +# do_test wal-13.1.1 { list [file exists test.db] [file exists test.db-wal] } {1 0} @@ -865,25 +887,26 @@ do_test wal-13.1.3 { db close file exists test.db-wal } {0} -do_test wal-13.1.4 { + +do_test wal-13.2.1 { sqlite3 db test.db execsql { SELECT count(*) FROM t2 } } {1} -do_test wal-13.1.5 { - for {set i 0} {$i < 6} {incr i} { +do_test wal-13.2.2 { + for {set i 0} {$i < 16} {incr i} { execsql { INSERT INTO t2 SELECT randomblob(400), randomblob(400) FROM t2 } } execsql { SELECT count(*) FROM t2 } -} [expr int(pow(2, 6))] -do_test wal-13.1.6 { +} [expr int(pow(2, 16))] +do_test wal-13.2.1 { file size test.db-wal -} [log_file_size 80 1024] +} [log_file_size 33123 1024] foreach code [list { - set tn 2 + set tn 3 proc buddy {tcl} { uplevel #0 $tcl } } { - set tn 3 + set tn 4 set ::buddy [launch_testfixture] proc buddy {tcl} { testfixture $::buddy $tcl } }] { @@ -896,14 +919,14 @@ foreach code [list { execsql { PRAGMA journal_mode = WAL; CREATE TABLE t1(x); - INSERT INTO t1 SELECT randomblob(400); + INSERT INTO t1 SELECT randomblob(800); } execsql { SELECT count(*) FROM t1 } } {1} for {set ii 1} {$ii<16} {incr ii} { do_test wal-13.$tn.$ii.a { - buddy { db2 eval { INSERT INTO t1 SELECT randomblob(400) FROM t1 } } + buddy { db2 eval { INSERT INTO t1 SELECT randomblob(800) FROM t1 } } buddy { db2 eval { SELECT count(*) FROM t1 } } } [expr (1<<$ii)] do_test wal-13.$tn.$ii.b { @@ -930,14 +953,12 @@ foreach code [list { # used it did not realize the cache was out-of-date and proceeded to # operate with an inconsistent cache. Leading to corruption. # - catch { db close } catch { db2 close } catch { db3 close } file delete -force test.db test.db-wal sqlite3 db test.db sqlite3 db2 test.db - do_test wal-14 { execsql { PRAGMA journal_mode = WAL; @@ -1108,6 +1129,70 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} { catch { db close } } +#------------------------------------------------------------------------- +# The following tests - wal-17.* - attempt to verify that the correct +# number of "padding" frames are appended to the log file when a transaction +# is committed in synchronous=FULL mode. +# +# Do this by creating a database that uses 512 byte pages. Then writing +# a transaction that modifies 171 pages. In synchronous=NORMAL mode, this +# produces a log file of: +# +# 12 + (16+512)*171 = 90300 bytes. +# +# Slightly larger than 11*8192 = 90112 bytes. +# +# Run the test using various different sector-sizes. In each case, the +# WAL code should write the 90300 bytes of log file containing the +# transaction, then append as may frames as are required to extend the +# log file so that no part of the next transaction will be written into +# a disk-sector used by transaction just committed. +# +set old_pending_byte [sqlite3_test_control_pending_byte 0x10000000] +catch { db close } +foreach {tn sectorsize logsize} { + 1 128 90828 + 2 256 90828 + 3 512 90828 + 4 1024 91356 + 5 2048 92412 + 6 4096 94524 + 7 8192 98748 +} { + file delete -force test.db test.db-wal test.db-journal + sqlite3_simulate_device -sectorsize $sectorsize + sqlite3 db test.db -vfs devsym + + do_test wal-17.$tn.1 { + execsql { + PRAGMA auto_vacuum = 0; + PRAGMA page_size = 512; + PRAGMA journal_mode = WAL; + PRAGMA synchronous = FULL; + } + execsql { + BEGIN; + CREATE TABLE t(x); + } + for {set i 0} {$i<166} {incr i} { + execsql { INSERT INTO t VALUES(randomblob(400)) } + } + execsql COMMIT + + file size test.db-wal + } $logsize + + do_test wal-17.$tn.2 { + file size test.db + } 512 + + do_test wal-17.$tn.3 { + db close + file size test.db + } [expr 512*171] +} +sqlite3_test_control_pending_byte $old_pending_byte + catch { db2 close } catch { db close } finish_test