source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbuvacuum
-proc do_rbu_vacuum_test {tn} {
+proc do_rbu_vacuum_test {tn step} {
uplevel [list do_test $tn.1 {
forcedelete state.db
- if {$::step==0} { sqlite3rbu_vacuum rbu test.db state.db }
+ if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db }
while 1 {
- if {$::step==1} { sqlite3rbu_vacuum rbu test.db state.db }
+ if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db }
set rc [rbu step]
if {$rc!="SQLITE_OK"} break
- if {$::step==1} { rbu close }
+ if {$step==1} { rbu close }
}
rbu close
} {SQLITE_DONE}]
INSERT INTO t1 VALUES(7, 8, 9);
PRAGMA integrity_check;
} {ok}
- do_rbu_vacuum_test 1.1
+ do_rbu_vacuum_test 1.1 $step
# A vacuum that actually reclaims space.
do_execsql_test 1.2.1 {
DELETE FROM t1 WHERE rowid BETWEEN 8 AND 11;
PRAGMA page_count;
} {12}
- do_rbu_vacuum_test 1.2.3
+ do_rbu_vacuum_test 1.2.3 $step
do_execsql_test 1.2.4 {
PRAGMA page_count;
} {3}
DELETE FROM t1 WHERE rowid BETWEEN 12 AND 15;
PRAGMA page_count;
} {18}
- do_rbu_vacuum_test 1.3.3
+ do_rbu_vacuum_test 1.3.3 $step
do_execsql_test 1.3.4 {
PRAGMA page_count;
} {5}
DELETE FROM t2 WHERE b BETWEEN 2 AND 7;
PRAGMA page_count;
} {20}
- do_rbu_vacuum_test 1.4.2
+ do_rbu_vacuum_test 1.4.2 $step
do_execsql_test 1.4.3 {
PRAGMA page_count;
} {10}
DELETE FROM t2 WHERE b BETWEEN 8 AND 12;
PRAGMA page_count;
} {35}
- do_rbu_vacuum_test 1.4.2
+ do_rbu_vacuum_test 1.4.2 $step
do_execsql_test 1.4.3 {
PRAGMA page_count;
} {15}
INSERT INTO t3 VALUES('d', 'e', 'f');
INSERT INTO t3 VALUES('g', 'h', 'i');
}
- do_rbu_vacuum_test 1.5.2
+ do_rbu_vacuum_test 1.5.2 $step
do_execsql_test 1.5.3 {
SELECT * FROM t3
} {a b c d e f g h i}
INSERT INTO t3 VALUES('j', 'k', 'l');
DELETE FROM t3 WHERE a = 'g';
}
- do_rbu_vacuum_test 1.5.5
+ do_rbu_vacuum_test 1.5.5 $step
do_execsql_test 1.5.6 {
SELECT rowid, * FROM t3 ORDER BY b
} {1 a b c 2 d e f 4 j k l}
INSERT INTO t4 VALUES('d', 'e', 'f');
INSERT INTO t4 VALUES('g', 'h', 'i');
}
- do_rbu_vacuum_test 1.6.2
+ do_rbu_vacuum_test 1.6.2 $step
do_execsql_test 1.6.3 {
SELECT * FROM t4
} {a b c d e f g h i}
INSERT INTO t4 VALUES('j', 'k', 'l');
DELETE FROM t4 WHERE a='g';
}
- do_rbu_vacuum_test 1.6.5
+ do_rbu_vacuum_test 1.6.5 $step
do_execsql_test 1.6.6 {
SELECT * FROM t4 ORDER BY b
} {a b c d e f j k l}
}
+#-------------------------------------------------------------------------
+# Test some error cases:
+#
+# 2.1.* the db being vacuumed being in wal mode already.
+# 2.2.* database modified mid vacuum.
+#
+reset_db
+do_execsql_test 2.1.0 {
+ CREATE TABLE t1(a, b);
+ INSERT INTO t1 VALUES(1, 2);
+ INSERT INTO t1 VALUES(3, 4);
+ INSERT INTO t1 VALUES(5, 6);
+ INSERT INTO t1 VALUES(7, 8);
+ PRAGMA journal_mode = wal;
+ INSERT INTO t1 VALUES(9, 10);
+} wal
+do_test 2.1.1 {
+ forcedelete state.db
+ sqlite3rbu_vacuum rbu test.db state.db
+ rbu step
+} {SQLITE_ERROR}
+do_test 2.1.2 {
+ list [catch { rbu close } msg] $msg
+} {1 {SQLITE_ERROR - cannot vacuum wal mode database}}
+
+reset_db
+do_execsql_test 2.2.0 {
+ CREATE TABLE tx(a PRIMARY KEY, b BLOB);
+ INSERT INTO tx VALUES(1, randomblob(900));
+ INSERT INTO tx SELECT a+1, randomblob(900) FROM tx;
+ INSERT INTO tx SELECT a+2, randomblob(900) FROM tx;
+ INSERT INTO tx SELECT a+4, randomblob(900) FROM tx;
+ INSERT INTO tx SELECT a+8, randomblob(900) FROM tx;
+}
+db_save_and_close
+for {set i 1} 1 {incr i} {
+ forcedelete state.db
+ db_restore_and_reopen
+
+ sqlite3rbu_vacuum rbu test.db state.db
+ for {set step 0} {$step<$i} {incr step} { rbu step }
+ rbu close
+ if {[file exists test.db-wal]} break
+
+ execsql { INSERT INTO tx VALUES(20, 20) }
+
+ do_test 2.2.$i.1 {
+ sqlite3rbu_vacuum rbu test.db state.db
+ rbu step
+ } {SQLITE_BUSY}
+ do_test 2.2.$i.2 {
+ list [catch { rbu close } msg] $msg
+ } {1 {SQLITE_BUSY - database modified during rbu vacuum}}
+
+}
+
catch { db close }
finish_test
int openFlags; /* Flags this file was opened with */
u32 iCookie; /* Cookie value for main db files */
u8 iWriteVer; /* "write-version" value for main db files */
- u8 bNolock;
+ u8 bNolock; /* True to fail EXCLUSIVE locks */
int nShm; /* Number of entries in apShm[] array */
char **apShm; /* Array of mmap'd *-shm regions */
}
p->eStage = 0;
- if( p->dbMain==0 ){
+ if( p->rc==SQLITE_OK && p->dbMain==0 ){
if( !rbuIsVacuum(p) ){
p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
+ }else if( p->pRbuFd->pWalFd ){
+ p->rc = SQLITE_ERROR;
+ p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database");
}else{
char *zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1", p->zRbu);
if( zTarget==0 ){
static void rbuSaveState(sqlite3rbu *p, int eStage){
if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){
sqlite3_stmt *pInsert = 0;
+ rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
int rc;
assert( p->zErrmsg==0 );
RBU_STATE_ROW, p->nStep,
RBU_STATE_PROGRESS, p->nProgress,
RBU_STATE_CKPT, p->iWalCksum,
- RBU_STATE_COOKIE, (i64)p->pTargetFd->iCookie,
+ RBU_STATE_COOKIE, (i64)pFd->iCookie,
RBU_STATE_OALSZ, p->iOalSz,
RBU_STATE_PHASEONESTEP, p->nPhaseOneStep
)
}
}
- if( p->rc==SQLITE_OK
- && !rbuIsVacuum(p)
+ if( p->rc==SQLITE_OK
&& (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE)
- && pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie
- ){
- /* At this point (pTargetFd->iCookie) contains the value of the
- ** change-counter cookie (the thing that gets incremented when a
- ** transaction is committed in rollback mode) currently stored on
- ** page 1 of the database file. */
- p->rc = SQLITE_BUSY;
- p->zErrmsg = sqlite3_mprintf("database modified during rbu update");
+ && pState->eStage!=0
+ ){
+ rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
+ if( pFd->iCookie!=pState->iCookie ){
+ /* At this point (pTargetFd->iCookie) contains the value of the
+ ** change-counter cookie (the thing that gets incremented when a
+ ** transaction is committed in rollback mode) currently stored on
+ ** page 1 of the database file. */
+ p->rc = SQLITE_BUSY;
+ p->zErrmsg = sqlite3_mprintf("database modified during rbu %s",
+ (rbuIsVacuum(p) ? "vacuum" : "update")
+ );
+ }
}
if( p->rc==SQLITE_OK ){
rbuPutU32(&aBuf[36], 0); /* number of free pages */
rbuPutU32(&aBuf[32], 0); /* first page on free list trunk */
rbuPutU32(&aBuf[28], 1); /* size of db file in pages */
+ rbuPutU32(&aBuf[24], pRbu->pRbuFd->iCookie+1); /* Change counter */
if( iAmt>100 ){
assert( iAmt>=101 );
u8 *pBuf = (u8*)zBuf;
p->iCookie = rbuGetU32(&pBuf[24]);
p->iWriteVer = pBuf[19];
- if( pRbu && rbuIsVacuum(p->pRbu) ){
- rbu_file *pRbuFd = 0;
- sqlite3_file_control(pRbu->dbRbu, "main",
- SQLITE_FCNTL_FILE_POINTER, (void*)&pRbuFd
- );
- rbuPutU32(&pBuf[24], pRbuFd->iCookie+1);
- }
}
}
return rc;
-C Another\sfix\sto\srbu\svacuum\sfor\sa\szipvfs\scase.
-D 2016-04-18T21:00:01.258
+C Detect\sattempts\sto\suse\srbu\svacuum\son\sa\swal\smode\sdatabase\s(not\sallowed).\sAnd\sattempts\sto\swrite\sto\sa\sdatabase\sin\sthe\smiddle\sof\san\srbu\svacuum\s(which\sprevents\sthe\svacuum\sfrom\sresuming).
+D 2016-04-19T16:20:24.513
F Makefile.in eba680121821b8a60940a81454316f47a341487a
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
-F ext/rbu/rbuvacuum.test 75b4231f85622859e814c7f028afad0303f72f60
-F ext/rbu/sqlite3rbu.c ac4621fc62e0bc3e9e92fceb483c0207af25addf
+F ext/rbu/rbuvacuum.test b7194617c22f69e2015082a5414585aae2827a29
+F ext/rbu/sqlite3rbu.c d269d60bddb770fc9bbe747c47522f946562878d
F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b
F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P d76f4aaa4caab713460421bd27365a82ac986c20
-R 02609be0d1cf35faad7663d479babac3
+P 29407d70e44ad9ea5ddaf1011d0e212b602a3ddf
+R da49b342c9cd61c56db951e40b34afc9
U dan
-Z ecb53ed56b3181cf4b46470b55ef0f36
+Z 3a78d0d54b42b6cec75432abbb63bed7
-29407d70e44ad9ea5ddaf1011d0e212b602a3ddf
\ No newline at end of file
+00b2f4b09ffca5156e43c4db2bfe0b2c979c49b0
\ No newline at end of file