1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

If a database file with the WAL flag set is opened in exclusive-locking mode, use heap memory to store the wal-index instead of shared-memory.

FossilOrigin-Name: 8dd5c69198619866923c6053b71899c1fb8c4c67
This commit is contained in:
dan
2010-11-01 17:38:24 +00:00
parent b6e321c09a
commit 8c40800439
12 changed files with 366 additions and 62 deletions

View File

@ -1,8 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C Change\sthe\sversion\snumber\sto\s3.7.4.
D 2010-11-01T14:34:31
C If\sa\sdatabase\sfile\swith\sthe\sWAL\sflag\sset\sis\sopened\sin\sexclusive-locking\smode,\suse\sheap\smemory\sto\sstore\sthe\swal-index\sinstead\sof\sshared-memory.
D 2010-11-01T17:38:25
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2c8cefd962eca0147132c7cf9eaa4bb24c656f3f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -165,7 +162,7 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
F src/os_unix.c 00a4a84aba46b61439913bebf0c10d408e42a630
F src/os_win.c 2f90f7bdec714fad51cd31b4ecad3cc1b4bb5aad
F src/pager.c d9858b47b216e3bcb0431bd50ef17d070ac0b92c
F src/pager.c c19b0e8d49220825fd382236fbbcb3063c48ce2d
F src/pager.h 8167a1e720d0b7a2790079007128e594010220ad
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa
@ -221,7 +218,7 @@ F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
F src/test_stat.c f682704b5d1ba8e1d4e7e882a6d7922e2dcf066c
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0
F src/test_vfs.c 702e52636113f6b9721da90ef1bf26e07fff414d
F src/test_vfs.c e10fcca756cafa89438311b31522ac1f95bf784b
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080
F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852
@ -238,8 +235,8 @@ F src/vdbeblob.c e0ce3c54cc0c183af2ec67b63a289acf92251df4
F src/vdbemem.c 23723a12cd3ba7ab3099193094cbb2eb78956aa9
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30
F src/wal.c 0dc7eb9e907a2c280cdcde876d313e07ea4ad811
F src/wal.h 96669b645e27cd5a111ba59f0cae7743a207bc3c
F src/wal.c f26b8d297bd11cb792e609917f9d4c6718ac8e0e
F src/wal.h c1aac6593a0b02b15dc625987e619edeab39292e
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
F src/where.c d9a31eb3d59466b6c53567c8c9a6c2fe68bbd565
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@ -569,7 +566,7 @@ F test/notify3.test d60923e186e0900f4812a845fcdfd8eea096e33a
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
F test/pager1.test 12ad20280db1ba25f1f0d7ddebf0971a305d8f80
F test/pager1.test fa74657dc832f0e21dc3ce60829feaee143296ba
F test/pager2.test 0fbb6b6dc40ce1fecfe758c555a748ad2e9beaa3
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F test/pagerfault.test 3cd3537bf2efb4baef26c74878718f4a32926da4
@ -578,7 +575,7 @@ F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
F test/pcache.test 4118a183908ecaed343a06fcef3ba82e87e0129d
F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
F test/permutations.test da40da6433f050b50e65a8ae37265ab6c89f876c
F test/permutations.test e54d5fc34708ecb4a67f2a18f7b8719b175a1652
F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
@ -655,7 +652,7 @@ F test/tclsqlite.test 8c154101e704170c2be10f137a5499ac2c6da8d3
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a
F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05
F test/tester.tcl b9c732d1228f0daab41bbbeddd6d0861394b23aa
F test/tester.tcl fa48313dcf20f9c6def1af485e284e29100d709e
F test/thread001.test a3e6a7254d1cb057836cb3145b60c10bf5b7e60f
F test/thread002.test afd20095e6e845b405df4f2c920cb93301ca69db
F test/thread003.test b824d4f52b870ae39fc5bae4d8070eca73085dca
@ -823,7 +820,7 @@ F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
F test/wal.test 70227190e713b3e7eb2a7d5ec3510b66db01f327
F test/wal2.test 223f3e14d475730af772a7f5862d4bcfa7565c3a
F test/wal2.test c794b8b257af54190bb913678ad3984cbf3311b9
F test/wal3.test 957a5f2a8fe8a6ff01de1a15285ecf2f376fcaf8
F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30
F test/wal_common.tcl 895d76138043b86bdccf36494054bdabcf65837b
@ -832,9 +829,10 @@ F test/walbig.test e882bc1d014afffbfa2b6ba36e0f07d30a633ad0
F test/walcksum.test a37b36375c595e61bdb7e1ec49b5f0979b6fc7ce
F test/walcrash.test e763841551d6b23677ccb419797c1589dcbdbaf5
F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142
F test/walfault.test 05c470688d742688e455dd56816bd6bcffa298f8
F test/walfault.test 1211c3c5f35142d93940c709c61fbaf58c3afab6
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
F test/walmode.test 22ddccd073c817ac9ead62b88ac446e8dedc7d2c
F test/walnoshm.test 732391f72af2785d2758aaa8f9ae563d6d519b20
F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933
F test/walthread.test a25a393c068a2b42b44333fa3fdaae9072f1617c
@ -884,14 +882,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 582db83294599ffd7265d3ab2db2765e7e4fbb8d
R a1ed7a266761633aef3d19047277de6a
U drh
Z 4f48c9a1b8040f4fd58227e590b304c6
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFMzs/6oxKgR168RlERAuCbAJ9uimmTB547wDq4mUtvniDAfA0HTwCeNbhj
lkScdJYDKuse8cKgqrNrUF4=
=7Gng
-----END PGP SIGNATURE-----
P db64843b540d23c58fe4de199a7fc40d44900bc4
R 2b6e847446dd321925fabfa8d797522d
U dan
Z 4b3ff964892084a664463cd0c913ef99

View File

@ -1 +1 @@
db64843b540d23c58fe4de199a7fc40d44900bc4
8dd5c69198619866923c6053b71899c1fb8c4c67

View File

@ -1050,7 +1050,7 @@ static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
static int pagerUnlockDb(Pager *pPager, int eLock){
int rc = SQLITE_OK;
assert( !pPager->exclusiveMode );
assert( !pPager->exclusiveMode || pPager->eLock==eLock );
assert( eLock==NO_LOCK || eLock==SHARED_LOCK );
assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
if( isOpen(pPager->fd) ){
@ -6350,7 +6350,8 @@ int sqlite3PagerLockingMode(Pager *pPager, int eMode){
|| eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
assert( PAGER_LOCKINGMODE_QUERY<0 );
assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
if( eMode>=0 && !pPager->tempFile ){
assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) );
if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){
pPager->exclusiveMode = (u8)eMode;
}
return (int)pPager->exclusiveMode;
@ -6537,9 +6538,61 @@ int sqlite3PagerWalCallback(Pager *pPager){
*/
int sqlite3PagerWalSupported(Pager *pPager){
const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
return pMethods->iVersion>=2 && pMethods->xShmMap!=0;
return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
}
/*
** Attempt to take an exclusive lock on the database file. If a PENDING lock
** is obtained instead, immediately release it.
*/
static int pagerExclusiveLock(Pager *pPager){
int rc; /* Return code */
assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
if( rc!=SQLITE_OK ){
/* If the attempt to grab the pending lock failed, release the
** exclusive lock that may have been obtained instead. */
pagerUnlockDb(pPager, SHARED_LOCK);
}
return rc;
}
/*
** Call sqlite3WalOpen() to open the WAL handle. If the pager is in
** exclusive-locking mode when this function is called, take an EXCLUSIVE
** lock on the database file and use heap-memory to store the wal-index
** in. Otherwise, use the normal shared-memory.
*/
static int pagerOpenWal(Pager *pPager){
int rc = SQLITE_OK;
assert( pPager->pWal==0 && pPager->tempFile==0 );
assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
/* If the pager is already in exclusive-mode, the WAL module will use
** heap-memory for the wal-index instead of the VFS shared-memory
** implementation. Take the exclusive lock now, before opening the WAL
** file, to make sure this is safe.
*/
if( pPager->exclusiveMode ){
rc = pagerExclusiveLock(pPager);
}
/* Open the connection to the log file. If this operation fails,
** (e.g. due to malloc() failure), return an error code.
*/
if( rc==SQLITE_OK ){
rc = sqlite3WalOpen(pPager->pVfs,
pPager->fd, pPager->zWal, pPager->exclusiveMode, &pPager->pWal
);
}
return rc;
}
/*
** The caller must be holding a SHARED lock on the database file to call
** this function.
@ -6573,11 +6626,7 @@ int sqlite3PagerOpenWal(
/* Close any rollback journal previously open */
sqlite3OsClose(pPager->jfd);
/* Open the connection to the log file. If this operation fails,
** (e.g. due to malloc() failure), unlock the database file and
** return an error code.
*/
rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, &pPager->pWal);
rc = pagerOpenWal(pPager);
if( rc==SQLITE_OK ){
pPager->journalMode = PAGER_JOURNALMODE_WAL;
pPager->eState = PAGER_OPEN;
@ -6616,8 +6665,7 @@ int sqlite3PagerCloseWal(Pager *pPager){
);
}
if( rc==SQLITE_OK && logexists ){
rc = sqlite3WalOpen(pPager->pVfs, pPager->fd,
pPager->zWal, &pPager->pWal);
rc = pagerOpenWal(pPager);
}
}
@ -6625,17 +6673,13 @@ int sqlite3PagerCloseWal(Pager *pPager){
** the database file, the log and log-summary files will be deleted.
*/
if( rc==SQLITE_OK && pPager->pWal ){
rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
rc = pagerExclusiveLock(pPager);
if( rc==SQLITE_OK ){
rc = sqlite3WalClose(pPager->pWal,
(pPager->noSync ? 0 : pPager->sync_flags),
pPager->pageSize, (u8*)pPager->pTmpSpace
(pPager->noSync ? 0 : pPager->sync_flags),
pPager->pageSize, (u8*)pPager->pTmpSpace
);
pPager->pWal = 0;
}else{
/* If we cannot get an EXCLUSIVE lock, downgrade the PENDING lock
** that we did get back to SHARED. */
pagerUnlockDb(pPager, SQLITE_LOCK_SHARED);
}
}
return rc;

View File

@ -26,6 +26,7 @@
** -default BOOLEAN (True to make the vfs default. Default false)
** -szosfile INTEGER (Value for sqlite3_vfs.szOsFile)
** -mxpathname INTEGER (Value for sqlite3_vfs.mxPathname)
** -iversion INTEGER (Value for sqlite3_vfs.iVersion)
*/
#include "sqlite3.h"

View File

@ -428,6 +428,13 @@ struct Wal {
#endif
};
/*
** Candidate values for Wal.exclusiveMode.
*/
#define WAL_NORMAL_MODE 0
#define WAL_EXCLUSIVE_MODE 1
#define WAL_HEAPMEMORY_MODE 2
/*
** Each page of the wal-index mapping contains a hash-table made up of
** an array of HASHTABLE_NSLOT elements of the following type.
@ -514,9 +521,14 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
/* Request a pointer to the required page from the VFS */
if( pWal->apWiData[iPage]==0 ){
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
);
if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM;
}else{
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
);
}
}
*ppPage = pWal->apWiData[iPage];
@ -599,6 +611,12 @@ static void walChecksumBytes(
aOut[1] = s2;
}
static void walShmBarrier(Wal *pWal){
if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
sqlite3OsShmBarrier(pWal->pDbFd);
}
}
/*
** Write the header information in pWal->hdr into the wal-index.
**
@ -613,7 +631,7 @@ static void walIndexWriteHdr(Wal *pWal){
pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
memcpy((void *)&aHdr[1], (void *)&pWal->hdr, sizeof(WalIndexHdr));
sqlite3OsShmBarrier(pWal->pDbFd);
walShmBarrier(pWal);
memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr));
}
@ -1185,7 +1203,15 @@ recovery_error:
** Close an open wal-index.
*/
static void walIndexClose(Wal *pWal, int isDelete){
sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
int i;
for(i=0; i<pWal->nWiData; i++){
sqlite3_free((void *)pWal->apWiData[i]);
pWal->apWiData[i] = 0;
}
}else{
sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
}
}
/*
@ -1207,6 +1233,7 @@ int sqlite3WalOpen(
sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */
sqlite3_file *pDbFd, /* The open database file */
const char *zWalName, /* Name of the WAL file */
int bNoShm, /* True to run in heap-memory mode */
Wal **ppWal /* OUT: Allocated Wal handle */
){
int rc; /* Return Code */
@ -1240,6 +1267,7 @@ int sqlite3WalOpen(
pRet->pDbFd = pDbFd;
pRet->readLock = -1;
pRet->zWalName = zWalName;
pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);
/* Open file handle on the write-ahead log file. */
flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
@ -1673,7 +1701,9 @@ int sqlite3WalClose(
*/
rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
if( rc==SQLITE_OK ){
pWal->exclusiveMode = 1;
if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
}
rc = sqlite3WalCheckpoint(pWal, sync_flags, nBuf, zBuf);
if( rc==SQLITE_OK ){
isDelete = 1;
@ -1729,7 +1759,7 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){
*/
aHdr = walIndexHdr(pWal);
memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
sqlite3OsShmBarrier(pWal->pDbFd);
walShmBarrier(pWal);
memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
if( memcmp(&h1, &h2, sizeof(h1))!=0 ){
@ -1930,7 +1960,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
** and can be safely ignored.
*/
rc = walLockShared(pWal, WAL_READ_LOCK(0));
sqlite3OsShmBarrier(pWal->pDbFd);
walShmBarrier(pWal);
if( rc==SQLITE_OK ){
if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){
/* It is not safe to allow the reader to continue here if frames
@ -2024,7 +2054,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
** log-wrap (either of which would require an exclusive lock on
** WAL_READ_LOCK(mxI)) has not occurred since the snapshot was valid.
*/
sqlite3OsShmBarrier(pWal->pDbFd);
walShmBarrier(pWal);
if( pInfo->aReadMark[mxI]!=mxReadMark
|| memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
){
@ -2667,13 +2697,14 @@ int sqlite3WalCallback(Wal *pWal){
** on the main database file before invoking this operation.
**
** If op is negative, then do a dry-run of the op==1 case but do
** not actually change anything. The pager uses this to see if it
** not actually change anything. The pager uses this to see if it
** should acquire the database exclusive lock prior to invoking
** the op==1 case.
*/
int sqlite3WalExclusiveMode(Wal *pWal, int op){
int rc;
assert( pWal->writeLock==0 );
assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 );
/* pWal->readLock is usually set, but might be -1 if there was a
** prior error while attempting to acquire are read-lock. This cannot
@ -2707,4 +2738,13 @@ int sqlite3WalExclusiveMode(Wal *pWal, int op){
return rc;
}
/*
** Return true if the argument is non-NULL and the WAL module is using
** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
** WAL module is using shared-memory, return false.
*/
int sqlite3WalHeapMemory(Wal *pWal){
return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
}
#endif /* #ifndef SQLITE_OMIT_WAL */

View File

@ -35,6 +35,7 @@
# define sqlite3WalCheckpoint(u,v,w,x) 0
# define sqlite3WalCallback(z) 0
# define sqlite3WalExclusiveMode(y,z) 0
# define sqlite3WalHeapMemory(z) 0
#else
#define WAL_SAVEPOINT_NDATA 4
@ -45,7 +46,7 @@
typedef struct Wal Wal;
/* Open and close a connection to a write-ahead log. */
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *zName, Wal**);
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *zName, int, Wal**);
int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
/* Used by readers to open (lock) and close (unlock) a snapshot. A
@ -102,5 +103,11 @@ int sqlite3WalCallback(Wal *pWal);
*/
int sqlite3WalExclusiveMode(Wal *pWal, int op);
/* Return true if the argument is non-NULL and the WAL module is using
** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
** WAL module is using shared-memory, return false.
*/
int sqlite3WalHeapMemory(Wal *pWal);
#endif /* ifndef SQLITE_OMIT_WAL */
#endif /* _WAL_H_ */

View File

@ -1107,10 +1107,10 @@ ifcapable wal {
COMMIT;
} {1 2} 0 -1
4 { PRAGMA journal_mode = WAL } wal -1 -1
5 { INSERT INTO t1 VALUES(3, 4) } {} -1 [wal_file_size 1 1024]
6 { PRAGMA locking_mode = NORMAL } normal -1 [wal_file_size 1 1024]
7 { INSERT INTO t1 VALUES(5, 6); } {} -1 [wal_file_size 2 1024]
4 { PRAGMA journal_mode = WAL } wal -1 -1
5 { INSERT INTO t1 VALUES(3, 4) } {} -1 [wal_file_size 1 1024]
6 { PRAGMA locking_mode = NORMAL } exclusive -1 [wal_file_size 1 1024]
7 { INSERT INTO t1 VALUES(5, 6); } {} -1 [wal_file_size 2 1024]
8 { PRAGMA journal_mode = TRUNCATE } truncate 0 -1
9 { INSERT INTO t1 VALUES(7, 8) } {} 0 -1

View File

@ -183,7 +183,7 @@ test_suite "coverage-wal" -description {
} -files {
wal.test wal2.test wal3.test walmode.test
walbak.test walhook.test walcrash2.test walcksum.test
walfault.test walbig.test
walfault.test walbig.test walnoshm.test
}
test_suite "coverage-pager" -description {

View File

@ -303,6 +303,8 @@ proc do_test {name cmd expected} {
global argv cmdlinearg
fix_testname name
sqlite3_memdebug_settitle $name
# if {[llength $argv]==0} {

View File

@ -430,13 +430,16 @@ do_test wal2-6.1.1 {
sqlite3 db test.db
execsql {
Pragma Journal_Mode = Wal;
Pragma Locking_Mode = Exclusive;
}
} {wal exclusive}
} {wal}
do_test wal2-6.1.2 {
execsql { PRAGMA lock_status }
} {main unlocked temp closed}
do_test wal2-6.1.3 {
execsql {
SELECT * FROM sqlite_master;
Pragma Locking_Mode = Exclusive;
}
execsql {
BEGIN;
CREATE TABLE t1(a, b);
@ -486,6 +489,7 @@ do_test wal2-6.2.2 {
do_test wal2-6.2.3 {
db close
sqlite3 db test.db
execsql { SELECT * FROM sqlite_master }
execsql { PRAGMA LOCKING_MODE = EXCLUSIVE }
} {exclusive}
do_test wal2-6.2.4 {
@ -732,6 +736,7 @@ do_test wal2-6.6.1 {
T script lock_control
T filter {}
sqlite3 db test.db -vfs T
execsql { SELECT * FROM sqlite_master }
execsql { PRAGMA locking_mode = exclusive }
execsql { INSERT INTO t2 VALUES('V', 'VI') }
} {}
@ -755,7 +760,7 @@ do_test wal2-6.6.2 {
T filter {}
execsql { INSERT INTO t2 VALUES('IX', 'X') }
} {}
do_test wal2-6.6.3 {
do_test wal2-6.6.4 {
# This time, we have successfully exited exclusive mode. So the second
# connection can read the database.
sqlite3 db2 test.db -vfs T

View File

@ -446,5 +446,73 @@ do_faultsim_test walfault-12 -prep {
faultsim_test_result {0 {}}
}
#-------------------------------------------------------------------------
# Test simple recovery, reading and writing a database file using a
# heap-memory wal-index.
#
do_test walfault-13-pre-1 {
faultsim_delete_and_reopen
execsql {
PRAGMA journal_mode = WAL;
PRAGMA wal_autocheckpoint = 0;
BEGIN;
CREATE TABLE abc(a PRIMARY KEY);
INSERT INTO abc VALUES(randomblob(1500));
INSERT INTO abc VALUES(randomblob(1500));
COMMIT;
}
faultsim_save_and_close
file delete sv_test.db-shm
} {}
do_faultsim_test walfault-13.1 -prep {
faultsim_restore_and_reopen
} -body {
db eval { PRAGMA locking_mode = exclusive }
db eval { SELECT count(*) FROM abc }
} -test {
faultsim_test_result {0 2}
if {[file exists test.db-shm]} { error "Not using heap-memory mode" }
faultsim_integrity_check
}
do_faultsim_test walfault-13.2 -prep {
faultsim_restore_and_reopen
db eval { PRAGMA locking_mode = exclusive }
} -body {
db eval { PRAGMA journal_mode = delete }
} -test {
faultsim_test_result {0 delete}
if {[file exists test.db-shm]} { error "Not using heap-memory mode" }
faultsim_integrity_check
}
do_test walfault-13-pre-2 {
faultsim_delete_and_reopen
execsql {
BEGIN;
CREATE TABLE abc(a PRIMARY KEY);
INSERT INTO abc VALUES(randomblob(1500));
INSERT INTO abc VALUES(randomblob(1500));
COMMIT;
}
faultsim_save_and_close
} {}
do_faultsim_test walfault-13.3 -prep {
faultsim_restore_and_reopen
} -body {
db eval {
PRAGMA locking_mode = exclusive;
PRAGMA journal_mode = WAL;
INSERT INTO abc VALUES(randomblob(1500));
}
} -test {
faultsim_test_result {0 {exclusive wal}}
if {[file exists test.db-shm]} { error "Not using heap-memory mode" }
faultsim_integrity_check
set nRow [db eval {SELECT count(*) FROM abc}]
if {!(($nRow==2 && $testrc) || $nRow==3)} { error "Bad db content" }
}
finish_test

146
test/walnoshm.test Normal file
View File

@ -0,0 +1,146 @@
# 2010 November 1
#
# 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 file is testing that WAL databases may be accessed without
# using the xShm primitives if the connection is in exclusive-mode.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix walnoshm
ifcapable !wal {finish_test ; return }
db close
testvfs tvfsshm
testvfs tvfs -default 1 -iversion 1
sqlite3 db test.db
#--------------------------------------------------------------------------
# Test that when using a version 1 VFS, a database can only be converted
# to WAL mode after setting locking_mode=EXCLUSIVE. Also, test that if a
# WAL database is opened using heap-memory for the WAL index, the connection
# cannot change back to locking_mode=NORMAL while the database is still in
# WAL mode.
#
do_execsql_test 1.1 {
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(1, 2);
}
do_execsql_test 1.2 {
PRAGMA journal_mode = WAL;
SELECT * FROM t1;
} {delete 1 2}
do_test 1.3 { file exists test.db-wal } {0}
do_execsql_test 1.4 {
PRAGMA locking_mode = exclusive;
PRAGMA journal_mode = WAL;
SELECT * FROM t1;
} {exclusive wal 1 2}
do_test 1.5 { file exists test.db-wal } {1}
do_execsql_test 1.6 { INSERT INTO t1 VALUES(3, 4) }
do_execsql_test 1.7 {
PRAGMA locking_mode = normal;
} {exclusive}
do_execsql_test 1.8 {
PRAGMA journal_mode = delete;
PRAGMA main.locking_mode;
} {delete exclusive}
do_execsql_test 1.9 {
PRAGMA locking_mode = normal;
} {normal}
do_execsql_test 1.10 {
SELECT * FROM t1;
} {1 2 3 4}
do_test 1.11 { file exists test.db-wal } {0}
#-------------------------------------------------------------------------
#
# 2.1.*: Test that a connection using a version 1 VFS can open a WAL database
# and convert it to rollback mode if it is set to use
# locking_mode=exclusive.
#
# 2.2.*: Test that if the exclusive lock cannot be obtained while attempting
# the above, the operation fails and the WAL file is not opened.
#
do_execsql_test 2.1.1 {
CREATE TABLE t2(x, y);
INSERT INTO t2 VALUES('a', 'b');
INSERT INTO t2 VALUES('c', 'd');
}
do_execsql_test 2.1.2 {
PRAGMA locking_mode = exclusive;
PRAGMA journal_mode = WAL;
INSERT INTO t2 VALUES('e', 'f');
INSERT INTO t2 VALUES('g', 'h');
} {exclusive wal}
do_test 2.1.3 {
file copy -force test.db test2.db
file copy -force test.db-wal test2.db-wal
sqlite3 db2 test2.db
catchsql { SELECT * FROM t2 } db2
} {1 {unable to open database file}}
do_test 2.1.4 {
catchsql { PRAGMA journal_mode = delete } db2
} {1 {unable to open database file}}
do_test 2.1.5 {
execsql {
PRAGMA locking_mode = exclusive;
PRAGMA journal_mode = delete;
SELECT * FROM t2;
} db2
} {exclusive delete a b c d e f g h}
do_test 2.2.1 {
file copy -force test.db test2.db
file copy -force test.db-wal test2.db-wal
sqlite3 db3 test2.db -vfs tvfsshm
sqlite3 db2 test2.db
execsql { SELECT * FROM t2 } db3
} {a b c d e f g h}
do_test 2.2.2 {
execsql { PRAGMA locking_mode = exclusive } db2
catchsql { PRAGMA journal_mode = delete } db2
} {1 {database is locked}}
do_test 2.2.3 {
# This is to test that [db2] is not holding a PENDING lock (which can
# happen when an attempt to obtain an EXCLUSIVE lock fails).
sqlite3 db4 test2.db -vfs tvfsshm
execsql { SELECT * FROM t2 } db4
} {a b c d e f g h}
do_test 2.2.4 {
catchsql { SELECT * FROM t2 } db2
} {1 {database is locked}}
do_test 2.2.5 {
db4 close
sqlite3 db4 test2.db -vfs tvfsshm
execsql { SELECT * FROM t2 } db4
} {a b c d e f g h}
do_test 2.2.6 {
db3 close
db4 close
execsql { SELECT * FROM t2 } db2
} {a b c d e f g h}
db2 close
finish_test