Avoid creating any extra files ("<target>-vacuum") when running an RBU vacuum. Ensure that the OAL file created is "<target>-oal", not "<target>-vacuum-oal".

FossilOrigin-Name: dc19aacc7e99213edca9bb57b5c11a8a1ac99113
This commit is contained in:
dan 2016-04-16 17:53:14 +00:00
parent ee65eea4af
commit 977cbe78b3
3 changed files with 84 additions and 77 deletions

View File

@ -2323,6 +2323,7 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
static void rbuOpenDatabase(sqlite3rbu *p){
assert( p->rc==SQLITE_OK );
assert( p->dbMain==0 && p->dbRbu==0 );
assert( rbuIsVacuum(p) || p->zTarget!=0 );
/* Open the RBU database */
p->dbRbu = rbuOpenDbhandle(p, p->zRbu);
@ -2355,16 +2356,21 @@ static void rbuOpenDatabase(sqlite3rbu *p){
p->eStage = 0;
if( p->dbMain==0 ){
if( p->zTarget ){
if( !rbuIsVacuum(p) ){
p->dbMain = rbuOpenDbhandle(p, p->zTarget);
}else{
char *zTarget = sqlite3_mprintf("%s-vacuum", p->zRbu);
char *zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1", p->zRbu);
if( zTarget==0 ){
p->rc = SQLITE_NOMEM;
return;
}
p->dbMain = rbuOpenDbhandle(p, zTarget);
sqlite3_free(zTarget);
if( p->rc==SQLITE_OK ){
p->rc = sqlite3_exec(p->dbMain,
"PRAGMA journal_mode=off; BEGIN EXCLUSIVE; COMMIT;", 0, 0, 0
);
}
}
}
@ -2641,14 +2647,15 @@ static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
*/
static void rbuMoveOalFile(sqlite3rbu *p){
const char *zBase = sqlite3_db_filename(p->dbMain, "main");
char *zOal = sqlite3_mprintf("%s-oal", zBase);
const char *zMove = zBase;
char *zOal;
char *zWal;
if( rbuIsVacuum(p) ){
zWal = sqlite3_mprintf("%s-wal", sqlite3_db_filename(p->dbRbu, "main"));
}else{
zWal = sqlite3_mprintf("%s-wal", zBase);
zMove = sqlite3_db_filename(p->dbRbu, "main");
}
zOal = sqlite3_mprintf("%s-oal", zMove);
zWal = sqlite3_mprintf("%s-wal", zMove);
assert( p->eStage==RBU_STAGE_MOVE );
assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
@ -2928,13 +2935,18 @@ static int rbuStep(sqlite3rbu *p){
/*
** Increment the schema cookie of the main database opened by p->dbMain.
**
** Or, if this is an RBU vacuum, set the schema cookie of the main db
** opened by p->dbMain to one more than the schema cookie of the main
** db opened by p->dbRbu.
*/
static void rbuIncrSchemaCookie(sqlite3rbu *p){
if( p->rc==SQLITE_OK ){
sqlite3 *dbread = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
int iCookie = 1000000;
sqlite3_stmt *pStmt;
p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
p->rc = prepareAndCollectError(dbread, &pStmt, &p->zErrmsg,
"PRAGMA schema_version"
);
if( p->rc==SQLITE_OK ){
@ -3408,6 +3420,7 @@ static sqlite3rbu *openRbuHandle(
}
if( p->rc==SQLITE_OK
&& !rbuIsVacuum(p)
&& (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE)
&& pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie
){
@ -3803,34 +3816,6 @@ static int rbuVfsRead(
memset(zBuf, 0, iAmt);
}else{
rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
/* If this is being called to read the first page of the target
** database as part of an rbu vacuum operation, synthesize the
** contents of the first page if it does not yet exist. Otherwise,
** SQLite will not check for a *-wal file. */
if( p->pRbu && rbuIsVacuum(p->pRbu)
&& rc==SQLITE_IOERR_SHORT_READ && iOfst==0
&& (p->openFlags & SQLITE_OPEN_MAIN_DB)
){
sqlite3_file *pFd = 0;
rc = sqlite3_file_control(
p->pRbu->dbRbu, "main", SQLITE_FCNTL_FILE_POINTER, (void*)&pFd
);
if( rc==SQLITE_OK ){
rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst);
}
if( rc==SQLITE_OK ){
rbuPutU32(&zBuf[52], 0); /* largest root page number */
rbuPutU32(&zBuf[36], 0); /* number of free pages */
rbuPutU32(&zBuf[32], 0); /* first page on free list trunk */
rbuPutU32(&zBuf[28], 1); /* size of db file in pages */
if( iAmt>100 ){
assert( iAmt>=101 );
memset(&zBuf[101], 0, iAmt-101);
rbuPutU16(&zBuf[105], iAmt & 0xFFFF);
}
}
}
}
if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
/* These look like magic numbers. But they are stable, as they are part
@ -3838,6 +3823,13 @@ static int rbuVfsRead(
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;
@ -3905,20 +3897,7 @@ static int rbuVfsSync(sqlite3_file *pFile, int flags){
*/
static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
rbu_file *p = (rbu_file *)pFile;
int rc;
rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
/* If this is an RBU vacuum operation and this is the target database,
** pretend that it has at least one page. Otherwise, SQLite will not
** check for the existance of a *-wal file. rbuVfsRead() contains
** similar logic. */
if( rc==SQLITE_OK && *pSize==0
&& p->pRbu && rbuIsVacuum(p->pRbu)
&& (p->openFlags & SQLITE_OPEN_MAIN_DB)
){
*pSize = 1024;
}
return rc;
return p->pReal->pMethods->xFileSize(p->pReal, pSize);
}
/*
@ -4156,6 +4135,33 @@ static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
return pDb;
}
/*
** A main database named zName has just been opened. The following
** function returns a pointer to a buffer owned by SQLite that contains
** the name of the *-wal file this db connection will use. SQLite
** happens to pass a pointer to this buffer when using xAccess()
** or xOpen() to operate on the *-wal file.
*/
static const char *rbuMainToWal(const char *zName, int flags){
int n = (int)strlen(zName);
const char *z = &zName[n];
if( flags & SQLITE_OPEN_URI ){
int odd = 0;
while( 1 ){
if( z[0]==0 ){
odd = 1 - odd;
if( odd && z[1]==0 ) break;
}
z++;
}
z += 2;
}else{
while( *z==0 ) z++;
}
z += (n + 8 + 1);
return z;
}
/*
** Open an rbu file handle.
*/
@ -4191,6 +4197,7 @@ static int rbuVfsOpen(
rbu_file *pFd = (rbu_file *)pFile;
int rc = SQLITE_OK;
const char *zOpen = zName;
int oflags = flags;
memset(pFd, 0, sizeof(rbu_file));
pFd->pReal = (sqlite3_file*)&pFd[1];
@ -4203,23 +4210,7 @@ static int rbuVfsOpen(
** the name of the *-wal file this db connection will use. SQLite
** happens to pass a pointer to this buffer when using xAccess()
** or xOpen() to operate on the *-wal file. */
int n = (int)strlen(zName);
const char *z = &zName[n];
if( flags & SQLITE_OPEN_URI ){
int odd = 0;
while( 1 ){
if( z[0]==0 ){
odd = 1 - odd;
if( odd && z[1]==0 ) break;
}
z++;
}
z += 2;
}else{
while( *z==0 ) z++;
}
z += (n + 8 + 1);
pFd->zWal = z;
pFd->zWal = rbuMainToWal(zName, flags);
}
else if( flags & SQLITE_OPEN_WAL ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
@ -4229,10 +4220,17 @@ static int rbuVfsOpen(
** code ensures that the string passed to xOpen() is terminated by a
** pair of '\0' bytes in case the VFS attempts to extract a URI
** parameter from it. */
size_t nCopy = strlen(zName);
char *zCopy = sqlite3_malloc64(nCopy+2);
const char *zBase = zName;
size_t nCopy;
char *zCopy;
if( rbuIsVacuum(pDb->pRbu) ){
zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
zBase = rbuMainToWal(zBase, SQLITE_OPEN_URI);
}
nCopy = strlen(zBase);
zCopy = sqlite3_malloc64(nCopy+2);
if( zCopy ){
memcpy(zCopy, zName, nCopy);
memcpy(zCopy, zBase, nCopy);
zCopy[nCopy-3] = 'o';
zCopy[nCopy] = '\0';
zCopy[nCopy+1] = '\0';
@ -4247,8 +4245,17 @@ static int rbuVfsOpen(
}
}
if( oflags & SQLITE_OPEN_MAIN_DB
&& sqlite3_uri_boolean(zName, "rbu_memory", 0)
){
assert( oflags & SQLITE_OPEN_MAIN_DB );
oflags = SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
zOpen = 0;
}
if( rc==SQLITE_OK ){
rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, flags, pOutFlags);
rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags);
}
if( pFd->pReal->pMethods ){
/* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods

View File

@ -1,5 +1,5 @@
C Fix\sa\scouple\sof\sassert()\sstatements\sthat\swere\sfailing\swith\sOOM\serror\stests.
D 2016-04-16T15:03:20.537
C Avoid\screating\sany\sextra\sfiles\s("<target>-vacuum")\swhen\srunning\san\sRBU\svacuum.\sEnsure\sthat\sthe\sOAL\sfile\screated\sis\s"<target>-oal",\snot\s"<target>-vacuum-oal".
D 2016-04-16T17:53:14.824
F Makefile.in eba680121821b8a60940a81454316f47a341487a
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
@ -247,7 +247,7 @@ 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 79b8be4a0c8276b2b2b24c88edf3944216ccd35b
F ext/rbu/sqlite3rbu.c 471b4055618473612e9ae7d7e4f1922559b59aaf
F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b
F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
@ -1483,7 +1483,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 0216b48f28042ad86711e00802c2da8ce9be3044
R 0603f47373db6aeb2d2c22dfe403e0e2
P 8eb3d7d8360530f364bbbebac53e1f0e6753d924
R 4d03a7f5bef5f70852d283bb46ff80e2
U dan
Z 6e5ab10ab6efe323abcf341183f13408
Z 0a7d529e6f2d77bae387935d2996f1da

View File

@ -1 +1 @@
8eb3d7d8360530f364bbbebac53e1f0e6753d924
dc19aacc7e99213edca9bb57b5c11a8a1ac99113