mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Modify the interface to the blocking wal-checkpoint functionality.
FossilOrigin-Name: 72787c010c8944e8fcf9c98aa4482f129142d8e9
This commit is contained in:
37
manifest
37
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\sexperimental\scommand\s"PRAGMA\swal_blocking_checkpoint",\swhich\suses\sthe\sbusy-handler\sto\sblock\suntil\sall\sreaders\shave\sfinished\sin\sorder\sto\sensure\sthe\snext\swriter\swill\sbe\sable\sto\swrap\saround\sto\sthe\sstart\sof\sthe\slog\sfile.
|
C Modify\sthe\sinterface\sto\sthe\sblocking\swal-checkpoint\sfunctionality.
|
||||||
D 2010-11-16T18:56:51
|
D 2010-11-18T12:11:05
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in e7a59672eaeb04408d1fa8501618d7501a3c5e39
|
F Makefile.in e7a59672eaeb04408d1fa8501618d7501a3c5e39
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -119,8 +119,8 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
|||||||
F src/backup.c d5b0137bc20327af08c14772227cc35134839c30
|
F src/backup.c d5b0137bc20327af08c14772227cc35134839c30
|
||||||
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
|
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
|
||||||
F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
|
F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
|
||||||
F src/btree.c 444aae4fc60cc57d6c97615358e1020f6884cca6
|
F src/btree.c d90149f6e0a6f715b58b272ef1028fa249a2a088
|
||||||
F src/btree.h d1144d38d790a8b7b2e215043f8d068f4f37de07
|
F src/btree.h 1d62748eb7d129292782cf65b891b85cbfa024d4
|
||||||
F src/btreeInt.h c424f2f131cc61ddf130f9bd736b3df12c8a51f0
|
F src/btreeInt.h c424f2f131cc61ddf130f9bd736b3df12c8a51f0
|
||||||
F src/build.c 00a327120d81ace6267e714ae8010c997d55de5d
|
F src/build.c 00a327120d81ace6267e714ae8010c997d55de5d
|
||||||
F src/callback.c a1d1b1c9c85415dff013af033e2fed9c8382d33b
|
F src/callback.c a1d1b1c9c85415dff013af033e2fed9c8382d33b
|
||||||
@@ -141,7 +141,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
|
|||||||
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
||||||
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
|
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
|
||||||
F src/loadext.c 8af9fcc75708d60b88636ccba38b4a7b3c155c3e
|
F src/loadext.c 8af9fcc75708d60b88636ccba38b4a7b3c155c3e
|
||||||
F src/main.c 89c658ae9a610a61ff856a110bda50606e9227d6
|
F src/main.c 91465f2658911ddb51be89e7b8ee01af8584308f
|
||||||
F src/malloc.c 3d7284cd9346ab6e3945535761e68c23c6cf40ef
|
F src/malloc.c 3d7284cd9346ab6e3945535761e68c23c6cf40ef
|
||||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||||
F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
|
F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
|
||||||
@@ -162,13 +162,13 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
|
|||||||
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
|
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
|
||||||
F src/os_unix.c de5be4cdbf3d07018059934eaf7e5d8d594a895c
|
F src/os_unix.c de5be4cdbf3d07018059934eaf7e5d8d594a895c
|
||||||
F src/os_win.c 2f90f7bdec714fad51cd31b4ecad3cc1b4bb5aad
|
F src/os_win.c 2f90f7bdec714fad51cd31b4ecad3cc1b4bb5aad
|
||||||
F src/pager.c 7f7587c2f11126d13ee1925ac8960a9e7ab13e8a
|
F src/pager.c b46a78a196d99bc855eec3c602777a1bc8db5122
|
||||||
F src/pager.h ad7d8db0fbcee7546dbc02ffe0d0d44ea868ef52
|
F src/pager.h e2485f2f2fa5264f2bb68d1783c149d3d57d3637
|
||||||
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
|
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
|
||||||
F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa
|
F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa
|
||||||
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
|
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
|
||||||
F src/pcache1.c e9578a3beac26f229ee558a4e16c863f2498185f
|
F src/pcache1.c e9578a3beac26f229ee558a4e16c863f2498185f
|
||||||
F src/pragma.c 66a8b53d1e74635011fbb0bb54b7ecc402684bae
|
F src/pragma.c f843c877845ddbb911f10eea50c9290bc8354b03
|
||||||
F src/prepare.c c2b318037d626fed27905c9446730b560637217a
|
F src/prepare.c c2b318037d626fed27905c9446730b560637217a
|
||||||
F src/printf.c 8ae5082dd38a1b5456030c3755ec3a392cd51506
|
F src/printf.c 8ae5082dd38a1b5456030c3755ec3a392cd51506
|
||||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||||
@@ -176,9 +176,9 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
|
|||||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||||
F src/select.c 550d67688f5e8bc8022faf6d014838afba1415af
|
F src/select.c 550d67688f5e8bc8022faf6d014838afba1415af
|
||||||
F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056
|
F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056
|
||||||
F src/sqlite.h.in f47e09412fc9a129f759fa4d96ef21f4b3d529eb
|
F src/sqlite.h.in 4645a3bddf4481fcc9422ba41acf4e71c1c81e22
|
||||||
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
|
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
|
||||||
F src/sqliteInt.h fe1cb073b2707001985f06dee9ee256247e4d0ce
|
F src/sqliteInt.h 4e7045f17606296bc8e7898d69567fc3cd06b761
|
||||||
F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44
|
F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44
|
||||||
F src/status.c 496913d4e8441195f6f2a75b1c95993a45b9b30b
|
F src/status.c 496913d4e8441195f6f2a75b1c95993a45b9b30b
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
@@ -227,7 +227,7 @@ F src/update.c 227e6cd512108b84f69421fc6c7aa1b83d60d6e0
|
|||||||
F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
|
F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
|
||||||
F src/util.c cd78524566fe45671863eee78685969a4bfd4e4c
|
F src/util.c cd78524566fe45671863eee78685969a4bfd4e4c
|
||||||
F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f
|
F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f
|
||||||
F src/vdbe.c b86b09beb3dcf2e6d5922acee48b8a1c16b68bfd
|
F src/vdbe.c 4bec828e70654c698ef843c29b557bee2c8a0a00
|
||||||
F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2
|
F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2
|
||||||
F src/vdbeInt.h 7f4cf1b2b69bef3a432b1f23dfebef57275436b4
|
F src/vdbeInt.h 7f4cf1b2b69bef3a432b1f23dfebef57275436b4
|
||||||
F src/vdbeapi.c 5368714fa750270cf6430160287c21adff44582d
|
F src/vdbeapi.c 5368714fa750270cf6430160287c21adff44582d
|
||||||
@@ -236,8 +236,8 @@ F src/vdbeblob.c e0ce3c54cc0c183af2ec67b63a289acf92251df4
|
|||||||
F src/vdbemem.c 23723a12cd3ba7ab3099193094cbb2eb78956aa9
|
F src/vdbemem.c 23723a12cd3ba7ab3099193094cbb2eb78956aa9
|
||||||
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
|
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
|
||||||
F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30
|
F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30
|
||||||
F src/wal.c 400624ce58acce44f0bf0d47ed2f435da290fb04
|
F src/wal.c 8eca619a28a70a667c913e5927131250836377a2
|
||||||
F src/wal.h d5bbc11242d7fd14e9dc6a74f68d3ccaf01a9e48
|
F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840
|
||||||
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
||||||
F src/where.c d5cc65f51661a038a2c6a663a945d5cf4c277b81
|
F src/where.c d5cc65f51661a038a2c6a663a945d5cf4c277b81
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
@@ -827,7 +827,7 @@ F test/wal.test 70227190e713b3e7eb2a7d5ec3510b66db01f327
|
|||||||
F test/wal2.test c794b8b257af54190bb913678ad3984cbf3311b9
|
F test/wal2.test c794b8b257af54190bb913678ad3984cbf3311b9
|
||||||
F test/wal3.test 957a5f2a8fe8a6ff01de1a15285ecf2f376fcaf8
|
F test/wal3.test 957a5f2a8fe8a6ff01de1a15285ecf2f376fcaf8
|
||||||
F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30
|
F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30
|
||||||
F test/wal5.test e0f1abdff4f76d3a8531f5d0f4cb237e5eff891c
|
F test/wal5.test 4e2854d7584dd97a73e7ce0f47bcbbe5c592fe29
|
||||||
F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe
|
F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe
|
||||||
F test/walbak.test 4df1c7369da0301caeb9a48fa45997fd592380e4
|
F test/walbak.test 4df1c7369da0301caeb9a48fa45997fd592380e4
|
||||||
F test/walbig.test e882bc1d014afffbfa2b6ba36e0f07d30a633ad0
|
F test/walbig.test e882bc1d014afffbfa2b6ba36e0f07d30a633ad0
|
||||||
@@ -887,10 +887,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P 56bbc539246a6dc9f1ae1edb898db7a4f6f6d322
|
P 7e3fc2c833a5baa08820c499867b6902bdc2ed5a
|
||||||
R 75a04ae738d792c76538f98d6f9ad655
|
R 1672f1722e4277222ee64bddb8543abf
|
||||||
T *branch * experimental
|
|
||||||
T *sym-experimental *
|
|
||||||
T -sym-trunk *
|
|
||||||
U dan
|
U dan
|
||||||
Z b1cbb492cf90106bd968e524fdd11e16
|
Z 2e080f5eeb72d6f9662d3b3c376a7b7c
|
||||||
|
@@ -1 +1 @@
|
|||||||
7e3fc2c833a5baa08820c499867b6902bdc2ed5a
|
72787c010c8944e8fcf9c98aa4482f129142d8e9
|
11
src/btree.c
11
src/btree.c
@@ -7936,14 +7936,9 @@ int sqlite3BtreeIsInTrans(Btree *p){
|
|||||||
** Return SQLITE_LOCKED if this or any other connection has an open
|
** Return SQLITE_LOCKED if this or any other connection has an open
|
||||||
** transaction on the shared-cache the argument Btree is connected to.
|
** transaction on the shared-cache the argument Btree is connected to.
|
||||||
**
|
**
|
||||||
** If parameter bBlock is true, then the layers below invoke the
|
** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
|
||||||
** busy-handler callback while waiting for readers to release locks so
|
|
||||||
** that the entire WAL can be checkpointed. If it is false, then as
|
|
||||||
** much as possible of the WAL is checkpointed without waiting for readers
|
|
||||||
** to finish. bBlock is true for "PRAGMA wal_blocking_checkpoint" and false
|
|
||||||
** for "PRAGMA wal_checkpoint".
|
|
||||||
*/
|
*/
|
||||||
int sqlite3BtreeCheckpoint(Btree *p, int bBlock){
|
int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
if( p ){
|
if( p ){
|
||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
@@ -7951,7 +7946,7 @@ int sqlite3BtreeCheckpoint(Btree *p, int bBlock){
|
|||||||
if( pBt->inTransaction!=TRANS_NONE ){
|
if( pBt->inTransaction!=TRANS_NONE ){
|
||||||
rc = SQLITE_LOCKED;
|
rc = SQLITE_LOCKED;
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3PagerCheckpoint(pBt->pPager, bBlock);
|
rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt);
|
||||||
}
|
}
|
||||||
sqlite3BtreeLeave(p);
|
sqlite3BtreeLeave(p);
|
||||||
}
|
}
|
||||||
|
@@ -207,7 +207,7 @@ void sqlite3BtreeCursorList(Btree*);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_WAL
|
#ifndef SQLITE_OMIT_WAL
|
||||||
int sqlite3BtreeCheckpoint(Btree*, int);
|
int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
39
src/main.c
39
src/main.c
@@ -1340,19 +1340,29 @@ void *sqlite3_wal_hook(
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points
|
** Checkpoint database zDb.
|
||||||
** to contains a zero-length string, all attached databases are
|
|
||||||
** checkpointed.
|
|
||||||
*/
|
*/
|
||||||
int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
|
int sqlite3_wal_checkpoint_v2(
|
||||||
|
sqlite3 *db, /* Database handle */
|
||||||
|
const char *zDb, /* Name of attached database (or NULL) */
|
||||||
|
int eMode, /* SQLITE_CHECKPOINT_* value */
|
||||||
|
int *pnLog, /* OUT: Size of WAL log in frames */
|
||||||
|
int *pnCkpt /* OUT: Total number of frames checkpointed */
|
||||||
|
){
|
||||||
#ifdef SQLITE_OMIT_WAL
|
#ifdef SQLITE_OMIT_WAL
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
#else
|
#else
|
||||||
int rc; /* Return code */
|
int rc; /* Return code */
|
||||||
int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */
|
int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */
|
||||||
|
|
||||||
|
if( eMode!=SQLITE_CHECKPOINT_PASSIVE
|
||||||
|
&& eMode!=SQLITE_CHECKPOINT_FULL
|
||||||
|
&& eMode!=SQLITE_CHECKPOINT_RESTART
|
||||||
|
){
|
||||||
|
return SQLITE_MISUSE;
|
||||||
|
}
|
||||||
|
|
||||||
sqlite3_mutex_enter(db->mutex);
|
sqlite3_mutex_enter(db->mutex);
|
||||||
if( zDb && zDb[0] ){
|
if( zDb && zDb[0] ){
|
||||||
iDb = sqlite3FindDbName(db, zDb);
|
iDb = sqlite3FindDbName(db, zDb);
|
||||||
@@ -1361,7 +1371,7 @@ int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
|
|||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
sqlite3Error(db, SQLITE_ERROR, "unknown database: %s", zDb);
|
sqlite3Error(db, SQLITE_ERROR, "unknown database: %s", zDb);
|
||||||
}else{
|
}else{
|
||||||
rc = sqlite3Checkpoint(db, iDb, 0);
|
rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
|
||||||
sqlite3Error(db, rc, 0);
|
sqlite3Error(db, rc, 0);
|
||||||
}
|
}
|
||||||
rc = sqlite3ApiExit(db, rc);
|
rc = sqlite3ApiExit(db, rc);
|
||||||
@@ -1370,6 +1380,16 @@ int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points
|
||||||
|
** to contains a zero-length string, all attached databases are
|
||||||
|
** checkpointed.
|
||||||
|
*/
|
||||||
|
int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
|
||||||
|
return sqlite3_wal_checkpoint_v2(db, zDb, SQLITE_CHECKPOINT_PASSIVE, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_WAL
|
#ifndef SQLITE_OMIT_WAL
|
||||||
/*
|
/*
|
||||||
** Run a checkpoint on database iDb. This is a no-op if database iDb is
|
** Run a checkpoint on database iDb. This is a no-op if database iDb is
|
||||||
@@ -1388,10 +1408,9 @@ int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
|
|||||||
** checkpointed. If an error is encountered it is returned immediately -
|
** checkpointed. If an error is encountered it is returned immediately -
|
||||||
** no attempt is made to checkpoint any remaining databases.
|
** no attempt is made to checkpoint any remaining databases.
|
||||||
**
|
**
|
||||||
** Parameter bBlock is true for a blocking-checkpoint, false for an
|
** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
|
||||||
** ordinary, non-blocking, checkpoint.
|
|
||||||
*/
|
*/
|
||||||
int sqlite3Checkpoint(sqlite3 *db, int iDb, int bBlock){
|
int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){
|
||||||
int rc = SQLITE_OK; /* Return code */
|
int rc = SQLITE_OK; /* Return code */
|
||||||
int i; /* Used to iterate through attached dbs */
|
int i; /* Used to iterate through attached dbs */
|
||||||
|
|
||||||
@@ -1399,7 +1418,7 @@ int sqlite3Checkpoint(sqlite3 *db, int iDb, int bBlock){
|
|||||||
|
|
||||||
for(i=0; i<db->nDb && rc==SQLITE_OK; i++){
|
for(i=0; i<db->nDb && rc==SQLITE_OK; i++){
|
||||||
if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){
|
if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){
|
||||||
rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, bBlock);
|
rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
src/pager.c
13
src/pager.c
@@ -6520,17 +6520,16 @@ sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
|
|||||||
** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
|
** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
|
||||||
** or wal_blocking_checkpoint() API functions.
|
** or wal_blocking_checkpoint() API functions.
|
||||||
**
|
**
|
||||||
** Parameter bBlock is true for a blocking-checkpoint, false for an
|
** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
|
||||||
** ordinary, non-blocking, checkpoint.
|
|
||||||
*/
|
*/
|
||||||
int sqlite3PagerCheckpoint(Pager *pPager, int bBlock){
|
int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
if( pPager->pWal ){
|
if( pPager->pWal ){
|
||||||
u8 *zBuf = (u8 *)pPager->pTmpSpace;
|
rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
|
||||||
rc = sqlite3WalCheckpoint(pPager->pWal,
|
pPager->xBusyHandler, pPager->pBusyHandlerArg,
|
||||||
(bBlock ? pPager->xBusyHandler : 0), pPager->pBusyHandlerArg,
|
|
||||||
(pPager->noSync ? 0 : pPager->sync_flags),
|
(pPager->noSync ? 0 : pPager->sync_flags),
|
||||||
pPager->pageSize, zBuf
|
pPager->pageSize, (u8 *)pPager->pTmpSpace,
|
||||||
|
pnLog, pnCkpt
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
@@ -138,7 +138,7 @@ int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
|
|||||||
int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
|
int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
|
||||||
int sqlite3PagerSharedLock(Pager *pPager);
|
int sqlite3PagerSharedLock(Pager *pPager);
|
||||||
|
|
||||||
int sqlite3PagerCheckpoint(Pager *pPager, int);
|
int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
|
||||||
int sqlite3PagerWalSupported(Pager *pPager);
|
int sqlite3PagerWalSupported(Pager *pPager);
|
||||||
int sqlite3PagerWalCallback(Pager *pPager);
|
int sqlite3PagerWalCallback(Pager *pPager);
|
||||||
int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
|
int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
|
||||||
|
26
src/pragma.c
26
src/pragma.c
@@ -1393,19 +1393,29 @@ void sqlite3Pragma(
|
|||||||
|
|
||||||
#ifndef SQLITE_OMIT_WAL
|
#ifndef SQLITE_OMIT_WAL
|
||||||
/*
|
/*
|
||||||
** PRAGMA [database.]wal_checkpoint
|
** PRAGMA [database.]wal_checkpoint = passive|full|restart
|
||||||
** PRAGMA [database.]wal_blocking_checkpoint
|
|
||||||
**
|
**
|
||||||
** Checkpoint the database.
|
** Checkpoint the database.
|
||||||
*/
|
*/
|
||||||
if( sqlite3StrICmp(zLeft, "wal_checkpoint")==0
|
if( sqlite3StrICmp(zLeft, "wal_checkpoint")==0 ){
|
||||||
|| sqlite3StrICmp(zLeft, "wal_blocking_checkpoint")==0
|
|
||||||
){
|
|
||||||
int bBlock = (zLeft[14]!=0);
|
|
||||||
int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
|
int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
|
||||||
assert( bBlock==(sqlite3StrICmp(zLeft, "wal_checkpoint")!=0) );
|
int eMode = SQLITE_CHECKPOINT_PASSIVE;
|
||||||
|
if( zRight ){
|
||||||
|
if( sqlite3StrICmp(zRight, "full")==0 ){
|
||||||
|
eMode = SQLITE_CHECKPOINT_FULL;
|
||||||
|
}else if( sqlite3StrICmp(zRight, "restart")==0 ){
|
||||||
|
eMode = SQLITE_CHECKPOINT_RESTART;
|
||||||
|
}
|
||||||
|
}
|
||||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||||
sqlite3VdbeAddOp2(v, OP_Checkpoint, iBt, bBlock);
|
sqlite3VdbeSetNumCols(v, 3);
|
||||||
|
pParse->nMem = 3;
|
||||||
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC);
|
||||||
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC);
|
||||||
|
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC);
|
||||||
|
|
||||||
|
sqlite3VdbeAddOp2(v, OP_Checkpoint, iBt, eMode);
|
||||||
|
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -6145,6 +6145,89 @@ int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
|
|||||||
*/
|
*/
|
||||||
int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
|
int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
|
||||||
|
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** CAPI3REF: Checkpoint a database
|
||||||
|
**
|
||||||
|
** Run a checkpoint operation on WAL database zDb attached to database
|
||||||
|
** handle db. The specific operation is determined by the value of the
|
||||||
|
** eMode parameter:
|
||||||
|
**
|
||||||
|
** <dl>
|
||||||
|
** <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
|
||||||
|
** Checkpoint as many frames as possible without waiting for any database
|
||||||
|
** readers or writers to finish. Sync the db file if all frames in the log
|
||||||
|
** are checkpointed. This mode is the same as calling
|
||||||
|
** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked.
|
||||||
|
**
|
||||||
|
** <dt>SQLITE_CHECKPOINT_FULL<dd>
|
||||||
|
** This mode blocks (calls the busy-handler callback) until there is no
|
||||||
|
** database writer and all readers are reading from the most recent database
|
||||||
|
** snapshot. It then checkpoints all frames in the log file and syncs the
|
||||||
|
** database file. This call blocks database writers while it is running,
|
||||||
|
** but not database readers.
|
||||||
|
**
|
||||||
|
** <dt>SQLITE_CHECKPOINT_RESTART<dd>
|
||||||
|
** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after
|
||||||
|
** checkpointing the log file it blocks (calls the busy-handler callback)
|
||||||
|
** until all readers are reading from the database file only. This ensures
|
||||||
|
** that the next client to write to the database file restarts the log file
|
||||||
|
** from the beginning. This call blocks database writers while it is running,
|
||||||
|
** but not database readers.
|
||||||
|
** </dl>
|
||||||
|
**
|
||||||
|
** If pnLog is not NULL, then *pnLog is set to the total number of frames in
|
||||||
|
** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to
|
||||||
|
** the total number of checkpointed frames (including any that were already
|
||||||
|
** checkpointed when this function is called). *pnLog and *pnCkpt may be
|
||||||
|
** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK.
|
||||||
|
** If no values are available because of an error, they are both set to -1
|
||||||
|
** before returning to communicate this to the caller.
|
||||||
|
**
|
||||||
|
** All calls obtain an exclusive "checkpoint" lock on the database file. If
|
||||||
|
** any other process is running a checkpoint operation at the same time, the
|
||||||
|
** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a
|
||||||
|
** busy-handler configured, it will not be invoked in this case.
|
||||||
|
**
|
||||||
|
** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive
|
||||||
|
** "writer" lock on the database file. If the writer lock cannot be obtained
|
||||||
|
** immediately, and a busy-handler is configured, it is invoked and the writer
|
||||||
|
** lock retried until either the busy-handler returns 0 or the lock is
|
||||||
|
** successfully obtained. The busy-handler is also invoked while waiting for
|
||||||
|
** database readers as described above. If the busy-handler returns 0 before
|
||||||
|
** the writer lock is obtained or while waiting for database readers, the
|
||||||
|
** checkpoint operation proceeds from that point in the same way as
|
||||||
|
** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible
|
||||||
|
** without blocking any further. SQLITE_BUSY is returned in this case.
|
||||||
|
**
|
||||||
|
** If parameter zDb is NULL or points to a zero length string, then the
|
||||||
|
** specified operation is attempted on all WAL databases. In this case the
|
||||||
|
** values written to output parameters *pnLog and *pnCkpt are undefined. If
|
||||||
|
** an SQLITE_BUSY error is encountered when processing one or more of the
|
||||||
|
** attached WAL databases, the operation is still attempted on any remaining
|
||||||
|
** attached databases and SQLITE_BUSY is returned to the caller. If any other
|
||||||
|
** error occurs while processing an attached database, processing is abandoned
|
||||||
|
** and the error code returned to the caller immediately. If no error
|
||||||
|
** (SQLITE_BUSY or otherwise) is encountered while processing the attached
|
||||||
|
** databases, SQLITE_OK is returned.
|
||||||
|
**
|
||||||
|
** If database zDb is the name of an attached database that is not in WAL
|
||||||
|
** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If
|
||||||
|
** zDb is not NULL (or a zero length string) and is not the name of any
|
||||||
|
** attached database, SQLITE_ERROR is returned to the caller.
|
||||||
|
*/
|
||||||
|
int sqlite3_wal_checkpoint_v2(
|
||||||
|
sqlite3 *db, /* Database handle */
|
||||||
|
const char *zDb, /* Name of attached database (or NULL) */
|
||||||
|
int eMode, /* SQLITE_CHECKPOINT_* value */
|
||||||
|
int *pnLog, /* OUT: Size of WAL log in frames */
|
||||||
|
int *pnCkpt /* OUT: Total number of frames checkpointed */
|
||||||
|
);
|
||||||
|
#define SQLITE_CHECKPOINT_PASSIVE 0
|
||||||
|
#define SQLITE_CHECKPOINT_FULL 1
|
||||||
|
#define SQLITE_CHECKPOINT_RESTART 2
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Undo the hack that converts floating point types to integer for
|
** Undo the hack that converts floating point types to integer for
|
||||||
** builds on processors without floating point support.
|
** builds on processors without floating point support.
|
||||||
|
@@ -3036,7 +3036,7 @@ CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
|
|||||||
int sqlite3TempInMemory(const sqlite3*);
|
int sqlite3TempInMemory(const sqlite3*);
|
||||||
VTable *sqlite3GetVTable(sqlite3*, Table*);
|
VTable *sqlite3GetVTable(sqlite3*, Table*);
|
||||||
const char *sqlite3JournalModename(int);
|
const char *sqlite3JournalModename(int);
|
||||||
int sqlite3Checkpoint(sqlite3*, int, int);
|
int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
|
||||||
int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
|
int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
|
||||||
|
|
||||||
/* Declarations for functions in fkey.c. All of these are replaced by
|
/* Declarations for functions in fkey.c. All of these are replaced by
|
||||||
|
26
src/vdbe.c
26
src/vdbe.c
@@ -5216,13 +5216,33 @@ case OP_AggFinal: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_WAL
|
#ifndef SQLITE_OMIT_WAL
|
||||||
/* Opcode: Checkpoint P1 P2 * * *
|
/* Opcode: Checkpoint P1 P2 P3 * *
|
||||||
**
|
**
|
||||||
** Checkpoint database P1. This is a no-op if P1 is not currently in
|
** Checkpoint database P1. This is a no-op if P1 is not currently in
|
||||||
** WAL mode. If P2 is non-zero, this is a blocking checkpoint.
|
** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL
|
||||||
|
** or RESTART.
|
||||||
*/
|
*/
|
||||||
case OP_Checkpoint: {
|
case OP_Checkpoint: {
|
||||||
rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2);
|
int nLog = -1; /* Number of pages in WAL log */
|
||||||
|
int nCkpt = -1; /* Number of checkpointed pages */
|
||||||
|
int bBusy = 0;
|
||||||
|
assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
|
||||||
|
|| pOp->p2==SQLITE_CHECKPOINT_FULL
|
||||||
|
|| pOp->p2==SQLITE_CHECKPOINT_RESTART
|
||||||
|
);
|
||||||
|
rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &nLog, &nCkpt);
|
||||||
|
if( rc==SQLITE_BUSY ){
|
||||||
|
rc = SQLITE_OK;
|
||||||
|
bBusy = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
aMem[1].u.i = bBusy;
|
||||||
|
aMem[2].u.i = nLog;
|
||||||
|
aMem[3].u.i = nCkpt;
|
||||||
|
MemSetTypeFlag(&aMem[1], MEM_Int);
|
||||||
|
MemSetTypeFlag(&aMem[2], MEM_Int);
|
||||||
|
MemSetTypeFlag(&aMem[3], MEM_Int);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
48
src/wal.c
48
src/wal.c
@@ -1576,11 +1576,13 @@ static int walBusyLock(
|
|||||||
*/
|
*/
|
||||||
static int walCheckpoint(
|
static int walCheckpoint(
|
||||||
Wal *pWal, /* Wal connection */
|
Wal *pWal, /* Wal connection */
|
||||||
|
int eMode, /* One of PASSIVE, FULL or RESTART */
|
||||||
int (*xBusy)(void*), /* Function to call when busy */
|
int (*xBusy)(void*), /* Function to call when busy */
|
||||||
void *pBusyArg, /* Context argument for xBusyHandler */
|
void *pBusyArg, /* Context argument for xBusyHandler */
|
||||||
int sync_flags, /* Flags for OsSync() (or 0) */
|
int sync_flags, /* Flags for OsSync() (or 0) */
|
||||||
int nBuf, /* Size of zBuf in bytes */
|
int nBuf, /* Size of zBuf in bytes */
|
||||||
u8 *zBuf /* Temporary buffer to use */
|
u8 *zBuf, /* Temporary buffer to use */
|
||||||
|
int *pnCkpt /* Total frames checkpointed */
|
||||||
){
|
){
|
||||||
int rc; /* Return code */
|
int rc; /* Return code */
|
||||||
int szPage; /* Database page-size */
|
int szPage; /* Database page-size */
|
||||||
@@ -1610,6 +1612,10 @@ static int walCheckpoint(
|
|||||||
goto walcheckpoint_out;
|
goto walcheckpoint_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pInfo = walCkptInfo(pWal);
|
||||||
|
mxPage = pWal->hdr.nPage;
|
||||||
|
if( pnCkpt ) *pnCkpt = pInfo->nBackfill;
|
||||||
|
|
||||||
/* Compute in mxSafeFrame the index of the last frame of the WAL that is
|
/* Compute in mxSafeFrame the index of the last frame of the WAL that is
|
||||||
** safe to write into the database. Frames beyond mxSafeFrame might
|
** safe to write into the database. Frames beyond mxSafeFrame might
|
||||||
** overwrite database pages that are in use by active readers and thus
|
** overwrite database pages that are in use by active readers and thus
|
||||||
@@ -1617,8 +1623,6 @@ static int walCheckpoint(
|
|||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
mxSafeFrame = pWal->hdr.mxFrame;
|
mxSafeFrame = pWal->hdr.mxFrame;
|
||||||
mxPage = pWal->hdr.nPage;
|
|
||||||
pInfo = walCkptInfo(pWal);
|
|
||||||
for(i=1; i<WAL_NREADER; i++){
|
for(i=1; i<WAL_NREADER; i++){
|
||||||
u32 y = pInfo->aReadMark[i];
|
u32 y = pInfo->aReadMark[i];
|
||||||
if( mxSafeFrame>=y ){
|
if( mxSafeFrame>=y ){
|
||||||
@@ -1634,7 +1638,8 @@ static int walCheckpoint(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}while( xBusy && mxSafeFrame<pWal->hdr.mxFrame && xBusy(pBusyArg) );
|
}while( eMode!=SQLITE_CHECKPOINT_PASSIVE
|
||||||
|
&& xBusy && mxSafeFrame<pWal->hdr.mxFrame && xBusy(pBusyArg) );
|
||||||
|
|
||||||
if( pInfo->nBackfill<mxSafeFrame
|
if( pInfo->nBackfill<mxSafeFrame
|
||||||
&& (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0), 1))==SQLITE_OK
|
&& (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0), 1))==SQLITE_OK
|
||||||
@@ -1685,19 +1690,12 @@ static int walCheckpoint(
|
|||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
pInfo->nBackfill = mxSafeFrame;
|
pInfo->nBackfill = mxSafeFrame;
|
||||||
|
if( pnCkpt ) *pnCkpt = mxSafeFrame;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the reader lock held while backfilling */
|
/* Release the reader lock held while backfilling */
|
||||||
walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
|
walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
|
||||||
|
|
||||||
if( xBusy && rc==SQLITE_OK && pWal->hdr.mxFrame==mxSafeFrame ){
|
|
||||||
assert( pWal->writeLock );
|
|
||||||
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
|
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( rc==SQLITE_BUSY ){
|
if( rc==SQLITE_BUSY ){
|
||||||
@@ -1706,6 +1704,17 @@ static int walCheckpoint(
|
|||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( rc==SQLITE_OK
|
||||||
|
&& eMode==SQLITE_CHECKPOINT_RESTART
|
||||||
|
&& pWal->hdr.mxFrame==mxSafeFrame
|
||||||
|
){
|
||||||
|
assert( pWal->writeLock );
|
||||||
|
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
walcheckpoint_out:
|
walcheckpoint_out:
|
||||||
walIteratorFree(pIter);
|
walIteratorFree(pIter);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1737,7 +1746,9 @@ int sqlite3WalClose(
|
|||||||
if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
|
if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
|
||||||
pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
|
pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
|
||||||
}
|
}
|
||||||
rc = sqlite3WalCheckpoint(pWal, 0, 0, sync_flags, nBuf, zBuf);
|
rc = sqlite3WalCheckpoint(
|
||||||
|
pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
|
||||||
|
);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
isDelete = 1;
|
isDelete = 1;
|
||||||
}
|
}
|
||||||
@@ -2658,11 +2669,14 @@ int sqlite3WalFrames(
|
|||||||
*/
|
*/
|
||||||
int sqlite3WalCheckpoint(
|
int sqlite3WalCheckpoint(
|
||||||
Wal *pWal, /* Wal connection */
|
Wal *pWal, /* Wal connection */
|
||||||
|
int eMode, /* PASSIVE, FULL or RESTART */
|
||||||
int (*xBusy)(void*), /* Function to call when busy */
|
int (*xBusy)(void*), /* Function to call when busy */
|
||||||
void *pBusyArg, /* Context argument for xBusyHandler */
|
void *pBusyArg, /* Context argument for xBusyHandler */
|
||||||
int sync_flags, /* Flags to sync db file with (or 0) */
|
int sync_flags, /* Flags to sync db file with (or 0) */
|
||||||
int nBuf, /* Size of temporary buffer */
|
int nBuf, /* Size of temporary buffer */
|
||||||
u8 *zBuf /* Temporary buffer to use */
|
u8 *zBuf, /* Temporary buffer to use */
|
||||||
|
int *pnLog, /* OUT: Number of frames in WAL */
|
||||||
|
int *pnCkpt /* OUT: Number of backfilled frames in WAL */
|
||||||
){
|
){
|
||||||
int rc; /* Return code */
|
int rc; /* Return code */
|
||||||
int isChanged = 0; /* True if a new wal-index header is loaded */
|
int isChanged = 0; /* True if a new wal-index header is loaded */
|
||||||
@@ -2684,7 +2698,7 @@ int sqlite3WalCheckpoint(
|
|||||||
** to prevent any writers from running while the checkpoint is underway.
|
** to prevent any writers from running while the checkpoint is underway.
|
||||||
** This has to be done before the call to walIndexReadHdr() below.
|
** This has to be done before the call to walIndexReadHdr() below.
|
||||||
*/
|
*/
|
||||||
if( xBusy ){
|
if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
|
||||||
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
|
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
|
||||||
if( rc==SQLITE_OK ) pWal->writeLock = 1;
|
if( rc==SQLITE_OK ) pWal->writeLock = 1;
|
||||||
}
|
}
|
||||||
@@ -2694,7 +2708,9 @@ int sqlite3WalCheckpoint(
|
|||||||
rc = walIndexReadHdr(pWal, &isChanged);
|
rc = walIndexReadHdr(pWal, &isChanged);
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = walCheckpoint(pWal, xBusy, pBusyArg, sync_flags, nBuf, zBuf);
|
if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
|
||||||
|
rc = walCheckpoint(
|
||||||
|
pWal, eMode, xBusy, pBusyArg, sync_flags, nBuf, zBuf, pnCkpt);
|
||||||
}
|
}
|
||||||
if( isChanged ){
|
if( isChanged ){
|
||||||
/* If a new wal-index header was loaded before the checkpoint was
|
/* If a new wal-index header was loaded before the checkpoint was
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
# define sqlite3WalSavepoint(y,z)
|
# define sqlite3WalSavepoint(y,z)
|
||||||
# define sqlite3WalSavepointUndo(y,z) 0
|
# define sqlite3WalSavepointUndo(y,z) 0
|
||||||
# define sqlite3WalFrames(u,v,w,x,y,z) 0
|
# define sqlite3WalFrames(u,v,w,x,y,z) 0
|
||||||
# define sqlite3WalCheckpoint(u,v,w,x,y,z) 0
|
# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
|
||||||
# define sqlite3WalCallback(z) 0
|
# define sqlite3WalCallback(z) 0
|
||||||
# define sqlite3WalExclusiveMode(y,z) 0
|
# define sqlite3WalExclusiveMode(y,z) 0
|
||||||
# define sqlite3WalHeapMemory(z) 0
|
# define sqlite3WalHeapMemory(z) 0
|
||||||
@@ -86,11 +86,14 @@ int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
|
|||||||
/* Copy pages from the log to the database file */
|
/* Copy pages from the log to the database file */
|
||||||
int sqlite3WalCheckpoint(
|
int sqlite3WalCheckpoint(
|
||||||
Wal *pWal, /* Write-ahead log connection */
|
Wal *pWal, /* Write-ahead log connection */
|
||||||
|
int eMode, /* One of PASSIVE, FULL and RESTART */
|
||||||
int (*xBusy)(void*), /* Function to call when busy */
|
int (*xBusy)(void*), /* Function to call when busy */
|
||||||
void *pBusyArg, /* Context argument for xBusyHandler */
|
void *pBusyArg, /* Context argument for xBusyHandler */
|
||||||
int sync_flags, /* Flags to sync db file with (or 0) */
|
int sync_flags, /* Flags to sync db file with (or 0) */
|
||||||
int nBuf, /* Size of buffer nBuf */
|
int nBuf, /* Size of buffer nBuf */
|
||||||
u8 *zBuf /* Temporary buffer to use */
|
u8 *zBuf, /* Temporary buffer to use */
|
||||||
|
int *pnLog, /* OUT: Number of frames in WAL */
|
||||||
|
int *pnCkpt /* OUT: Number of backfilled frames in WAL */
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Return the value to pass to a sqlite3_wal_hook callback, the
|
/* Return the value to pass to a sqlite3_wal_hook callback, the
|
||||||
|
@@ -82,7 +82,7 @@ do_multiclient_test tn {
|
|||||||
#
|
#
|
||||||
set ::busy_handler_script { if {$n==5} { sql2 COMMIT } }
|
set ::busy_handler_script { if {$n==5} { sql2 COMMIT } }
|
||||||
do_test 1.$tn.5 {
|
do_test 1.$tn.5 {
|
||||||
sql1 { PRAGMA wal_blocking_checkpoint }
|
sql1 { PRAGMA wal_checkpoint = RESTART }
|
||||||
list [db_page_count] [wal_page_count] $::nBusyHandler
|
list [db_page_count] [wal_page_count] $::nBusyHandler
|
||||||
} {6 12 6}
|
} {6 12 6}
|
||||||
do_test 1.$tn.6 {
|
do_test 1.$tn.6 {
|
||||||
@@ -109,7 +109,8 @@ do_multiclient_test tn {
|
|||||||
if {$n==7} { sql3 COMMIT }
|
if {$n==7} { sql3 COMMIT }
|
||||||
}
|
}
|
||||||
do_test 1.$tn.11 {
|
do_test 1.$tn.11 {
|
||||||
sql1 { PRAGMA wal_blocking_checkpoint }
|
breakpoint
|
||||||
|
sql1 { PRAGMA wal_checkpoint = RESTART }
|
||||||
list [db_page_count] [wal_page_count] $::nBusyHandler
|
list [db_page_count] [wal_page_count] $::nBusyHandler
|
||||||
} {10 5 8}
|
} {10 5 8}
|
||||||
do_test 1.$tn.12 { set ::db_file_size } 10
|
do_test 1.$tn.12 { set ::db_file_size } 10
|
||||||
|
Reference in New Issue
Block a user