Changes to support interrupting a checkpoint using sqlite3_interrupt().
FossilOrigin-Name: c88d36e251abec24aa7e37cf550e148904b9fd2d
This commit is contained in:
commit
1480095ff5
31
manifest
31
manifest
@ -1,5 +1,5 @@
|
||||
C Small\ssize\sreduction\sand\sperformance\sincrease\sin\sthe\sstring\sduplicator.
|
||||
D 2016-10-17T00:48:06.879
|
||||
C Changes\sto\ssupport\sinterrupting\sa\scheckpoint\susing\ssqlite3_interrupt().
|
||||
D 2016-10-17T15:28:39.424
|
||||
F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f
|
||||
@ -329,7 +329,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63
|
||||
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
|
||||
F src/btree.c 7a45743fb947c89bd6c972bfb18c8f80c070ad51
|
||||
F src/btree.c 4d035fb52b0ef9658d43dfe604413185dff7a5d1
|
||||
F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde
|
||||
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
|
||||
F src/build.c 59dcfdc1ee55439d069af301ef7f2e84421b5102
|
||||
@ -351,7 +351,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 2d5e197f2f60351937b201196965fd14cd88489c
|
||||
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
|
||||
F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d
|
||||
F src/main.c c9e49e376820bccca55fa9bf2ca321a51725db91
|
||||
F src/main.c 395bfa7a200943395f7742a40b6671ec400559ea
|
||||
F src/malloc.c 5ee7c2d3dcb1b0a902c9c6d0115deef54736bdfa
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||
@ -373,8 +373,8 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c be9ca0f901a2b6c1bc93dc338f4863675180c189
|
||||
F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c bf5b71bde3e9b6110e7d6990607db881f6a471a2
|
||||
F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d
|
||||
F src/pager.c 49b6c163832498838c92d0c4c90721576ae707b7
|
||||
F src/pager.h 0a19b1e212d0f5d0507f186ae1cca4e523d09d1a
|
||||
F src/parse.y 0338f906b61e311c2b7e11a3f89b0092c780b664
|
||||
F src/pcache.c 5ff2a08f76a9c1b22f43eb063b7068fb085465ac
|
||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||
@ -388,7 +388,7 @@ F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722
|
||||
F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2
|
||||
F src/sqlite.h.in 1011de924a6a7340c74e5442cb76f7b49c134512
|
||||
F src/sqlite.h.in 7ef021d74ac7d4004c784a16ad015508f171c4bf
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
|
||||
F src/sqliteInt.h 8d241c2c0a1a7b6611d3e9398f41d69426da850d
|
||||
@ -397,7 +397,7 @@ F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
||||
F src/tclsqlite.c aef87dcd8cb66564d560ab48d43d19ac812a1eab
|
||||
F src/test1.c 1f1a399956c8730d5f7b09c729e98764f2082162
|
||||
F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee
|
||||
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
|
||||
F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d
|
||||
@ -453,7 +453,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498
|
||||
F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3
|
||||
F src/vdbe.c ad4b4df4885067cd82ec025e5ff0d3eb02e84d4d
|
||||
F src/vdbe.c 6aa65e22bd1a44eb0cb1fa040cb9955b6670e5dd
|
||||
F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7
|
||||
F src/vdbeInt.h 0a18713d0a2fec6807d076bd333d9bf3e57530cd
|
||||
F src/vdbeapi.c 8272f9342c39ab8d7eb4b9decc6caa7bc75b7d83
|
||||
@ -464,8 +464,8 @@ F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c
|
||||
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
|
||||
F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a
|
||||
F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2
|
||||
F src/wal.c 0b44e89742024d3b6992bf404d2ab692113e1e60
|
||||
F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2
|
||||
F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0
|
||||
F src/where.c 5f846d94bb3d35b3146d9915eb301ee362957b0a
|
||||
F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d
|
||||
@ -863,6 +863,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
|
||||
F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2
|
||||
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
|
||||
F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc
|
||||
F test/interrupt2.test 829b06f9e20a6c378d8bd121b26c337f4dfa36e5
|
||||
F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8
|
||||
F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc
|
||||
F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d
|
||||
@ -1525,7 +1526,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 16d88a907730e3773a1320dbaf1f82c2bc71d71f
|
||||
R 2f0998819cd5004bd7aa9d1c4c13ab4c
|
||||
U drh
|
||||
Z 1e4256190583968ad55966afe2350526
|
||||
P cda998f080cb00779d8c0d1c83d8fe2b74462cd4 c7a9f26d118c7a453d45fa73efa4d1ab79301659
|
||||
R 00d803db9be93d1b8c7f2861fe9a2270
|
||||
U dan
|
||||
Z b37d65eeae68b321dec11a25d79485cc
|
||||
|
@ -1 +1 @@
|
||||
cda998f080cb00779d8c0d1c83d8fe2b74462cd4
|
||||
c88d36e251abec24aa7e37cf550e148904b9fd2d
|
13
src/btree.c
13
src/btree.c
@ -2395,12 +2395,14 @@ int sqlite3BtreeOpen(
|
||||
btree_open_out:
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( pBt && pBt->pPager ){
|
||||
sqlite3PagerClose(pBt->pPager);
|
||||
sqlite3PagerClose(pBt->pPager, 0);
|
||||
}
|
||||
sqlite3_free(pBt);
|
||||
sqlite3_free(p);
|
||||
*ppBtree = 0;
|
||||
}else{
|
||||
sqlite3_file *pFile;
|
||||
|
||||
/* If the B-Tree was successfully opened, set the pager-cache size to the
|
||||
** default value. Except, when opening on an existing shared pager-cache,
|
||||
** do not change the pager-cache size.
|
||||
@ -2408,6 +2410,11 @@ btree_open_out:
|
||||
if( sqlite3BtreeSchema(p, 0, 0)==0 ){
|
||||
sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE);
|
||||
}
|
||||
|
||||
pFile = sqlite3PagerFile(pBt->pPager);
|
||||
if( pFile->pMethods ){
|
||||
sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db);
|
||||
}
|
||||
}
|
||||
if( mutexOpen ){
|
||||
assert( sqlite3_mutex_held(mutexOpen) );
|
||||
@ -2537,7 +2544,7 @@ int sqlite3BtreeClose(Btree *p){
|
||||
** Clean out and delete the BtShared object.
|
||||
*/
|
||||
assert( !pBt->pCursor );
|
||||
sqlite3PagerClose(pBt->pPager);
|
||||
sqlite3PagerClose(pBt->pPager, p->db);
|
||||
if( pBt->xFreeSchema && pBt->pSchema ){
|
||||
pBt->xFreeSchema(pBt->pSchema);
|
||||
}
|
||||
@ -9477,7 +9484,7 @@ int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){
|
||||
if( pBt->inTransaction!=TRANS_NONE ){
|
||||
rc = SQLITE_LOCKED;
|
||||
}else{
|
||||
rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt);
|
||||
rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt);
|
||||
}
|
||||
sqlite3BtreeLeave(p);
|
||||
}
|
||||
|
@ -2106,6 +2106,13 @@ int sqlite3_wal_checkpoint_v2(
|
||||
sqlite3Error(db, rc);
|
||||
}
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
|
||||
/* If there are no active statements, clear the interrupt flag at this
|
||||
** point. */
|
||||
if( db->nVdbeActive==0 ){
|
||||
db->u1.isInterrupted = 0;
|
||||
}
|
||||
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
#endif
|
||||
|
19
src/pager.c
19
src/pager.c
@ -4021,9 +4021,10 @@ static void pagerFreeMapHdrs(Pager *pPager){
|
||||
** a hot journal may be left in the filesystem but no error is returned
|
||||
** to the caller.
|
||||
*/
|
||||
int sqlite3PagerClose(Pager *pPager){
|
||||
int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
|
||||
u8 *pTmp = (u8 *)pPager->pTmpSpace;
|
||||
|
||||
assert( db || pagerUseWal(pPager)==0 );
|
||||
assert( assert_pager_state(pPager) );
|
||||
disable_simulated_io_errors();
|
||||
sqlite3BeginBenignMalloc();
|
||||
@ -4031,7 +4032,7 @@ int sqlite3PagerClose(Pager *pPager){
|
||||
/* pPager->errCode = 0; */
|
||||
pPager->exclusiveMode = 0;
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
|
||||
sqlite3WalClose(pPager->pWal,db,pPager->ckptSyncFlags,pPager->pageSize,pTmp);
|
||||
pPager->pWal = 0;
|
||||
#endif
|
||||
pager_reset(pPager);
|
||||
@ -7194,10 +7195,16 @@ void sqlite3PagerClearCache(Pager *pPager){
|
||||
**
|
||||
** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
|
||||
*/
|
||||
int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
|
||||
int sqlite3PagerCheckpoint(
|
||||
Pager *pPager, /* Checkpoint on this pager */
|
||||
sqlite3 *db, /* Db handle used to check for interrupts */
|
||||
int eMode, /* Type of checkpoint */
|
||||
int *pnLog, /* OUT: Final number of frames in log */
|
||||
int *pnCkpt /* OUT: Final number of checkpointed frames */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
if( pPager->pWal ){
|
||||
rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
|
||||
rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
|
||||
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
|
||||
pPager->pBusyHandlerArg,
|
||||
pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
|
||||
@ -7329,7 +7336,7 @@ int sqlite3PagerOpenWal(
|
||||
** error (SQLITE_BUSY) is returned and the log connection is not closed.
|
||||
** If successful, the EXCLUSIVE lock is not released before returning.
|
||||
*/
|
||||
int sqlite3PagerCloseWal(Pager *pPager){
|
||||
int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
|
||||
@ -7357,7 +7364,7 @@ int sqlite3PagerCloseWal(Pager *pPager){
|
||||
if( rc==SQLITE_OK && pPager->pWal ){
|
||||
rc = pagerExclusiveLock(pPager);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
|
||||
rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags,
|
||||
pPager->pageSize, (u8*)pPager->pTmpSpace);
|
||||
pPager->pWal = 0;
|
||||
pagerFixMaplimit(pPager);
|
||||
|
@ -122,7 +122,7 @@ int sqlite3PagerOpen(
|
||||
int,
|
||||
void(*)(DbPage*)
|
||||
);
|
||||
int sqlite3PagerClose(Pager *pPager);
|
||||
int sqlite3PagerClose(Pager *pPager, sqlite3*);
|
||||
int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
|
||||
|
||||
/* Functions used to configure a Pager object. */
|
||||
@ -173,11 +173,11 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
|
||||
int sqlite3PagerSharedLock(Pager *pPager);
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
|
||||
int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
|
||||
int sqlite3PagerWalSupported(Pager *pPager);
|
||||
int sqlite3PagerWalCallback(Pager *pPager);
|
||||
int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
|
||||
int sqlite3PagerCloseWal(Pager *pPager);
|
||||
int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
|
||||
# ifdef SQLITE_ENABLE_SNAPSHOT
|
||||
int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
|
||||
int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
|
||||
|
@ -1035,6 +1035,7 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_VFS_POINTER 27
|
||||
#define SQLITE_FCNTL_JOURNAL_POINTER 28
|
||||
#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
|
||||
#define SQLITE_FCNTL_PDB 30
|
||||
|
||||
/* deprecated names */
|
||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||
|
@ -93,7 +93,7 @@ static int SQLITE_TCLAPI pager_close(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
pPager = sqlite3TestTextToPtr(argv[1]);
|
||||
rc = sqlite3PagerClose(pPager);
|
||||
rc = sqlite3PagerClose(pPager, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
|
@ -6273,7 +6273,7 @@ case OP_JournalMode: { /* out2 */
|
||||
** file. An EXCLUSIVE lock may still be held on the database file
|
||||
** after a successful return.
|
||||
*/
|
||||
rc = sqlite3PagerCloseWal(pPager);
|
||||
rc = sqlite3PagerCloseWal(pPager, db);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3PagerSetJournalMode(pPager, eNew);
|
||||
}
|
||||
|
13
src/wal.c
13
src/wal.c
@ -1723,6 +1723,7 @@ static void walRestartHdr(Wal *pWal, u32 salt1){
|
||||
*/
|
||||
static int walCheckpoint(
|
||||
Wal *pWal, /* Wal connection */
|
||||
sqlite3 *db, /* Check for interrupts on this handle */
|
||||
int eMode, /* One of PASSIVE, FULL or RESTART */
|
||||
int (*xBusy)(void*), /* Function to call when busy */
|
||||
void *pBusyArg, /* Context argument for xBusyHandler */
|
||||
@ -1817,6 +1818,10 @@ static int walCheckpoint(
|
||||
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
|
||||
i64 iOffset;
|
||||
assert( walFramePgno(pWal, iFrame)==iDbpage );
|
||||
if( db->u1.isInterrupted ){
|
||||
rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
|
||||
break;
|
||||
}
|
||||
if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
|
||||
continue;
|
||||
}
|
||||
@ -1921,6 +1926,7 @@ static void walLimitSize(Wal *pWal, i64 nMax){
|
||||
*/
|
||||
int sqlite3WalClose(
|
||||
Wal *pWal, /* Wal to close */
|
||||
sqlite3 *db, /* For interrupt flag */
|
||||
int sync_flags, /* Flags to pass to OsSync() (or 0) */
|
||||
int nBuf,
|
||||
u8 *zBuf /* Buffer of at least nBuf bytes */
|
||||
@ -1942,8 +1948,8 @@ int sqlite3WalClose(
|
||||
if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
|
||||
pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
|
||||
}
|
||||
rc = sqlite3WalCheckpoint(
|
||||
pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
|
||||
rc = sqlite3WalCheckpoint(pWal, db,
|
||||
SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
|
||||
);
|
||||
if( rc==SQLITE_OK ){
|
||||
int bPersist = -1;
|
||||
@ -3191,6 +3197,7 @@ int sqlite3WalFrames(
|
||||
*/
|
||||
int sqlite3WalCheckpoint(
|
||||
Wal *pWal, /* Wal connection */
|
||||
sqlite3 *db, /* Check this handle's interrupt flag */
|
||||
int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */
|
||||
int (*xBusy)(void*), /* Function to call when busy */
|
||||
void *pBusyArg, /* Context argument for xBusyHandler */
|
||||
@ -3265,7 +3272,7 @@ int sqlite3WalCheckpoint(
|
||||
if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
|
||||
rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
|
||||
}
|
||||
|
||||
/* If no error occurred, set the output variables. */
|
||||
|
@ -28,7 +28,7 @@
|
||||
#ifdef SQLITE_OMIT_WAL
|
||||
# define sqlite3WalOpen(x,y,z) 0
|
||||
# define sqlite3WalLimit(x,y)
|
||||
# define sqlite3WalClose(w,x,y,z) 0
|
||||
# define sqlite3WalClose(v,w,x,y,z) 0
|
||||
# define sqlite3WalBeginReadTransaction(y,z) 0
|
||||
# define sqlite3WalEndReadTransaction(z)
|
||||
# define sqlite3WalDbsize(y) 0
|
||||
@ -38,7 +38,7 @@
|
||||
# define sqlite3WalSavepoint(y,z)
|
||||
# define sqlite3WalSavepointUndo(y,z) 0
|
||||
# define sqlite3WalFrames(u,v,w,x,y,z) 0
|
||||
# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
|
||||
# define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0
|
||||
# define sqlite3WalCallback(z) 0
|
||||
# define sqlite3WalExclusiveMode(y,z) 0
|
||||
# define sqlite3WalHeapMemory(z) 0
|
||||
@ -56,7 +56,7 @@ typedef struct Wal Wal;
|
||||
|
||||
/* Open and close a connection to a write-ahead log. */
|
||||
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
|
||||
int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
|
||||
int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *);
|
||||
|
||||
/* Set the limiting size of a WAL file. */
|
||||
void sqlite3WalLimit(Wal*, i64);
|
||||
@ -99,6 +99,7 @@ int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
|
||||
/* Copy pages from the log to the database file */
|
||||
int sqlite3WalCheckpoint(
|
||||
Wal *pWal, /* Write-ahead log connection */
|
||||
sqlite3 *db, /* Check this handle's interrupt flag */
|
||||
int eMode, /* One of PASSIVE, FULL and RESTART */
|
||||
int (*xBusy)(void*), /* Function to call when busy */
|
||||
void *pBusyArg, /* Context argument for xBusyHandler */
|
||||
|
154
test/interrupt2.test
Normal file
154
test/interrupt2.test
Normal file
@ -0,0 +1,154 @@
|
||||
# 2016 Aug 12
|
||||
#
|
||||
# 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 using the sqlite_interrupt() API to
|
||||
# interrupt WAL checkpoint operations.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
set testprefix interrupt2
|
||||
|
||||
db close
|
||||
testvfs tvfs -default 1
|
||||
|
||||
tvfs filter xWrite
|
||||
tvfs script write_cb
|
||||
|
||||
set ::trigger_interrupt 0
|
||||
proc write_cb {method args} {
|
||||
set filename [lindex $args 0]
|
||||
if {[file tail $filename]=="test.db" && $::trigger_interrupt} {
|
||||
if {$::trigger_interrupt} {
|
||||
incr ::trigger_interrupt -1
|
||||
if {$::trigger_interrupt==0} { sqlite3_interrupt db }
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
PRAGMA journal_mode = wal;
|
||||
|
||||
WITH ii(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM ii WHERE i<1000 )
|
||||
INSERT INTO t1 SELECT i, i FROM ii;
|
||||
} {wal}
|
||||
|
||||
foreach idelay {
|
||||
5
|
||||
10
|
||||
15
|
||||
20
|
||||
} {
|
||||
|
||||
set ::trigger_interrupt $idelay
|
||||
do_catchsql_test 1.$idelay.1 { PRAGMA wal_checkpoint; } {1 interrupted}
|
||||
do_execsql_test 1.$idelay.2 { SELECT count(*) FROM t1 } 1000
|
||||
|
||||
set ::trigger_interrupt $idelay
|
||||
do_test 1.$idelay.3 {
|
||||
list [catch { sqlite3_wal_checkpoint_v2 db truncate } msg] $msg
|
||||
} {1 {SQLITE_INTERRUPT - interrupted}}
|
||||
do_execsql_test 1.$idelay.4 { SELECT count(*) FROM t1 } 1000
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that if there are other SQL statements running, a checkpoint does
|
||||
# not clear the isInterrupted flag.
|
||||
#
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TEMP TABLE z1(a, b);
|
||||
INSERT INTO z1 SELECT * FROM t1;
|
||||
}
|
||||
|
||||
do_test 2.1 {
|
||||
set i 10
|
||||
set res [list [catch {
|
||||
set i 10
|
||||
db eval {SELECT * FROM z1} {
|
||||
incr i -1
|
||||
if {$i==0} {
|
||||
set ::trigger_interrupt 10
|
||||
set cres [catch { sqlite3_wal_checkpoint_v2 db truncate } msg]
|
||||
lappend cres $msg
|
||||
}
|
||||
}
|
||||
} msg] $msg]
|
||||
|
||||
list $cres $res
|
||||
} {{1 {SQLITE_INTERRUPT - interrupted}} {1 interrupted}}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
SELECT count(*) FROM t1
|
||||
UNION ALL
|
||||
SELECT count(*) FROM z1
|
||||
} {1000 1000}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check the effect of an interrupt during sqlite3_close().
|
||||
#
|
||||
db_save_and_close
|
||||
|
||||
db_restore_and_reopen
|
||||
do_test 3.1.1 {
|
||||
set ::trigger_interrupt 10
|
||||
db eval { SELECT * FROM sqlite_master }
|
||||
db close
|
||||
set {} {}
|
||||
} {}
|
||||
do_test 3.1.2 {
|
||||
list [file exists test.db] [file exists test.db-wal]
|
||||
} {1 1}
|
||||
|
||||
db_restore_and_reopen
|
||||
do_test 3.2.1 {
|
||||
db eval { SELECT * FROM sqlite_master }
|
||||
db close
|
||||
set {} {}
|
||||
} {}
|
||||
do_test 3.2.2 {
|
||||
list [file exists test.db] [file exists test.db-wal]
|
||||
} {1 0}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check the effect of an interrupt during an automatic checkpoint
|
||||
#
|
||||
db_restore_and_reopen
|
||||
do_test 4.0 {
|
||||
execsql { PRAGMA wal_autocheckpoint = 10 }
|
||||
set ::trigger_interrupt 10
|
||||
execsql { CREATE TABLE t2(x, y) }
|
||||
} {}
|
||||
|
||||
# The auto-checkpoint in test 4.0 should have been interrupted. So this
|
||||
# db write should cause the wal file to grow.
|
||||
do_test 4.1 {
|
||||
set nFrame1 [wal_frame_count test.db-wal 1024]
|
||||
execsql { CREATE TABLE t3(x, y) }
|
||||
set nFrame2 [wal_frame_count test.db-wal 1024]
|
||||
expr $nFrame2 > $nFrame1
|
||||
} {1}
|
||||
|
||||
# The auto-checkpoint in test 4.0 should not have been interrupted. So
|
||||
# this db write should not cause the wal file to grow.
|
||||
do_test 4.2 {
|
||||
set nFrame1 [wal_frame_count test.db-wal 1024]
|
||||
execsql { CREATE TABLE t4(x, y) }
|
||||
set nFrame2 [wal_frame_count test.db-wal 1024]
|
||||
expr $nFrame2 == $nFrame1
|
||||
} {1}
|
||||
|
||||
finish_test
|
Loading…
x
Reference in New Issue
Block a user