diff --git a/manifest b/manifest index 1f70a29a67..564725623d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sproblem\sin\stest_vfs.c. -D 2010-06-03T19:10:09 +C Fix\sa\sproblem\swhere\san\sSQLITE_BUSY\sin\sthe\scheckpoint\scode\swas\sbeing\streated\sas\san\sIO\serror\s(abandoning,\sinstead\sof\sjust\slimiting,\sthe\scheckpoint). +D 2010-06-04T10:37:06 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -207,7 +207,7 @@ F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c aa9919c885a1fe53eafc73492f0898ee6c0a0726 -F src/test_vfs.c 0f0242f29584537845cf0e0dfc04ece0b357b857 +F src/test_vfs.c 6203bc7d88a95a093ceb2c372252317b3154b315 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb F src/trigger.c 8927588cb9e6d47f933b53bfe74200fbb504100d @@ -224,7 +224,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 be73c9a8a3027a7bba1229dc09890927b992da45 +F src/wal.c 453811af926fe12eacea41b4ea02ee1a2d2f004b F src/wal.h 4ace25262452d17e7d3ec970c89ee17794004008 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 75fee9e255b62f773fcadd1d1f25b6f63ac7a356 @@ -763,13 +763,13 @@ F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d F test/wal.test bfec61450b47cdf09f7d2269f9e9967683b8b0fc F test/wal2.test 1dcbbe59ab662bebb859bb1ede83143f8a39814e -F test/wal3.test cac89168c8f8a8679f1fb5234624d5699a84b2f0 +F test/wal3.test 535867201f4e5eccc459dbfdbb43e1b9555fd30a F test/wal_common.tcl 3e953ae60919281688ea73e4d0aa0e1bc94becd9 F test/walbak.test e7650a26eb4b8abeca9b145b1af1e63026dde432 F test/walcksum.test 4efa8fb88c32bed8288ea4385a9cc113a5c8f0bf F test/walcrash.test f6d5fb2bb108876f04848720a488065d9deef69f F test/walcrash2.test 14585ad1a2c85da2de721caa3b4deeea55213008 -F test/walfault.test 0cd672eb059d98ef07714f64371fd7d4d1ebb642 +F test/walfault.test 4c412eae947aea5f58d5c616a4d8740f034e49d1 F test/walhook.test 67e675127f4acb72f061a12667ce6e5460b06b78 F test/walmode.test 6ca9d710cc9f6545b913abcded6d6b0b15641048 F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933 @@ -817,7 +817,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P fcbf7cf189506e43fc2f0820aedffb195038d3a9 -R e093d2af0534cd33e5ed13655be56b08 +P df7d59899ceb2743764b0433cb68f4bc33f16344 +R 1a3cb251079fbc88fab0e8991c692f47 U dan -Z e9eec85577950a5d26e2b23744407a2d +Z 13abdffaf01f3e682d39faa8c6e78666 diff --git a/manifest.uuid b/manifest.uuid index 43d840249c..d2362e35a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -df7d59899ceb2743764b0433cb68f4bc33f16344 \ No newline at end of file +02c4040ce2b4c970b3dee09f7c9ad5a2a3a9aa49 \ No newline at end of file diff --git a/src/test_vfs.c b/src/test_vfs.c index 1beeef47c8..05fa0096a5 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -596,7 +596,8 @@ static int tvfsShmGet( if( p->pScript && p->mask&TESTVFS_SHMGET_MASK ){ tvfsExecTcl(p, "xShmGet", - Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0 + Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, + Tcl_NewIntObj(reqMapSize) ); tvfsResultCode(p, &rc); } diff --git a/src/wal.c b/src/wal.c index 25175d966a..5399dfda95 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1299,14 +1299,10 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){ int i; /* Iterator variable */ int nFinal; /* Number of unindexed entries */ u8 *aTmp; /* Temp space used by merge-sort */ - int rc; /* Return code of walIndexMap() */ u8 *aSpace; /* Surplus space on the end of the allocation */ /* Make sure the wal-index is mapped into local memory */ - rc = walIndexMap(pWal, walMappingSize(pWal->hdr.mxFrame)); - if( rc!=SQLITE_OK ){ - return rc; - } + assert( pWal->pWiData && pWal->szWIndex>=walMappingSize(pWal->hdr.mxFrame) ); /* This routine only runs while holding SQLITE_SHM_CHECKPOINT. No other ** thread is able to write to shared memory while this routine is @@ -1360,7 +1356,6 @@ static void walIteratorFree(WalIterator *p){ sqlite3_free(p); } - /* ** Copy as much content as we can from the WAL back into the database file ** in response to an sqlite3_wal_checkpoint() request or the equivalent. @@ -1411,14 +1406,13 @@ static int walCheckpoint( /* Allocate the iterator */ rc = walIteratorInit(pWal, &pIter); if( rc!=SQLITE_OK || pWal->hdr.mxFrame==0 ){ - walIteratorFree(pIter); - return rc; + goto walcheckpoint_out; } /*** TODO: Move this test out to the caller. Make it an assert() here ***/ if( pWal->hdr.szPage!=nBuf ){ - walIteratorFree(pIter); - return SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_BKPT; + goto walcheckpoint_out; } /* Compute in mxSafeFrame the index of the last frame of the WAL that is @@ -1432,17 +1426,16 @@ static int walCheckpoint( assert( pInfo==walCkptInfo(pWal) ); for(i=1; iaReadMark[i]; - if( y>0 && (mxSafeFrame==0 || mxSafeFrame>=y) ){ - if( y<=pWal->hdr.mxFrame - && walLockExclusive(pWal, WAL_READ_LOCK(i), 1)==SQLITE_OK - ){ + if( y>0 && mxSafeFrame>=y ){ + assert( y<=pWal->hdr.mxFrame ); + rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); + if( rc==SQLITE_OK ){ pInfo->aReadMark[i] = 0; walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); }else if( rc==SQLITE_BUSY ){ mxSafeFrame = y-1; }else{ - walIteratorFree(pIter); - return rc; + goto walcheckpoint_out; } } } @@ -1488,6 +1481,7 @@ static int walCheckpoint( rc = SQLITE_OK; } + walcheckpoint_out: walIteratorFree(pIter); return rc; } diff --git a/test/wal3.test b/test/wal3.test index 2d2d8b39cb..3ddfeaea6a 100644 --- a/test/wal3.test +++ b/test/wal3.test @@ -109,5 +109,88 @@ for {set i 1} {$i < 20} {incr i} { db2 close } +db close +foreach code [list { + proc code2 {tcl} { uplevel #0 $tcl } + proc code3 {tcl} { uplevel #0 $tcl } + set tn singleproc +} { + set ::code2_chan [launch_testfixture] + set ::code3_chan [launch_testfixture] + proc code2 {tcl} { testfixture $::code2_chan $tcl } + proc code3 {tcl} { testfixture $::code3_chan $tcl } + set tn multiproc +}] { + file delete -force test.db test.db-wal test.db-journal + sqlite3 db test.db + eval $code + + # Open connections [db2] and [db3]. Depending on which iteration this + # is, the connections may be created in this interpreter, or in + # interpreters running in other OS processes. As such, the [db2] and [db3] + # commands should only be accessed within [code2] and [code3] blocks, + # respectively. + # + code2 { sqlite3 db2 test.db ; db2 eval { PRAGMA journal_mode = WAL } } + code3 { sqlite3 db3 test.db ; db3 eval { PRAGMA journal_mode = WAL } } + + # Shorthand commands. Execute SQL using database connection [db], [db2] + # or [db3]. Return the results. + # + proc sql {sql} { db eval $sql } + proc sql2 {sql} { code2 [list db2 eval $sql] } + proc sql3 {sql} { code3 [list db3 eval $sql] } + + do_test wal3-2.$tn.1 { + sql { + PRAGMA page_size = 1024; + PRAGMA auto_vacuum = OFF; + PRAGMA journal_mode = WAL; + } + sql { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 'one'); + BEGIN; + SELECT * FROM t1; + } + } {1 one} + do_test wal3-2.$tn.2 { + sql2 { + CREATE TABLE t2(a, b); + INSERT INTO t2 VALUES(2, 'two'); + BEGIN; + SELECT * FROM t2; + } + } {2 two} + do_test wal3-2.$tn.3 { + sql3 { + CREATE TABLE t3(a, b); + INSERT INTO t3 VALUES(3, 'three'); + BEGIN; + SELECT * FROM t3; + } + } {3 three} + + # Try to checkpoint the database using [db]. It should be possible to + # checkpoint everything except the frames added by [db3] (checkpointing + # these frames would clobber the snapshot currently being used by [db2]). + # + do_test wal3-2.$tn.4 { + sql { + COMMIT; + PRAGMA wal_checkpoint; + } + } {} + do_test wal3-2.$tn.5 { + file size test.db + } [expr 3*1024] + + + catch { db close } + catch { code2 { db2 close } } + catch { code3 { db3 close } } + catch { close $::code2_chan } + catch { close $::code3_chan } +} finish_test diff --git a/test/walfault.test b/test/walfault.test index 28be17e52d..a0552021e1 100644 --- a/test/walfault.test +++ b/test/walfault.test @@ -16,6 +16,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl +source $testdir/lock_common.tcl ifcapable !wal {finish_test ; return } @@ -321,82 +322,5 @@ do_faultsim_test walfault-9 -prep { if {$n != 1 && $n != 2} { error "Incorrect number of rows: $n" } } -#------------------------------------------------------------------------- -# When a database is checkpointed, SQLite does the following: -# -# 1. xShmLock(CHECKPOINT) to lock the WAL. -# 2. xShmGet(-1) to get a mapping to read the wal-index header. -# 3. If the mapping obtained in (2) is not large enough to cover the -# entire wal-index, call xShmGet(nReq) to get a larger mapping. -# 4. Do the checkpoint. -# 5. Release the lock and mapping. -# -# This test case tests the outcome of an IO error in step 2. -# -proc walfault_10_vfs_cb {method args} { - switch -- $::shm_state { - 0 { return SQLITE_OK } - 1 { - if {$method == "xShmGet"} { - set ::wal_index [tvfs shm [lindex $args 0]] - tvfs shm [lindex $args 0] [string range $::wal_index 0 65535] - set ::shm_state 2 - } - } - 2 { - if {$method == "xShmGet"} { - tvfs shm [lindex $args 0] $::wal_index - return SQLITE_IOERR - } - } - } - return SQLITE_OK -} -do_test walfault-10.1 { - set ::shm_state 0 - testvfs tvfs - tvfs script walfault_10_vfs_cb - - sqlite3 db test.db -vfs tvfs - sqlite3 db2 test.db -vfs tvfs - - execsql { - PRAGMA journal_mode = WAL; - PRAGMA wal_autocheckpoint = 0; - CREATE TABLE t1(x); - INSERT INTO t1 VALUES(randomblob(900)); - } -} {wal 0} -do_test walfault-10.2 { - execsql { - PRAGMA wal_autocheckpoint = 0; - BEGIN; - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 2 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 4 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 8 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 16 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 32 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 64 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 128 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 256 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 512 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 1024 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 2048 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 4096 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 8192 */ - INSERT INTO t1 SELECT randomblob(900) FROM t1; /* 16384 */ - COMMIT; - } db2 -} {0} -do_test walfault-10.3 { - set ::shm_state 1 - catchsql { PRAGMA wal_checkpoint } db2 -} {1 {disk I/O error}} -set ::shm_state 0 -db close -db2 close -tvfs delete -unset -nocomplain ::wal_index ::shm_state - finish_test