From: dan Date: Mon, 8 May 2017 20:15:23 +0000 (+0000) Subject: Add some support for wal mode to the hack on this branch. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b7bcf5c16ca8cc016c21eafab030a44227159de5;p=thirdparty%2Fsqlite.git Add some support for wal mode to the hack on this branch. FossilOrigin-Name: b733afc1d0abc09861903ce8e27a8f2462ec871967f5d3dc2847b31bb28b55f3 --- diff --git a/manifest b/manifest index cd7195c02b..676b3e30e1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthis\sbranch\swith\slatest\strunk\schanges. -D 2017-05-06T16:04:58.355 +C Add\ssome\ssupport\sfor\swal\smode\sto\sthe\shack\son\sthis\sbranch. +D 2017-05-08T20:15:23.906 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6a8c838220f7c00820e1fc0ac1bccaaa8e5676067e1dbfa1bafa7a4ffecf8ae6 @@ -389,7 +389,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 67e97956c302cf81acf0f3f56e1853b32c88cda5ae09ecba3bcd35272d2ab739 +F src/pager.c aec4a28d8aace83424bc9ec1f85867f2defd0e2173caba11628ff5daee2c4d5c F src/pager.h ea05992c581c3366279fb1d436944604b4be17208ebb41fa407306e5e4b34205 F src/parse.y 0513387ce02fea97897d8caef82d45f347818593f24f1bdc48e0c530a8af122d F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 @@ -481,8 +481,8 @@ F src/vdbesort.c e72fe02a2121386ba767ede8942e9450878b8fc873abf3d1b6824485f092570 F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 -F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 +F src/wal.c 126aadd32eddde857e7f495e8887fa9dc6847fb287994ec5a5a25d29e00026ef +F src/wal.h 739d92494eb18b6d8f3e353e66c10eb8f94534bafd336ece9f3f60235317ea08 F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791 F src/where.c c6352f15be5031907c68bcbde96cad1a6da20e9f4051d10168a59235de9a8566 F src/whereInt.h 2a4b634d63ce488b46d4b0da8f2eaa8f9aeab202bc25ef76f007de5e3fba1f20 @@ -1114,6 +1114,7 @@ F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118 F test/server2.test 11dda300ebef43b4abe0fdc086b6f51b964beddb529fb65bc1f026db5895c36e F test/server3.test c33343f2f6bc23f2b4e2f047c3d083579f0cfac2795e0f1eb226ab34758967c0 F test/servercrash.test 816c132b26af008067cab2913783f67006d4003e3988f3f3ee1075742f6e0a6c +F test/serverwal.test 92b8bf8e298f1998abbbdd7be3d7a8998da3ce0752e6145e8b5dc3e1bafaa248 F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746 F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 @@ -1582,7 +1583,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 83b1e163ef6ac01d252268415f26a2a999670de583491becc091d294075980bc b9a58daca80a815e87e541cb5fff9bc8b93f131d223f322c5b83dd5a5f0c0312 -R 952da0dcda6531ec91ee10aec90184f4 +P ed6bad67f530afa2fba1bce339a9772f281bd108666ca6c23642efcefa2d98e5 +R 2a0e7ce8f8804eb6e9ded68b549dbd29 U dan -Z 3f846c10a713919860c0f77bb78b97b0 +Z 1f1788eecdf4834ab0b218624657be1d diff --git a/manifest.uuid b/manifest.uuid index 8585eadf6c..9dea27d4b6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed6bad67f530afa2fba1bce339a9772f281bd108666ca6c23642efcefa2d98e5 \ No newline at end of file +b733afc1d0abc09861903ce8e27a8f2462ec871967f5d3dc2847b31bb28b55f3 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 5c810bad30..e0a4a47313 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5373,17 +5373,17 @@ int sqlite3PagerSharedLock(Pager *pPager){ } } + rc = pagerServerConnect(pPager); + /* If there is a WAL file in the file-system, open this database in WAL ** mode. Otherwise, the following function call is a no-op. */ - rc = pagerOpenWalIfPresent(pPager); + if( rc==SQLITE_OK ){ + rc = pagerOpenWalIfPresent(pPager); + } #ifndef SQLITE_OMIT_WAL assert( pPager->pWal==0 || rc==SQLITE_OK ); #endif - - if( rc==SQLITE_OK && pagerUseWal(pPager)==0 ){ - rc = pagerServerConnect(pPager); - } } #ifdef SQLITE_SERVER_EDITION @@ -5391,7 +5391,7 @@ int sqlite3PagerSharedLock(Pager *pPager){ assert( rc==SQLITE_OK ); pager_reset(pPager); rc = sqlite3ServerBegin(pPager->pServer); - }else + } #endif if( pagerUseWal(pPager) ){ assert( rc==SQLITE_OK ); @@ -7455,7 +7455,7 @@ int sqlite3PagerWalCallback(Pager *pPager){ */ int sqlite3PagerWalSupported(Pager *pPager){ const sqlite3_io_methods *pMethods = pPager->fd->pMethods; - if( pPager->noLock ) return 0; + if( pPager->noLock && !pagerIsServer(pPager) ) return 0; return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap); } @@ -7550,6 +7550,7 @@ int sqlite3PagerOpenWal( if( rc==SQLITE_OK ){ pPager->journalMode = PAGER_JOURNALMODE_WAL; pPager->eState = PAGER_OPEN; + sqlite3WalServer(pPager->pWal, pPager->pServer); } }else{ *pbOpen = 1; diff --git a/src/wal.c b/src/wal.c index 09f605fe57..cbc95a69f5 100644 --- a/src/wal.c +++ b/src/wal.c @@ -454,8 +454,17 @@ struct Wal { #ifdef SQLITE_ENABLE_SNAPSHOT WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ #endif +#ifdef SQLITE_SERVER_EDITION + Server *pServer; +#endif }; +#ifdef SQLITE_SERVER_EDITION +# define walIsServer(p) ((p)->pServer!=0) +#else +# define walIsServer(p) 0 +#endif + /* ** Candidate values for Wal.exclusiveMode. */ @@ -1261,6 +1270,14 @@ static void walIndexClose(Wal *pWal, int isDelete){ } } +#ifdef SQLITE_SERVER_EDITION +int sqlite3WalServer(Wal *pWal, Server *pServer){ + assert( pWal->pServer==0 ); + pWal->pServer = pServer; + return SQLITE_OK; +} +#endif + /* ** Open a connection to the WAL file zWalName. The database file must ** already be opened on connection pDbFd. The buffer that zWalName points @@ -2249,6 +2266,9 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ } } + assert( rc==SQLITE_OK ); + if( walIsServer(pWal) ) return SQLITE_OK; + pInfo = walCkptInfo(pWal); if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame #ifdef SQLITE_ENABLE_SNAPSHOT @@ -2588,7 +2608,12 @@ int sqlite3WalFindFrame( int iMinHash; /* This routine is only be called from within a read transaction. */ - assert( pWal->readLock>=0 || pWal->lockError ); + assert( walIsServer(pWal) || pWal->readLock>=0 || pWal->lockError ); + + if( walIsServer(pWal) ){ + /* A server mode connection must read from the most recent snapshot. */ + iLast = walIndexHdr(pWal)->mxFrame; + } /* If the "last page" field of the wal-index header snapshot is 0, then ** no data will be read from the wal under any circumstances. Return early @@ -2700,7 +2725,7 @@ int sqlite3WalReadFrame( ** Return the size of the database in pages (or zero, if unknown). */ Pgno sqlite3WalDbsize(Wal *pWal){ - if( pWal && ALWAYS(pWal->readLock>=0) ){ + if( pWal && (walIsServer(pWal) || ALWAYS(pWal->readLock>=0)) ){ return pWal->hdr.nPage; } return 0; @@ -2725,13 +2750,18 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){ /* Cannot start a write transaction without first holding a read ** transaction. */ - assert( pWal->readLock>=0 ); + assert( walIsServer(pWal) || pWal->readLock>=0 ); assert( pWal->writeLock==0 && pWal->iReCksum==0 ); if( pWal->readOnly ){ return SQLITE_READONLY; } + /* For a server connection, do nothing at this point. */ + if( walIsServer(pWal) ){ + return SQLITE_OK; + } + /* Only one writer allowed at a time. Get the write lock. Return ** SQLITE_BUSY if unable. */ @@ -3058,7 +3088,18 @@ int sqlite3WalFrames( WalIndexHdr *pLive; /* Pointer to shared header */ assert( pList ); - assert( pWal->writeLock ); + assert( pWal->writeLock || walIsServer(pWal) ); + if( pWal->writeLock==0 ){ + int bDummy = 0; + rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); + if( rc==SQLITE_OK ){ + pWal->writeLock = 1; + rc = walIndexTryHdr(pWal, &bDummy); + } + if( rc!=SQLITE_OK ){ + return rc; + } + } /* If this frame set completes a transaction, then nTruncate>0. If ** nTruncate==0 then this frame set does not complete the transaction. */ diff --git a/src/wal.h b/src/wal.h index 4f6d01dad6..4eea6ef65d 100644 --- a/src/wal.h +++ b/src/wal.h @@ -144,5 +144,9 @@ int sqlite3WalFramesize(Wal *pWal); /* Return the sqlite3_file object for the WAL file */ sqlite3_file *sqlite3WalFile(Wal *pWal); +#ifdef SQLITE_SERVER_EDITION +int sqlite3WalServer(Wal *pWal, Server *pServer); +#endif + #endif /* ifndef SQLITE_OMIT_WAL */ #endif /* SQLITE_WAL_H */ diff --git a/test/serverwal.test b/test/serverwal.test new file mode 100644 index 0000000000..8d726ecdfa --- /dev/null +++ b/test/serverwal.test @@ -0,0 +1,64 @@ +# 2017 April 25 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this script is testing the server mode of SQLite. +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix serverwal + +# Check files are created and deleted as expected. +# +do_execsql_test 1.0 { + PRAGMA journal_mode = wal; +} {wal} +do_execsql_test 1.1 { + CREATE TABLE t1(a, b); +} +do_execsql_test 1.2 { + SELECT * FROM t1; +} {} +do_test 1.3 { + lsort [glob test.db*] +} {test.db test.db-hma test.db-shm test.db-wal} +do_test 1.4 { + db close + glob test.db* +} {test.db} + +# Two concurrent transactions. +# +do_test 2.0 { + sqlite3 db test.db + sqlite3 db2 test.db + db eval { + CREATE TABLE t2(a, b); + } +} {} +do_test 2.1 { + execsql { + BEGIN; + INSERT INTO t1 VALUES(1, 2); + } db + execsql { + BEGIN; + INSERT INTO t2 VALUES(1, 2); + } db2 +} {} +do_test 2.2 { + execsql COMMIT db + execsql COMMIT db2 +} {} + + +finish_test