/ Check-in [29407d70]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Another fix to rbu vacuum for a zipvfs case.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | rbu-vacuum
Files: files | file ages | folders
SHA1: 29407d70e44ad9ea5ddaf1011d0e212b602a3ddf
User & Date: dan 2016-04-18 21:00:01
Context
2016-04-19
16:20
Detect attempts to use rbu vacuum on a wal mode database (not allowed). And attempts to write to a database in the middle of an rbu vacuum (which prevents the vacuum from resuming). check-in: 00b2f4b0 user: dan tags: rbu-vacuum
2016-04-18
21:00
Another fix to rbu vacuum for a zipvfs case. check-in: 29407d70 user: dan tags: rbu-vacuum
18:18
Fix some zipvfs related problems in RBU vacuum. check-in: d76f4aaa user: dan tags: rbu-vacuum
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/rbu/sqlite3rbu.c.

   366    366     u32 mLock;
   367    367     int nFrame;                     /* Entries in aFrame[] array */
   368    368     int nFrameAlloc;                /* Allocated size of aFrame[] array */
   369    369     RbuFrame *aFrame;
   370    370     int pgsz;
   371    371     u8 *aBuf;
   372    372     i64 iWalCksum;
          373  +
          374  +  /* Used in RBU vacuum mode only */
          375  +  int nRbu;                       /* Number of RBU VFS in the stack */
          376  +  rbu_file *pRbuFd;               /* Fd for main db of dbRbu */
   373    377   };
   374    378   
   375    379   /*
   376    380   ** An rbu VFS is implemented using an instance of this structure.
   377    381   */
   378    382   struct rbu_vfs {
   379    383     sqlite3_vfs base;               /* rbu VFS shim methods */
................................................................................
  2324   2328   
  2325   2329   
  2326   2330   /*
  2327   2331   ** Open the database handle and attach the RBU database as "rbu". If an
  2328   2332   ** error occurs, leave an error code and message in the RBU handle.
  2329   2333   */
  2330   2334   static void rbuOpenDatabase(sqlite3rbu *p){
  2331         -  int nRbu = 0;
  2332   2335     assert( p->rc==SQLITE_OK );
  2333   2336     assert( p->dbMain==0 && p->dbRbu==0 );
  2334   2337     assert( rbuIsVacuum(p) || p->zTarget!=0 );
  2335   2338   
  2336   2339     /* Open the RBU database */
  2337   2340     p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
  2338   2341   
  2339   2342     if( rbuIsVacuum(p) ){
  2340         -    sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, &nRbu);
         2343  +    sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
  2341   2344     }
  2342   2345   
  2343   2346     /* If using separate RBU and state databases, attach the state database to
  2344   2347     ** the RBU db handle now.  */
  2345   2348     if( p->zState ){
  2346   2349       rbuMPrintfExec(p, p->dbRbu, "ATTACH %Q AS stat", p->zState);
  2347   2350       memcpy(p->zStateDb, "stat", 4);
................................................................................
  2350   2353     }
  2351   2354   
  2352   2355     /* If it has not already been created, create the rbu_state table */
  2353   2356     rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb);
  2354   2357   
  2355   2358     if( rbuIsVacuum(p) ){
  2356   2359       int bOpen = 0;
         2360  +    p->nRbu = 0;
         2361  +    p->pRbuFd = 0;
         2362  +    sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
  2357   2363       if( p->eStage>=RBU_STAGE_MOVE ){
  2358   2364         bOpen = 1;
  2359   2365       }else{
  2360   2366         RbuState *pState = rbuLoadState(p);
  2361   2367         if( pState ){
  2362   2368           bOpen = (pState->eStage>RBU_STAGE_MOVE);
  2363   2369           rbuFreeState(pState);
  2364   2370         }
  2365   2371       }
  2366         -    if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, nRbu<=1);
         2372  +    if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, p->nRbu<=1);
  2367   2373     }
  2368   2374   
  2369   2375     p->eStage = 0;
  2370   2376     if( p->dbMain==0 ){
  2371   2377       if( !rbuIsVacuum(p) ){
  2372   2378         p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
  2373   2379       }else{
  2374   2380         char *zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1", p->zRbu);
  2375   2381         if( zTarget==0 ){
  2376   2382           p->rc = SQLITE_NOMEM;
  2377   2383           return;
  2378   2384         }
  2379         -      p->dbMain = rbuOpenDbhandle(p, zTarget, nRbu<=1);
         2385  +      p->dbMain = rbuOpenDbhandle(p, zTarget, p->nRbu<=1);
  2380   2386         sqlite3_free(zTarget);
  2381   2387       }
  2382   2388     }
  2383   2389   
  2384   2390     if( p->rc==SQLITE_OK ){
  2385   2391       p->rc = sqlite3_create_function(p->dbMain, 
  2386   2392           "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0
................................................................................
  3819   3825       }else{
  3820   3826         rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
  3821   3827   #if 1
  3822   3828         /* If this is being called to read the first page of the target 
  3823   3829         ** database as part of an rbu vacuum operation, synthesize the 
  3824   3830         ** contents of the first page if it does not yet exist. Otherwise,
  3825   3831         ** SQLite will not check for a *-wal file.  */
  3826         -      if( p->pRbu && rbuIsVacuum(p->pRbu) 
         3832  +      if( pRbu && rbuIsVacuum(pRbu) 
  3827   3833             && rc==SQLITE_IOERR_SHORT_READ && iOfst==0
  3828   3834             && (p->openFlags & SQLITE_OPEN_MAIN_DB)
  3829   3835         ){
  3830         -        sqlite3_file *pFd = 0;
  3831         -        rc = sqlite3_file_control(
  3832         -            p->pRbu->dbRbu, "main", SQLITE_FCNTL_FILE_POINTER, (void*)&pFd
  3833         -        );
  3834         -        if( rc==SQLITE_OK ){
  3835         -          rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst);
  3836         -        }
         3836  +        sqlite3_file *pFd = (sqlite3_file*)pRbu->pRbuFd;
         3837  +        rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst);
  3837   3838           if( rc==SQLITE_OK ){
  3838   3839             u8 *aBuf = (u8*)zBuf;
  3839   3840             rbuPutU32(&aBuf[52], 0);          /* largest root page number */
  3840   3841             rbuPutU32(&aBuf[36], 0);          /* number of free pages */
  3841   3842             rbuPutU32(&aBuf[32], 0);          /* first page on free list trunk */
  3842   3843             rbuPutU32(&aBuf[28], 1);          /* size of db file in pages */
  3843   3844   
................................................................................
  4017   4018           if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
  4018   4019           rc = SQLITE_OK;
  4019   4020         }
  4020   4021       }
  4021   4022       return rc;
  4022   4023     }
  4023   4024     else if( op==SQLITE_FCNTL_RBUCNT ){
  4024         -    int *pnRbu = (int*)pArg;
  4025         -    (*pnRbu)++;
         4025  +    sqlite3rbu *pRbu = (sqlite3rbu*)pArg;
         4026  +    pRbu->nRbu++;
         4027  +    pRbu->pRbuFd = p;
  4026   4028       p->bNolock = 1;
  4027   4029     }
  4028   4030   
  4029   4031     rc = xControl(p->pReal, op, pArg);
  4030   4032     if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
  4031   4033       rbu_vfs *pRbuVfs = p->pRbuVfs;
  4032   4034       char *zIn = *(char**)pArg;