Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the sqlite3_wal_checkpoint() and sqlite3_wal_autocheckpoint() APIs. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | wal |
Files: | files | file ages | folders |
SHA1: |
9803196dec85e3aa4105cc477e9cfe98 |
User & Date: | dan 2010-05-03 08:04:49.000 |
Context
2010-05-03
| ||
08:19 | Merge two wal leaves. (check-in: 23c0e6c3f3 user: dan tags: wal) | |
08:04 | Add the sqlite3_wal_checkpoint() and sqlite3_wal_autocheckpoint() APIs. (check-in: 9803196dec user: dan tags: wal) | |
2010-05-01
| ||
17:57 | Define an invariant to guarantee deadlock-free operation of SHM in os_unix.c and check that invariant with assert() statements. (check-in: 6af2dca75b user: drh tags: wal) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 | sqlite3_mutex_enter(db->mutex); pRet = db->pRollbackArg; db->xRollbackCallback = xCallback; db->pRollbackArg = pArg; sqlite3_mutex_leave(db->mutex); return pRet; } /* ** Register a callback to be invoked each time a transaction is written ** into the write-ahead-log by this database connection. */ void *sqlite3_wal_hook( sqlite3 *db, /* Attach the hook to this db handle */ int(*xCallback)(void *, sqlite3*, const char*, int), void *pArg /* First argument passed to xCallback() */ ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < > > > > > > > > > > > > > > > | > > > > | > | > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 | sqlite3_mutex_enter(db->mutex); pRet = db->pRollbackArg; db->xRollbackCallback = xCallback; db->pRollbackArg = pArg; sqlite3_mutex_leave(db->mutex); 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. */ void *sqlite3_wal_hook( sqlite3 *db, /* Attach the hook to this db handle */ int(*xCallback)(void *, sqlite3*, const char*, int), void *pArg /* First argument passed to xCallback() */ ){ void *pRet; sqlite3_mutex_enter(db->mutex); pRet = db->pWalArg; db->xWalCallback = xCallback; db->pWalArg = pArg; sqlite3_mutex_leave(db->mutex); return pRet; } /* ** 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; } 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 ** a temporary file for transient pager files and statement journals. ** The value returned depends on the value of db->temp_store (runtime ** parameter) and the compile time value of SQLITE_TEMP_STORE. The ** following table describes the relationship between these two values |
︙ | ︙ | |||
1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 | sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), SQLITE_DEFAULT_LOCKING_MODE); #endif /* Enable the lookaside-malloc subsystem */ setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, sqlite3GlobalConfig.nLookaside); opendb_out: if( db ){ assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 ); sqlite3_mutex_leave(db->mutex); } rc = sqlite3_errcode(db); | > > | 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 | sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), SQLITE_DEFAULT_LOCKING_MODE); #endif /* Enable the lookaside-malloc subsystem */ 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 ); sqlite3_mutex_leave(db->mutex); } rc = sqlite3_errcode(db); |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
1403 1404 1405 1406 1407 1408 1409 | #ifndef SQLITE_OMIT_WAL /* ** PRAGMA [database.]checkpoint ** ** Checkpoint the database. */ if( sqlite3StrICmp(zLeft, "checkpoint")==0 ){ | < | 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 | #ifndef SQLITE_OMIT_WAL /* ** PRAGMA [database.]checkpoint ** ** Checkpoint the database. */ if( sqlite3StrICmp(zLeft, "checkpoint")==0 ){ sqlite3VdbeAddOp3(v, OP_Checkpoint, iDb, 0, 0); }else #endif #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* ** Report the current state of file logs for all databases |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 | */ void *sqlite3_wal_hook( sqlite3*, int(*)(void *,sqlite3*,const char*,int), void* ); /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif | > > > > > > > > > > | 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 | */ void *sqlite3_wal_hook( sqlite3*, int(*)(void *,sqlite3*,const char*,int), 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. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
820 821 822 823 824 825 826 827 828 829 830 831 832 833 | void *pCommitArg; /* Argument to xCommitCallback() */ int (*xCommitCallback)(void*); /* Invoked at every commit. */ void *pRollbackArg; /* Argument to xRollbackCallback() */ void (*xRollbackCallback)(void*); /* Invoked at every commit. */ void *pUpdateArg; void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64); #ifndef SQLITE_OMIT_WAL int (*xWalCallback)(void *, sqlite3 *, const char *, int); void *pWalArg; #endif void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); void *pCollNeededArg; sqlite3_value *pErr; /* Most recent error message */ | > | 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 | void *pCommitArg; /* Argument to xCommitCallback() */ int (*xCommitCallback)(void*); /* Invoked at every commit. */ void *pRollbackArg; /* Argument to xRollbackCallback() */ void (*xRollbackCallback)(void*); /* Invoked at every commit. */ 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 void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); void *pCollNeededArg; sqlite3_value *pErr; /* Most recent error message */ |
︙ | ︙ | |||
2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 | int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); int sqlite3Reprepare(Vdbe*); void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); int sqlite3TempInMemory(const sqlite3*); VTable *sqlite3GetVTable(sqlite3*, Table*); const char *sqlite3JournalModename(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 ** key functionality is available. If OMIT_TRIGGER is defined but ** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In ** this case foreign keys are parsed, but no other functionality is ** provided (enforcement of FK constraints requires the triggers sub-system). | > | 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 | int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); int sqlite3Reprepare(Vdbe*); void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); 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 ** key functionality is available. If OMIT_TRIGGER is defined but ** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In ** this case foreign keys are parsed, but no other functionality is ** provided (enforcement of FK constraints requires the triggers sub-system). |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
5189 5190 5191 5192 5193 5194 5195 | #ifndef SQLITE_OMIT_WAL /* Opcode: Checkpoint P1 * * * * ** ** Checkpoint database P1. This is a no-op if P1 is not currently in ** WAL mode. */ case OP_Checkpoint: { | < | < < < < | 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 | #ifndef SQLITE_OMIT_WAL /* Opcode: Checkpoint P1 * * * * ** ** Checkpoint database P1. This is a no-op if P1 is not currently in ** WAL mode. */ case OP_Checkpoint: { rc = sqlite3Checkpoint(db, pOp->p1); break; }; #endif /* Opcode: JournalMode P1 P2 P3 * * ** ** Change the journal mode of database P1 to P3. P3 must be one of the |
︙ | ︙ |
Changes to test/backup.test.
︙ | ︙ | |||
485 486 487 488 489 490 491 492 493 494 495 496 497 498 | # # 1) Backing up file-to-file. The writer writes via an external pager. # 2) Backing up file-to-file. The writer writes via the same pager as # is used by the backup operation. # 3) Backing up memory-to-file. # set iTest 0 foreach {writer file} {db test.db db3 test.db db :memory:} { incr iTest catch { file delete bak.db } sqlite3 db2 bak.db catch { file delete $file } sqlite3 db $file sqlite3 db3 $file | > | 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | # # 1) Backing up file-to-file. The writer writes via an external pager. # 2) Backing up file-to-file. The writer writes via the same pager as # is used by the backup operation. # 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 } sqlite3 db2 bak.db catch { file delete $file } sqlite3 db $file sqlite3 db3 $file |
︙ | ︙ |
Changes to test/walthread.test.
︙ | ︙ | |||
458 459 460 461 462 463 464 | # This test case attempts to provoke a deadlock condition that existed in # the unix VFS at one point. The problem occurred only while recovering a # very large wal file (one that requires a wal-index larger than the # initial default allocation of 64KB). # | < < < < < < < < < < < < < < < < < < < < < < < < | 458 459 460 461 462 463 464 465 466 467 468 469 470 471 | # This test case attempts to provoke a deadlock condition that existed in # the unix VFS at one point. The problem occurred only while recovering a # very large wal file (one that requires a wal-index larger than the # initial default allocation of 64KB). # do_thread_test walthread-5 -seconds $seconds(walthread-5) -init { proc log_file_size {nFrame pgsz} { expr {12 + ($pgsz+16)*$nFrame} } execsql { |
︙ | ︙ |