1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

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){ static void rbuOpenDatabase(sqlite3rbu *p){
assert( p->rc==SQLITE_OK ); assert( p->rc==SQLITE_OK );
assert( p->dbMain==0 && p->dbRbu==0 ); assert( p->dbMain==0 && p->dbRbu==0 );
assert( rbuIsVacuum(p) || p->zTarget!=0 );
/* Open the RBU database */ /* Open the RBU database */
p->dbRbu = rbuOpenDbhandle(p, p->zRbu); p->dbRbu = rbuOpenDbhandle(p, p->zRbu);
@ -2355,16 +2356,21 @@ static void rbuOpenDatabase(sqlite3rbu *p){
p->eStage = 0; p->eStage = 0;
if( p->dbMain==0 ){ if( p->dbMain==0 ){
if( p->zTarget ){ if( !rbuIsVacuum(p) ){
p->dbMain = rbuOpenDbhandle(p, p->zTarget); p->dbMain = rbuOpenDbhandle(p, p->zTarget);
}else{ }else{
char *zTarget = sqlite3_mprintf("%s-vacuum", p->zRbu); char *zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1", p->zRbu);
if( zTarget==0 ){ if( zTarget==0 ){
p->rc = SQLITE_NOMEM; p->rc = SQLITE_NOMEM;
return; return;
} }
p->dbMain = rbuOpenDbhandle(p, zTarget); p->dbMain = rbuOpenDbhandle(p, zTarget);
sqlite3_free(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){ static void rbuMoveOalFile(sqlite3rbu *p){
const char *zBase = sqlite3_db_filename(p->dbMain, "main"); const char *zBase = sqlite3_db_filename(p->dbMain, "main");
char *zOal = sqlite3_mprintf("%s-oal", zBase); const char *zMove = zBase;
char *zOal;
char *zWal; char *zWal;
if( rbuIsVacuum(p) ){ if( rbuIsVacuum(p) ){
zWal = sqlite3_mprintf("%s-wal", sqlite3_db_filename(p->dbRbu, "main")); zMove = sqlite3_db_filename(p->dbRbu, "main");
}else{
zWal = sqlite3_mprintf("%s-wal", zBase);
} }
zOal = sqlite3_mprintf("%s-oal", zMove);
zWal = sqlite3_mprintf("%s-wal", zMove);
assert( p->eStage==RBU_STAGE_MOVE ); assert( p->eStage==RBU_STAGE_MOVE );
assert( p->rc==SQLITE_OK && p->zErrmsg==0 ); 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. ** 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){ static void rbuIncrSchemaCookie(sqlite3rbu *p){
if( p->rc==SQLITE_OK ){ if( p->rc==SQLITE_OK ){
sqlite3 *dbread = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
int iCookie = 1000000; int iCookie = 1000000;
sqlite3_stmt *pStmt; sqlite3_stmt *pStmt;
p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, p->rc = prepareAndCollectError(dbread, &pStmt, &p->zErrmsg,
"PRAGMA schema_version" "PRAGMA schema_version"
); );
if( p->rc==SQLITE_OK ){ if( p->rc==SQLITE_OK ){
@ -3408,6 +3420,7 @@ static sqlite3rbu *openRbuHandle(
} }
if( p->rc==SQLITE_OK if( p->rc==SQLITE_OK
&& !rbuIsVacuum(p)
&& (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE) && (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE)
&& pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie && pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie
){ ){
@ -3803,34 +3816,6 @@ static int rbuVfsRead(
memset(zBuf, 0, iAmt); memset(zBuf, 0, iAmt);
}else{ }else{
rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); 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) ){ 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 /* These look like magic numbers. But they are stable, as they are part
@ -3838,6 +3823,13 @@ static int rbuVfsRead(
u8 *pBuf = (u8*)zBuf; u8 *pBuf = (u8*)zBuf;
p->iCookie = rbuGetU32(&pBuf[24]); p->iCookie = rbuGetU32(&pBuf[24]);
p->iWriteVer = pBuf[19]; 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; return rc;
@ -3905,20 +3897,7 @@ static int rbuVfsSync(sqlite3_file *pFile, int flags){
*/ */
static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
rbu_file *p = (rbu_file *)pFile; rbu_file *p = (rbu_file *)pFile;
int rc; return p->pReal->pMethods->xFileSize(p->pReal, pSize);
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;
} }
/* /*
@ -4156,6 +4135,33 @@ static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
return pDb; 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. ** Open an rbu file handle.
*/ */
@ -4191,6 +4197,7 @@ static int rbuVfsOpen(
rbu_file *pFd = (rbu_file *)pFile; rbu_file *pFd = (rbu_file *)pFile;
int rc = SQLITE_OK; int rc = SQLITE_OK;
const char *zOpen = zName; const char *zOpen = zName;
int oflags = flags;
memset(pFd, 0, sizeof(rbu_file)); memset(pFd, 0, sizeof(rbu_file));
pFd->pReal = (sqlite3_file*)&pFd[1]; 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 ** the name of the *-wal file this db connection will use. SQLite
** happens to pass a pointer to this buffer when using xAccess() ** happens to pass a pointer to this buffer when using xAccess()
** or xOpen() to operate on the *-wal file. */ ** or xOpen() to operate on the *-wal file. */
int n = (int)strlen(zName); pFd->zWal = rbuMainToWal(zName, flags);
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;
} }
else if( flags & SQLITE_OPEN_WAL ){ else if( flags & SQLITE_OPEN_WAL ){
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName); 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 ** 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 ** pair of '\0' bytes in case the VFS attempts to extract a URI
** parameter from it. */ ** parameter from it. */
size_t nCopy = strlen(zName); const char *zBase = zName;
char *zCopy = sqlite3_malloc64(nCopy+2); 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 ){ if( zCopy ){
memcpy(zCopy, zName, nCopy); memcpy(zCopy, zBase, nCopy);
zCopy[nCopy-3] = 'o'; zCopy[nCopy-3] = 'o';
zCopy[nCopy] = '\0'; zCopy[nCopy] = '\0';
zCopy[nCopy+1] = '\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 ){ 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 ){ if( pFd->pReal->pMethods ){
/* The xOpen() operation has succeeded. Set the sqlite3_file.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. 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-16T15:03:20.537 D 2016-04-16T17:53:14.824
F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.in eba680121821b8a60940a81454316f47a341487a
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
@ -247,7 +247,7 @@ F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
F ext/rbu/rbuvacuum.test 75b4231f85622859e814c7f028afad0303f72f60 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/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b
F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
@ -1483,7 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 0216b48f28042ad86711e00802c2da8ce9be3044 P 8eb3d7d8360530f364bbbebac53e1f0e6753d924
R 0603f47373db6aeb2d2c22dfe403e0e2 R 4d03a7f5bef5f70852d283bb46ff80e2
U dan U dan
Z 6e5ab10ab6efe323abcf341183f13408 Z 0a7d529e6f2d77bae387935d2996f1da

View File

@ -1 +1 @@
8eb3d7d8360530f364bbbebac53e1f0e6753d924 dc19aacc7e99213edca9bb57b5c11a8a1ac99113