------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Define\san\sinvariant\sto\sguarantee\sdeadlock-free\soperation\sof\sSHM\sin\sos_unix.c\nand\scheck\sthat\sinvariant\swith\sassert()\sstatements.
-D 2010-05-01T17:57:36
+C Add\sthe\ssqlite3_wal_checkpoint()\sand\ssqlite3_wal_autocheckpoint()\sAPIs.
+D 2010-05-03T08:04:49
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in d83a0ffef3dcbfb08b410a6c6dd6c009ec9167fb
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
F src/loadext.c 1c7a61ce1281041f437333f366a96aa0d29bb581
-F src/main.c b672c4af58f033c54398999dec5db9d4b6d99331
+F src/main.c 7aab969e23fea0140bdc2cc6d2b8978e8d9b0090
F src/malloc.c a08f16d134f0bfab6b20c3cd142ebf3e58235a6a
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 89d4ea8d5cdd55635cbaa48ad53132af6294cbb2
F src/pcache.c ace8f6a5ecd4711cc66a1b23053be7109bd437cf
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
F src/pcache1.c 6dc1871ce8ead9187161c370a58cd06c84221f76
-F src/pragma.c 3d4ba9c35438b296360dc09ebf86c417cf996667
+F src/pragma.c 97c6054d7867b8c5b13023d3dc566274057cd853
F src/prepare.c fd1398cb1da54385ba5bd68d93928f10d10a1d9c
F src/printf.c 5f5b65a83e63f2096a541a340722a509fa0240a7
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c c03d8a0565febcde8c6a12c5d77d065fddae889b
F src/shell.c c40427c7245535a04a9cb4a417b6cc05c022e6a4
-F src/sqlite.h.in 6e91727c0c3f9e1365e8fea2b07369a09830f47f
+F src/sqlite.h.in dcf9cfc4e9c75d00b822d1a0d07f28cb970932bf
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
-F src/sqliteInt.h 3eb613c8ba7f5159be0acf3fc148d41ec49add86
+F src/sqliteInt.h 1f81585797162269a0f18b77c815d552dad636c2
F src/sqliteLimit.h 3afab2291762b5d09ae20c18feb8e9fa935a60a6
F src/status.c 4df6fe7dce2d256130b905847c6c60055882bdbe
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
F src/util.c 32aebf04c10e51ad3977a928b7416bed671b620b
F src/vacuum.c 8e7d9a6fd076774bb6e211cad335c7337948a164
-F src/vdbe.c b2e2b70e9518c6cc986e74eca99607700904f4bd
+F src/vdbe.c 8be37a1b18786b5c026adcb2e9edc93e3a940885
F src/vdbe.h 471f6a3dcec4817ca33596fe7f6654d56c0e75f3
F src/vdbeInt.h 19ebc8c2a2e938340051ee65af3f377fb99102d1
F src/vdbeapi.c 810abe698db3ccaf67c5a8982f8cd4f31c6c902f
F test/autovacuum.test 25f891bc343a8bf5d9229e2e9ddab9f31a9ab5ec
F test/autovacuum_ioerr2.test 598b0663074d3673a9c1bc9a16e80971313bafe6
F test/avtrans.test 7a26ffc6a355b7fbff2a082f56180ede863b126c
-F test/backup.test b1e874fa9b01de9dd5137a8371d060b76a435162
+F test/backup.test 5f7f66d067e695a6040be3295a5abc289f823838
F test/backup2.test 159419073d9769fdb1780ed7e5b391a046f898d5
F test/backup_ioerr.test 1f012e692f42c0442ae652443258f70e9f20fa38
F test/backup_malloc.test 1e063c6d75143d0d6e0ae77971dd690070369387
F test/walhook.test 5ee5fd35cdc3763d5674da0dd9974f6f70c07bed
F test/walmode.test bac6f06544a8554588a1543def996bbe2fc41792
F test/walslow.test 9be52d033e871cb608a18fa4425a6dc64b625377
-F test/walthread.test 16559527eb1f1a6e9eff21cc92f7fa51fb0b5a32
+F test/walthread.test 4ef06a22d0d207aecba8cd11add820f6e7e94c43
F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
F test/where3.test aa44a9b29e8c9f3d7bb94a3bb3a95b31627d520d
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 1a0f69bef2c489e81a3d4b910b426972e9ed4054
-R 9a63fdaeb48f811dfa07166dc0124f9e
-U drh
-Z 0ec029f9a2c3c35cece8a5840fe4c2a0
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFL3GuToxKgR168RlERAruJAJ93UG+yjpg4IAjppTK82HawrL2+6ACfZrj+
-F2hwX359XH9Tj7T1X7t3awQ=
-=0PFi
------END PGP SIGNATURE-----
+P 6af2dca75b8139134ea394c1d71aefc6523f02e9
+R c94ad925a665396e6feea1ca0a681bf5
+U dan
+Z 86d18456fd55c8daa32a6607f2d982a8
-6af2dca75b8139134ea394c1d71aefc6523f02e9
\ No newline at end of file
+9803196dec85e3aa4105cc477e9cfe98d370e486
\ No newline at end of file
return pRet;
}
+#ifndef SQLITE_OMIT_WAL
+/*
+** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
+** Return non-zero, indicating to the caller that a checkpoint should be run,
+** if the number of frames in the log file is greater than
+** sqlite3.nDefaultCheckpoint (the value configured by wal_autocheckpoint()).
+*/
+static int defaultWalHook(void *p, sqlite3 *db, const char *z, int nFrame){
+ UNUSED_PARAMETER(p);
+ UNUSED_PARAMETER(z);
+ return ( nFrame>=db->nDefaultCheckpoint );
+}
+
+/*
+** Configure an sqlite3_wal_hook() callback to automatically checkpoint
+** a database after committing a transaction if there are nFrame or
+** more frames in the log file. Passing zero or a negative value as the
+** nFrame parameter disables automatic checkpoints entirely.
+**
+** The callback registered by this function replaces any existing callback
+** registered using sqlite3_wal_hook(). Likewise, registering a callback
+** using sqlite3_wal_hook() disables the automatic checkpoint mechanism
+** configured by this function.
+*/
+int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
+ sqlite3_mutex_enter(db->mutex);
+ if( nFrame>0 ){
+ db->nDefaultCheckpoint = nFrame;
+ sqlite3_wal_hook(db, defaultWalHook, 0);
+ }else{
+ sqlite3_wal_hook(db, 0, 0);
+ }
+ sqlite3_mutex_leave(db->mutex);
+ return SQLITE_OK;
+}
+
/*
** Register a callback to be invoked each time a transaction is written
** into the write-ahead-log by this database connection.
int(*xCallback)(void *, sqlite3*, const char*, int),
void *pArg /* First argument passed to xCallback() */
){
-#ifndef SQLITE_OMIT_WAL
void *pRet;
sqlite3_mutex_enter(db->mutex);
pRet = db->pWalArg;
db->pWalArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pRet;
-#else
+}
+
+/*
+** Checkpoint database zDb. If zDb is NULL, the main database is checkpointed.
+*/
+int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
+ int rc; /* Return code */
+ int iDb = 0; /* sqlite3.aDb[] index of db to checkpoint */
+
+ sqlite3_mutex_enter(db->mutex);
+ if( zDb ){
+ iDb = sqlite3FindDbName(db, zDb);
+ }
+ if( iDb<0 ){
+ rc = SQLITE_ERROR;
+ }else{
+ rc = sqlite3Checkpoint(db, iDb);
+ }
+ sqlite3_mutex_leave(db->mutex);
+
+ return rc;
+}
+
+/*
+** Run a checkpoint on database iDb. This is a no-op if database iDb is
+** not currently open in WAL mode.
+**
+** If a transaction is open at either the database handle (db) or b-tree
+** level, this function returns SQLITE_LOCKED and a checkpoint is not
+** attempted. If an error occurs while running the checkpoint, an SQLite
+** error code is returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK.
+**
+** The mutex on database handle db should be held by the caller. The mutex
+** associated with the specific b-tree being checkpointed is taken by
+** this function while the checkpoint is running.
+*/
+int sqlite3Checkpoint(sqlite3 *db, int iDb){
+ Btree *pBt; /* Btree handle to checkpoint */
+ int rc; /* Return code */
+
+ assert( sqlite3_mutex_held(db->mutex) );
+
+ pBt = db->aDb[iDb].pBt;
+ if( sqlite3BtreeIsInReadTrans(pBt) ){
+ rc = SQLITE_LOCKED;
+ }else{
+ sqlite3BtreeEnter(pBt);
+ rc = sqlite3PagerCheckpoint(sqlite3BtreePager(pBt));
+ sqlite3BtreeLeave(pBt);
+ }
+
+ return rc;
+}
+#else /* ifndef SQLITE_OMIT_WAL */
+/*
+** If SQLITE_OMIT_WAL is defined, the following API functions are no-ops:
+**
+** sqlite3_wal_hook()
+** sqlite3_wal_checkpoint()
+** sqlite3_wal_autocheckpoint()
+*/
+void *sqlite3_wal_hook(
+ sqlite3 *x,
+ int(*xCallback)(void *, sqlite3*, const char*, int),
+ void *pArg
+){
return 0;
-#endif
}
+int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ return SQLITE_OK; }
+int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){ return SQLITE_OK; }
+#endif
/*
** This function returns true if main-memory should be used instead of
setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
sqlite3GlobalConfig.nLookaside);
+ sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_CACHE_SIZE);
+
opendb_out:
if( db ){
assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
** Checkpoint the database.
*/
if( sqlite3StrICmp(zLeft, "checkpoint")==0 ){
- sqlite3VdbeUsesBtree(v, iDb);
sqlite3VdbeAddOp3(v, OP_Checkpoint, iDb, 0, 0);
}else
#endif
void*
);
+/*
+** CAPI3REF: Configure an auto-checkpoint
+*/
+int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
+
+/*
+** CAPI3REF: Checkpoint a database
+*/
+int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+
/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
void *pUpdateArg;
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
#ifndef SQLITE_OMIT_WAL
+ int nDefaultCheckpoint; /* Value configured by wal_autocheckpoint() */
int (*xWalCallback)(void *, sqlite3 *, const char *, int);
void *pWalArg;
#endif
int sqlite3TempInMemory(const sqlite3*);
VTable *sqlite3GetVTable(sqlite3*, Table*);
const char *sqlite3JournalModename(int);
+int sqlite3Checkpoint(sqlite3*, int);
/* Declarations for functions in fkey.c. All of these are replaced by
** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
** WAL mode.
*/
case OP_Checkpoint: {
- Btree *pBt; /* Btree to checkpoint */
-
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pBt = db->aDb[pOp->p1].pBt;
- rc = sqlite3PagerCheckpoint(sqlite3BtreePager(pBt));
+ rc = sqlite3Checkpoint(db, pOp->p1);
break;
};
#endif
# 3) Backing up memory-to-file.
#
set iTest 0
+file delete -force bak.db-wal
foreach {writer file} {db test.db db3 test.db db :memory:} {
incr iTest
catch { file delete bak.db }
# very large wal file (one that requires a wal-index larger than the
# initial default allocation of 64KB).
#
-# When recovering a log file, mutexes are usually obtained and released
-# as follows:
-#
-# xShmGet ENTER mutexBuf
-# xShmLock(RECOVER) ENTER mutexRecov
-# <do recovery work>
-# xShmLock(READ) LEAVE mutexRecov
-# xShmRelease LEAVE mutexBuf
-#
-# However, if the initial wal-index allocation needs to be enlarged during
-# the recovery process, the mutex operations become:
-#
-# xShmGet ENTER mutexBuf
-# xShmLock(RECOVER) ENTER mutexRecov
-# <do first part of recovery work>
-# xShmRelease LEAVE mutexBuf
-# xShmSize
-# xShmGet ENTER mutexBuf
-# <do second part of recovery work>
-# xShmLock(READ) LEAVE mutexRecov
-# xShmRelease LEAVE mutexBuf
-#
-# If multiple threads attempt the above simultaneously, deadlock can occur.
-#
do_thread_test walthread-5 -seconds $seconds(walthread-5) -init {
proc log_file_size {nFrame pgsz} {