From b9780027438f426ca2d9650a1305fe6811c6f57e Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Apr 2010 18:37:57 +0000 Subject: [PATCH] Tests for (and changes to) the code to switch between WAL and rollback modes. FossilOrigin-Name: 9f4f933f2c6596064fcfc7fb5add87e8c5b57448 --- manifest | 24 +++++++-------- manifest.uuid | 2 +- src/btree.c | 25 ++++++++++++---- src/btreeInt.h | 1 + src/log.c | 1 - src/pager.c | 27 +++++------------ src/vdbe.c | 5 +--- test/wal.test | 6 ++-- test/walmode.test | 76 +++++++++++++++++++++++++++++++++++++++++++++-- 9 files changed, 117 insertions(+), 50 deletions(-) diff --git a/manifest b/manifest index 324d0ff215..8f9be85819 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If,\safter\sobtaining\sa\sSHARED\slock,\sthere\sexists\sa\s*-wal\sfile\sin\sthe\sfile-system,\suse\sWAL\smode.\sThis\sis\snecessary\sto\srecover\sfrom\sa\scrash\sthat\sdamages\sthe\sfirst\spage\sof\sthe\sdatabase\sfile. -D 2010-04-21T11:43:38 +C Tests\sfor\s(and\schanges\sto)\sthe\scode\sto\sswitch\sbetween\sWAL\sand\srollback\smodes. +D 2010-04-21T18:37:57 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -109,9 +109,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c e86634da8c48357a759694c9c7c471125cd8d5a8 F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0 F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff -F src/btree.c e6ef1020c35db638f9ebbc91b77bc6493d9be2a1 +F src/btree.c fcfff21fb259fc5f09d8ae65478c3240553f4cd9 F src/btree.h dd83041eda10c17daf023257c1fc883b5f71f85a -F src/btreeInt.h 22447d259639271774a931cbf66aa55112846681 +F src/btreeInt.h b0c87f6725b06a0aa194a6d25d54b16ce9d6e291 F src/build.c 11100b66fb97638d2d874c1d34d8db90650bb1d7 F src/callback.c 908f3e0172c3d4058f4ca0acd42c637c52e9669f F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac @@ -131,7 +131,7 @@ F src/journal.c b0ea6b70b532961118ab70301c00a33089f9315c F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 1c7a61ce1281041f437333f366a96aa0d29bb581 -F src/log.c a5bbeb05c456ee7ee9d4f3dba5e72bae2d9b6530 +F src/log.c edafa806982a281205e71c439e99766e924de938 F src/log.h b8c45a6348d9ef57c5205a08c611d57d07ee9feb F src/main.c 867de6aa444abd97771b2b70472f448d65c1c77e F src/malloc.c a08f16d134f0bfab6b20c3cd142ebf3e58235a6a @@ -154,7 +154,7 @@ F src/os_common.h 240c88b163b02c21a9f21f87d49678a0aa21ff30 F src/os_os2.c 75a8c7b9a00a2cf1a65f9fa4afbc27d46634bb2f F src/os_unix.c 5bf0015cebe2f21635da2af983c348eb88b3b4c1 F src/os_win.c 1c7453c2df4dab26d90ff6f91272aea18bcf7053 -F src/pager.c 4ff50f4e72ca7fff6c1e40e67db78377a53879fe +F src/pager.c f20f9090456b2f4aa3c5174e390a3cfd61bd3cc1 F src/pager.h cee4487ab4f0911dd9f22a40e3cd55afdb7ef444 F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e F src/pcache.c ace8f6a5ecd4711cc66a1b23053be7109bd437cf @@ -214,7 +214,7 @@ F src/update.c c0dc6b75ad28b76b619042d934f337b02acee208 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c 32aebf04c10e51ad3977a928b7416bed671b620b F src/vacuum.c b1d542c8919d4d11119f78069e1906a1ad07e0ee -F src/vdbe.c 304851b32c5f918a7ce92e4e9f94fbde0b604b21 +F src/vdbe.c 4d99d175264ef5b2ac57b19396f2b78199539e22 F src/vdbe.h 471f6a3dcec4817ca33596fe7f6654d56c0e75f3 F src/vdbeInt.h 19ebc8c2a2e938340051ee65af3f377fb99102d1 F src/vdbeapi.c 466044df5bc916f778833e927165fd02cdef6086 @@ -758,10 +758,10 @@ 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 9ee4025785972fa509250c1f20c5b9456472a789 +F test/wal.test fd0e5914599b205172dae33c765368a75feb2462 F test/walcrash.test f022cee7eb7baa5fb898726120a6a4073dd831d1 F test/walhook.test 76a559e262f0715c470bade4a8d8333035f8ee47 -F test/walmode.test cd6ee20f08af2d81fddc049f8d7e387a807f067e +F test/walmode.test 004da14c0d6be8314bba076d2d89c16458b6f849 F test/walslow.test 38076d5fad49e3678027be0f8110e6a32d531dc2 F test/walthread.test 27e44ee6fd02f1f494a24f999c97086af3ab739d F test/where.test de337a3fe0a459ec7c93db16a519657a90552330 @@ -807,7 +807,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 278ed41e1d4bbff9544cb2cf4cf52dbbcf0c17df -R aeea7589488764dd7471605e974b33ab +P 33cabf271b8f4dda508a610bf59964273fe2cb84 +R ce8d5df20a1a383d4fb608ef1b16a4c8 U dan -Z eeb703c307b6c73f6f34fd39a65a4afd +Z 9951e081ef8379216185ea5ef99b745d diff --git a/manifest.uuid b/manifest.uuid index f51f56c3a0..8514b695f3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -33cabf271b8f4dda508a610bf59964273fe2cb84 \ No newline at end of file +9f4f933f2c6596064fcfc7fb5add87e8c5b57448 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 2c387ffabf..71de1ef681 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2276,7 +2276,7 @@ static int lockBtree(BtShared *pBt){ ** may not be the latest version - there may be a newer one in the log ** file. */ - if( page1[19]==2 ){ + if( page1[19]==2 && pBt->doNotUseWAL==0 ){ int isOpen = 0; rc = sqlite3PagerOpenLog(pBt->pPager, &isOpen); if( rc!=SQLITE_OK ){ @@ -7992,16 +7992,29 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ BtShared *pBt = pBtree->pBt; int rc; /* Return code */ - assert( pBtree->inTrans==TRANS_WRITE ); - assert( pBt->pPage1 ); + assert( pBtree->inTrans==TRANS_NONE ); assert( iVersion==1 || iVersion==2 ); - rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + /* If setting the version fields to 1, do not automatically open the + ** WAL connection, even if the version fields are currently set to 2. + */ + pBt->doNotUseWAL = (iVersion==1); + + rc = sqlite3BtreeBeginTrans(pBtree, 0); if( rc==SQLITE_OK ){ u8 *aData = pBt->pPage1->aData; - aData[18] = (u8)iVersion; - aData[19] = (u8)iVersion; + if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ + rc = sqlite3BtreeBeginTrans(pBtree, 1); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==SQLITE_OK ){ + aData[18] = (u8)iVersion; + aData[19] = (u8)iVersion; + } + } + } } + pBt->doNotUseWAL = 0; return rc; } diff --git a/src/btreeInt.h b/src/btreeInt.h index cd40713ead..8b68d7b316 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -420,6 +420,7 @@ struct BtShared { u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */ u16 minLeaf; /* Minimum local payload in a LEAFDATA table */ u8 inTransaction; /* Transaction state */ + u8 doNotUseWAL; /* If true, do not open write-ahead-log file */ int nTransaction; /* Number of open transactions (read + write) */ u32 nPage; /* Number of pages in the database */ void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ diff --git a/src/log.c b/src/log.c index 67029d3f8e..89b60568b5 100644 --- a/src/log.c +++ b/src/log.c @@ -1235,7 +1235,6 @@ int sqlite3LogClose( } logSummaryUnmap(pSummary, 0); } - sqlite3OsUnlock(pFd, SQLITE_LOCK_NONE); sqlite3_mutex_free(pSummary->mutex); sqlite3_free(pSummary); diff --git a/src/pager.c b/src/pager.c index 48e67fdb03..7e96049d3b 100644 --- a/src/pager.c +++ b/src/pager.c @@ -491,17 +491,6 @@ static int assert_pager_state(Pager *pPager){ } #endif -#ifndef NDEBUG -static void assert_file_lock(Pager *pPager, int eLock){ - int locktype; - sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCKSTATE, &locktype); - assert( locktype==eLock ); -} -#else -# define assert_file_lock(x,y) -#endif - - /* ** Return true if it is necessary to write page *pPg into the sub-journal. ** A page needs to be written into the sub-journal if there exists one @@ -3008,10 +2997,10 @@ static int syncJournal(Pager *pPager){ */ i64 iNextHdrOffset; u8 aMagic[8]; - u8 zHeader[sizeof(aJournalMagic)+4]; + u8 zHeader[sizeof(aJournalMagic)+4]; - memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); - put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); iNextHdrOffset = journalHdrOffset(pPager); rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset); @@ -3043,7 +3032,7 @@ static int syncJournal(Pager *pPager){ IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr)); rc = sqlite3OsWrite( pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr - ); + ); if( rc!=SQLITE_OK ) return rc; } if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ @@ -3753,7 +3742,7 @@ static int pagerHasWAL(Pager *pPager, int *pExists){ ** ensures there is no race condition between the xAccess() below and ** an xDelete() being executed by some other connection. */ - assert_file_lock(pPager, SQLITE_LOCK_SHARED); + assert( pPager->state>=PAGER_SHARED ); if( !pPager->tempFile ){ char *zLog = sqlite3_mprintf("%s-wal", pPager->zFilename); @@ -5736,7 +5725,7 @@ int sqlite3PagerLogCallback(Pager *pPager){ int sqlite3PagerOpenLog(Pager *pPager, int *pisOpen){ int rc = SQLITE_OK; /* Return code */ - assert_file_lock(pPager, SQLITE_LOCK_SHARED); + assert( pPager->state>=PAGER_SHARED ); if( !pPager->pLog ){ /* Open the connection to the log file. If this operation fails, @@ -5769,7 +5758,7 @@ int sqlite3PagerCloseLog(Pager *pPager){ if( pPager->pLog ){ /* Try to obtain an EXCLUSIVE lock on the database file. */ - rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_EXCLUSIVE); /* If the EXCLUSIVE lock was obtained, checkpoint and close the log. */ if( rc==SQLITE_OK ){ @@ -5779,8 +5768,6 @@ int sqlite3PagerCloseLog(Pager *pPager){ ); pPager->pLog = 0; } - - assert_file_lock(pPager, SQLITE_LOCK_EXCLUSIVE); } return rc; } diff --git a/src/vdbe.c b/src/vdbe.c index cc53c9bff1..5e2316678f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5260,9 +5260,6 @@ case OP_JournalMode: { ** mode, this transaction always uses a rollback journal. */ assert( sqlite3BtreeIsInTrans(pBt)==0 ); - rc = sqlite3BtreeBeginTrans(pBt, 2); - assert( rc==SQLITE_OK || eOld!=PAGER_JOURNALMODE_WAL ); - if( rc!=SQLITE_OK ) goto abort_due_to_error; rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); if( rc!=SQLITE_OK ) goto abort_due_to_error; } @@ -5272,7 +5269,7 @@ case OP_JournalMode: { eNew = sqlite3PagerJournalMode(pPager, eNew); pOut = &aMem[pOp->p2]; pOut->flags = MEM_Str|MEM_Static|MEM_Term; - pOut->z = sqlite3JournalModename(eNew); + pOut->z = (char *)sqlite3JournalModename(eNew); pOut->n = sqlite3Strlen30(pOut->z); pOut->enc = SQLITE_UTF8; sqlite3VdbeChangeEncoding(pOut, encoding); diff --git a/test/wal.test b/test/wal.test index 2c73904634..f0268e19a2 100644 --- a/test/wal.test +++ b/test/wal.test @@ -625,7 +625,7 @@ do_test wal-11.10 { SELECT count(*) FROM t1; } list [expr [file size test.db]/1024] [file size test.db-wal] -} [list 37 [log_file_size 37 1024]] +} [list 37 [log_file_size 35 1024]] do_test wal-11.11 { execsql { SELECT count(*) FROM t1; @@ -635,7 +635,7 @@ do_test wal-11.11 { } {32 16} do_test wal-11.12 { list [expr [file size test.db]/1024] [file size test.db-wal] -} [list 37 [log_file_size 37 1024]] +} [list 37 [log_file_size 35 1024]] do_test wal-11.13 { execsql { INSERT INTO t1 VALUES( blob(900) ); @@ -645,7 +645,7 @@ do_test wal-11.13 { } {17 ok} do_test wal-11.14 { list [expr [file size test.db]/1024] [file size test.db-wal] -} [list 37 [log_file_size 37 1024]] +} [list 37 [log_file_size 35 1024]] #------------------------------------------------------------------------- diff --git a/test/walmode.test b/test/walmode.test index 1a3af3a705..8d3b882f01 100644 --- a/test/walmode.test +++ b/test/walmode.test @@ -17,9 +17,79 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test walmode-1.1 { - execsql { - PRAGMA journal_mode = wal; - } + set sqlite_sync_count 0 + execsql { PRAGMA page_size = 1024 } + execsql { PRAGMA journal_mode = wal } } {wal} +do_test walmode-1.2 { + file size test.db +} {1024} +do_test walmode-1.3 { + set sqlite_sync_count +} {4} +do_test walmode-1.4 { + file exists test.db-wal +} {0} +do_test walmode-1.5 { + execsql { CREATE TABLE t1(a, b) } + file size test.db +} {1024} +do_test walmode-1.6 { + file exists test.db-wal +} {1} +do_test walmode-1.7 { + db close + file exists test.db-wal +} {0} + +# There is now a database file with the read and write versions set to 2 +# in the file system. This file should default to WAL mode. +# +do_test walmode-2.1 { + sqlite3 db test.db + file exists test.db-wal +} {0} +do_test walmode-2.2 { + execsql { SELECT * FROM sqlite_master } + file exists test.db-wal +} {1} +do_test walmode-2.3 { + db close + file exists test.db-wal +} {0} + +# If the first statement executed is "PRAGMA journal_mode = wal", and +# the file is already configured for WAL (read and write versions set +# to 2), then there should be no need to write the database. The +# statement should cause the client to connect to the log file. +# +set sqlite_sync_count 0 +do_test walmode-3.1 { + sqlite3 db test.db + execsql { PRAGMA journal_mode = wal } +} {wal} +do_test walmode-3.2 { + list $sqlite_sync_count [file exists test.db-wal] [file size test.db-wal] +} {0 1 0} + +do_test walmode-4.1 { + execsql { INSERT INTO t1 VALUES(1, 2) } + execsql { PRAGMA journal_mode = persist } +} {persist} +do_test walmode-4.2 { + list [file exists test.db-journal] [file exists test.db-wal] +} {1 0} +do_test walmode-4.3 { + execsql { SELECT * FROM t1 } +} {1 2} +do_test walmode-4.4 { + db close + sqlite3 db test.db + execsql { SELECT * FROM t1 } +} {1 2} +do_test walmode-4.5 { + list [file exists test.db-journal] [file exists test.db-wal] +} {1 0} finish_test + -- 2.47.2