From: dan Date: Sat, 16 Apr 2016 17:53:14 +0000 (+0000) Subject: Avoid creating any extra files ("-vacuum") when running an RBU vacuum. Ensure... X-Git-Tag: version-3.13.0~75^2~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=977cbe78b3945be39c0e353c77e25d6e1d161d35;p=thirdparty%2Fsqlite.git Avoid creating any extra files ("-vacuum") when running an RBU vacuum. Ensure that the OAL file created is "-oal", not "-vacuum-oal". FossilOrigin-Name: dc19aacc7e99213edca9bb57b5c11a8a1ac99113 --- diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index e71690769b..ff01f30725 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -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 diff --git a/manifest b/manifest index eeb8cf07ef..0e404f7022 100644 --- a/manifest +++ b/manifest @@ -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("-vacuum")\swhen\srunning\san\sRBU\svacuum.\sEnsure\sthat\sthe\sOAL\sfile\screated\sis\s"-oal",\snot\s"-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 diff --git a/manifest.uuid b/manifest.uuid index 773e6bf755..56172c7c76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8eb3d7d8360530f364bbbebac53e1f0e6753d924 \ No newline at end of file +dc19aacc7e99213edca9bb57b5c11a8a1ac99113 \ No newline at end of file