/ Check-in [228e7c34]
Login

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

Overview
Comment:Fix the change-counter increment for WAL pages so that it works even when invoked from xStress. Ticket [5d863f876ee9561b95e2].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | bug-5d863f87
Files: files | file ages | folders
SHA1:228e7c34c64114670fe015747d47fdaa3b7e1270
User & Date: drh 2011-01-15 18:11:12
Original Comment: Fix the change-counter increment for WAL pages so that it works even when invoked from xStress. Ticket [5d863f876ee9561b95e2].
Context
2011-01-15
21:42
Make sure the change counter and SQLite version numbers in the header are set correctly, even when running in WAL mode and when VACUUMing in WAL mode. Ticket [5d863f876ee9561b9]. check-in: 0be92a75 user: drh tags: trunk
18:11
Fix the change-counter increment for WAL pages so that it works even when invoked from xStress. Ticket [5d863f876ee9561b95e2]. Closed-Leaf check-in: 228e7c34 user: drh tags: bug-5d863f87
17:12
Increment the change counter and update the SQLite version number whenever page 1 is added to the WAL. Ticket [5d863f876ee9561b9] check-in: c1e0d09c user: drh tags: bug-5d863f87
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pager.c.

  2911   2911       rc = pagerUndoCallback((void *)pPager, pList->pgno);
  2912   2912       pList = pNext;
  2913   2913     }
  2914   2914   
  2915   2915     return rc;
  2916   2916   }
  2917   2917   
  2918         -/* Forward declaration */
  2919         -static int pager_incr_changecounter(Pager*,int);
         2918  +
         2919  +/*
         2920  +** Update the value of the change-counter at offsets 24 and 92 in
         2921  +** the header and the sqlite version number at offset 96.
         2922  +**
         2923  +** This is an unconditional update.  See also the pager_incr_changecounter()
         2924  +** routine which only updates the change-counter if the update is actually
         2925  +** needed, as determined by the pPager->changeCountDone state variable.
         2926  +*/
         2927  +static void pager_write_changecounter(PgHdr *pPg){
         2928  +  u32 change_counter;
         2929  +
         2930  +  /* Increment the value just read and write it back to byte 24. */
         2931  +  change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1;
         2932  +  put32bits(((char*)pPg->pData)+24, change_counter);
         2933  +
         2934  +  /* Also store the SQLite version number in bytes 96..99 and in
         2935  +  ** bytes 92..95 store the change counter for which the version number
         2936  +  ** is valid. */
         2937  +  put32bits(((char*)pPg->pData)+92, change_counter);
         2938  +  put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER);
         2939  +}
  2920   2940   
  2921   2941   /*
  2922   2942   ** This function is a wrapper around sqlite3WalFrames(). As well as logging
  2923   2943   ** the contents of the list of pages headed by pList (connected by pDirty),
  2924   2944   ** this function notifies any active backup processes that the pages have
  2925   2945   ** changed.
  2926   2946   **
................................................................................
  2943   2963   #ifdef SQLITE_DEBUG
  2944   2964     /* Verify that the page list is in accending order */
  2945   2965     for(p=pList; p && p->pDirty; p=p->pDirty){
  2946   2966       assert( p->pgno < p->pDirty->pgno );
  2947   2967     }
  2948   2968   #endif
  2949   2969   
  2950         -  if( pList->pgno==1 ){
  2951         -    pPager->changeCountDone = 0;
  2952         -    pager_incr_changecounter(pPager,0);
  2953         -    pPager->changeCountDone = 0;
  2954         -  }
         2970  +  if( pList->pgno==1 ) pager_write_changecounter(pList);
  2955   2971     rc = sqlite3WalFrames(pPager->pWal, 
  2956   2972         pPager->pageSize, pList, nTruncate, isCommit, syncFlags
  2957   2973     );
  2958   2974     if( rc==SQLITE_OK && pPager->pBackup ){
  2959   2975       PgHdr *p;
  2960   2976       for(p=pList; p; p=p->pDirty){
  2961   2977         sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
................................................................................
  5505   5521       pager_set_pagehash(pPg);
  5506   5522     }
  5507   5523   }
  5508   5524   
  5509   5525   /*
  5510   5526   ** This routine is called to increment the value of the database file 
  5511   5527   ** change-counter, stored as a 4-byte big-endian integer starting at 
  5512         -** byte offset 24 of the pager file.
         5528  +** byte offset 24 of the pager file.  The secondary change counter at
         5529  +** 92 is also updated, as is the SQLite version number at offset 96.
         5530  +**
         5531  +** But this only happens if the pPager->changeCountDone flag is false.
         5532  +** To avoid excess churning of page 1, the update only happens once.
         5533  +** See also the pager_write_changecounter() routine that does an 
         5534  +** unconditional update of the change counters.
  5513   5535   **
  5514   5536   ** If the isDirectMode flag is zero, then this is done by calling 
  5515   5537   ** sqlite3PagerWrite() on page 1, then modifying the contents of the
  5516   5538   ** page data. In this case the file will be updated when the current
  5517   5539   ** transaction is committed.
  5518   5540   **
  5519   5541   ** The isDirectMode flag may only be non-zero if the library was compiled
................................................................................
  5546   5568     UNUSED_PARAMETER(isDirectMode);
  5547   5569   #else
  5548   5570   # define DIRECT_MODE isDirectMode
  5549   5571   #endif
  5550   5572   
  5551   5573     if( !pPager->changeCountDone && pPager->dbSize>0 ){
  5552   5574       PgHdr *pPgHdr;                /* Reference to page 1 */
  5553         -    u32 change_counter;           /* Initial value of change-counter field */
  5554   5575   
  5555   5576       assert( !pPager->tempFile && isOpen(pPager->fd) );
  5556   5577   
  5557   5578       /* Open page 1 of the file for writing. */
  5558   5579       rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
  5559   5580       assert( pPgHdr==0 || rc==SQLITE_OK );
  5560   5581   
................................................................................
  5564   5585       ** above is always successful - hence the ALWAYS on rc==SQLITE_OK.
  5565   5586       */
  5566   5587       if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){
  5567   5588         rc = sqlite3PagerWrite(pPgHdr);
  5568   5589       }
  5569   5590   
  5570   5591       if( rc==SQLITE_OK ){
  5571         -      /* Increment the value just read and write it back to byte 24. */
  5572         -      change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers);
  5573         -      change_counter++;
  5574         -      put32bits(((char*)pPgHdr->pData)+24, change_counter);
  5575         -
  5576         -      /* Also store the SQLite version number in bytes 96..99 and in
  5577         -      ** bytes 92..95 store the change counter for which the version number
  5578         -      ** is valid. */
  5579         -      put32bits(((char*)pPgHdr->pData)+92, change_counter);
  5580         -      put32bits(((char*)pPgHdr->pData)+96, SQLITE_VERSION_NUMBER);
         5592  +      /* Actually do the update of the change counter */
         5593  +      pager_write_changecounter(pPgHdr);
  5581   5594   
  5582   5595         /* If running in direct mode, write the contents of page 1 to the file. */
  5583   5596         if( DIRECT_MODE ){
  5584   5597           const void *zBuf;
  5585   5598           assert( pPager->dbFileSize>0 );
  5586   5599           CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf);
  5587   5600           if( rc==SQLITE_OK ){