/ Check-in [347f22a5]
Login

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

Overview
Comment:Remove variable Pager.needSync, which was almost completely unused.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: 347f22a5b777af92873590a5b9af5a6498bef918
User & Date: dan 2010-07-30 15:43:13
Context
2010-08-02
14:32
Experimental refactoring of the Pager object state. This version is surely buggy. check-in: 03a24051 user: dan tags: experimental
2010-07-30
15:43
Remove variable Pager.needSync, which was almost completely unused. check-in: 347f22a5 user: dan tags: experimental
14:39
Merge trunk changes into experimental again. check-in: 87e0f4e1 user: dan tags: experimental
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pager.c.

   321    321   **   inhibits all cache spill and doNotSyncSpill inhibits those spills that
   322    322   **   would require a journal sync.  The doNotSyncSpill is set and cleared 
   323    323   **   by sqlite3PagerWrite() in order to prevent a journal sync from happening 
   324    324   **   in between the journalling of two pages on the same sector.  The
   325    325   **   doNotSpill value set to prevent pagerStress() from trying to use
   326    326   **   the journal during a rollback.
   327    327   **
   328         -** needSync
   329         -**
   330         -**   TODO: It might be easier to set this variable in writeJournalHdr()
   331         -**   and writeMasterJournal() only. Change its meaning to "unsynced data
   332         -**   has been written to the journal".
   333         -**
   334    328   ** subjInMemory
   335    329   **
   336    330   **   This is a boolean variable. If true, then any required sub-journal
   337    331   **   is opened as an in-memory journal file. If false, then in-memory
   338    332   **   sub-journals are only used for in-memory pager files.
   339    333   */
   340    334   struct Pager {
................................................................................
   359    353     ** The 'state' variable is described in more detail along with the
   360    354     ** descriptions of the values it may take - PAGER_UNLOCK etc. Many of the
   361    355     ** other variables in this block are described in the comment directly 
   362    356     ** above this class definition.
   363    357     */
   364    358     u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
   365    359     u8 dbModified;              /* True if there are any changes to the Db */
   366         -  u8 needSync;                /* True if an fsync() is needed on the journal */
   367    360     u8 journalStarted;          /* True if header of journal is synced */
   368    361     u8 changeCountDone;         /* Set after incrementing the change-counter */
   369    362     u8 setMaster;               /* True if a m-j name has been written to jrnl */
   370    363     u8 doNotSpill;              /* Do not spill the cache when non-zero */
   371    364     u8 doNotSyncSpill;          /* Do not do a spill that requires jrnl sync */
   372    365     u8 dbSizeValid;             /* Set when dbSize is correct */
   373    366     u8 subjInMemory;            /* True to use in-memory sub-journals */
................................................................................
  1115   1108      || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster)))
  1116   1109      || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum)))
  1117   1110      || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8)))
  1118   1111     ){
  1119   1112       return rc;
  1120   1113     }
  1121   1114     pPager->journalOff += (nMaster+20);
  1122         -  pPager->needSync = !pPager->noSync;
  1123   1115   
  1124   1116     /* If the pager is in peristent-journal mode, then the physical 
  1125   1117     ** journal-file may extend past the end of the master-journal name
  1126   1118     ** and 8 bytes of magic data just written to the file. This is 
  1127   1119     ** dangerous because the code to rollback a hot-journal file
  1128   1120     ** will not be able to find the master-journal name to determine 
  1129   1121     ** whether or not the journal is hot. 
................................................................................
  1481   1473       rc2 = osUnlock(pPager->fd, SHARED_LOCK);
  1482   1474       pPager->state = PAGER_SHARED;
  1483   1475       pPager->changeCountDone = 0;
  1484   1476     }else if( pPager->state==PAGER_SYNCED ){
  1485   1477       pPager->state = PAGER_EXCLUSIVE;
  1486   1478     }
  1487   1479     pPager->setMaster = 0;
  1488         -  pPager->needSync = 0;
  1489   1480     pPager->dbModified = 0;
  1490   1481   
  1491   1482     /* TODO: Is this optimal? Why is the db size invalidated here 
  1492   1483     ** when the database file is not unlocked? */
  1493   1484     pPager->dbOrigSize = 0;
  1494   1485     sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
  1495   1486     if( !MEMDB ){
................................................................................
  2677   2668   ** and FULL=3.
  2678   2669   */
  2679   2670   #ifndef SQLITE_OMIT_PAGER_PRAGMAS
  2680   2671   void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int bFullFsync){
  2681   2672     pPager->noSync =  (level==1 || pPager->tempFile) ?1:0;
  2682   2673     pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
  2683   2674     pPager->sync_flags = (bFullFsync?SQLITE_SYNC_FULL:SQLITE_SYNC_NORMAL);
  2684         -  if( pPager->noSync ) pPager->needSync = 0;
  2685   2675   }
  2686   2676   #endif
  2687   2677   
  2688   2678   /*
  2689   2679   ** The following global variable is incremented whenever the library
  2690   2680   ** attempts to open a temporary file.  This information is used for
  2691   2681   ** testing and analysis only.  
................................................................................
  3177   3167   }
  3178   3168   
  3179   3169   /*
  3180   3170   ** Sync the journal. In other words, make sure all the pages that have
  3181   3171   ** been written to the journal have actually reached the surface of the
  3182   3172   ** disk and can be restored in the event of a hot-journal rollback.
  3183   3173   **
  3184         -** If the Pager.needSync flag is not set, then this function is a
  3185         -** no-op. Otherwise, the actions required depend on the journal-mode
  3186         -** and the device characteristics of the the file-system, as follows:
         3174  +** If the Pager.noSync flag is set, then this function is a no-op. 
         3175  +** Otherwise, the actions required depend on the journal-mode and the 
         3176  +** device characteristics of the the file-system, as follows:
  3187   3177   **
  3188   3178   **   * If the journal file is an in-memory journal file, no action need
  3189   3179   **     be taken.
  3190   3180   **
  3191   3181   **   * Otherwise, if the device does not support the SAFE_APPEND property,
  3192   3182   **     then the nRec field of the most recently written journal header
  3193   3183   **     is updated to contain the number of journal records that have
................................................................................
  3203   3193   **     if( NOT SAFE_APPEND ){
  3204   3194   **       if( <full-sync mode> ) xSync(<journal file>);
  3205   3195   **       <update nRec field>
  3206   3196   **     } 
  3207   3197   **     if( NOT SEQUENTIAL ) xSync(<journal file>);
  3208   3198   **   }
  3209   3199   **
  3210         -** The Pager.needSync flag is never be set for temporary files, or any
  3211         -** file operating in no-sync mode (Pager.noSync set to non-zero).
  3212         -**
  3213   3200   ** If successful, this routine clears the PGHDR_NEED_SYNC flag of every 
  3214   3201   ** page currently held in memory before returning SQLITE_OK. If an IO
  3215   3202   ** error is encountered, then the IO error code is returned to the caller.
  3216   3203   */
  3217   3204   static int syncJournal(Pager *pPager){
  3218         -  if( pPager->needSync ){
         3205  +  if( !pPager->noSync ){
  3219   3206       assert( !pPager->tempFile );
  3220         -    if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){
         3207  +    if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY 
         3208  +     && pPager->journalMode!=PAGER_JOURNALMODE_OFF 
         3209  +    ){
  3221   3210         int rc;                              /* Return code */
  3222   3211         const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
  3223   3212         assert( isOpen(pPager->jfd) );
  3224   3213   
  3225   3214         if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
  3226   3215           /* This block deals with an obscure problem. If the last connection
  3227   3216           ** that wrote to this database was operating in persistent-journal
................................................................................
  3291   3280           rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags| 
  3292   3281             (pPager->sync_flags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
  3293   3282           );
  3294   3283           if( rc!=SQLITE_OK ) return rc;
  3295   3284         }
  3296   3285       }
  3297   3286   
  3298         -    /* The journal file was just successfully synced. Set Pager.needSync 
  3299         -    ** to zero and clear the PGHDR_NEED_SYNC flag on all pagess.
         3287  +    /* The journal file was just successfully synced. Clear the 
         3288  +    ** PGHDR_NEED_SYNC flag on all pagess.
  3300   3289       */
  3301         -    pPager->needSync = 0;
  3302   3290       pPager->journalStarted = 1;
  3303   3291       pPager->journalHdr = pPager->journalOff;
  3304   3292       sqlite3PcacheClearSyncFlags(pPager->pPCache);
  3305   3293     }
  3306   3294   
  3307   3295     return SQLITE_OK;
  3308   3296   }
................................................................................
  3390   3378       **
  3391   3379       ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag
  3392   3380       ** set (set by sqlite3PagerDontWrite()).
  3393   3381       */
  3394   3382       if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
  3395   3383         i64 offset = (pgno-1)*(i64)pPager->pageSize;   /* Offset to write */
  3396   3384         char *pData;                                   /* Data to write */    
         3385  +
         3386  +      assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
  3397   3387   
  3398   3388         /* Encode the database */
  3399   3389         CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
  3400   3390   
  3401   3391         /* Write out the page data. */
  3402   3392         rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
  3403   3393   
................................................................................
  3600   3590           rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
  3601   3591       ) ){
  3602   3592         rc = subjournalPage(pPg);
  3603   3593       }
  3604   3594     
  3605   3595       /* Write the contents of the page out to the database file. */
  3606   3596       if( rc==SQLITE_OK ){
         3597  +      assert( (pPg->flags&PGHDR_NEED_SYNC)==0 );
  3607   3598         rc = pager_write_pagelist(pPager, pPg);
  3608   3599       }
  3609   3600     }
  3610   3601   
  3611   3602     /* Mark the page as clean. */
  3612   3603     if( rc==SQLITE_OK ){
  3613   3604       PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
................................................................................
  3881   3872     assert( tempFile==PAGER_LOCKINGMODE_NORMAL 
  3882   3873             || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
  3883   3874     assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
  3884   3875     pPager->exclusiveMode = (u8)tempFile; 
  3885   3876     pPager->changeCountDone = pPager->tempFile;
  3886   3877     pPager->memDb = (u8)memDb;
  3887   3878     pPager->readOnly = (u8)readOnly;
  3888         -  /* pPager->needSync = 0; */
  3889   3879     assert( useJournal || pPager->tempFile );
  3890   3880     pPager->noSync = pPager->tempFile;
  3891   3881     pPager->fullSync = pPager->noSync ?0:1;
  3892   3882     pPager->sync_flags = SQLITE_SYNC_NORMAL;
  3893   3883     /* pPager->pFirst = 0; */
  3894   3884     /* pPager->pFirstSynced = 0; */
  3895   3885     /* pPager->pLast = 0; */
................................................................................
  4546   4536     /* Write the first journal header to the journal file and open 
  4547   4537     ** the sub-journal if necessary.
  4548   4538     */
  4549   4539     if( rc==SQLITE_OK ){
  4550   4540       /* TODO: Check if all of these are really required. */
  4551   4541       pPager->dbOrigSize = pPager->dbSize;
  4552   4542       pPager->journalStarted = 0;
  4553         -    pPager->needSync = 0;
  4554   4543       pPager->nRec = 0;
  4555   4544       pPager->journalOff = 0;
  4556   4545       pPager->setMaster = 0;
  4557   4546       pPager->journalHdr = 0;
  4558   4547       rc = writeJournalHdr(pPager);
  4559   4548     }
  4560   4549   
................................................................................
  4766   4755           ** Otherwise, when the transaction is rolled back, the logic in
  4767   4756           ** playback_one_page() will think that the page needs to be restored
  4768   4757           ** in the database file. And if an IO error occurs while doing so,
  4769   4758           ** then corruption may follow.
  4770   4759           */
  4771   4760           if( !pPager->noSync ){
  4772   4761             pPg->flags |= PGHDR_NEED_SYNC;
  4773         -          pPager->needSync = 1;
  4774   4762           }
  4775   4763   
  4776   4764           /* An error has occurred writing to the journal file. The 
  4777   4765           ** transaction will be rolled back by the layer above.
  4778   4766           */
  4779   4767           if( rc!=SQLITE_OK ){
  4780   4768             return rc;
................................................................................
  4789   4777           if( rc!=SQLITE_OK ){
  4790   4778             assert( rc==SQLITE_NOMEM );
  4791   4779             return rc;
  4792   4780           }
  4793   4781         }else{
  4794   4782           if( !pPager->journalStarted && !pPager->noSync ){
  4795   4783             pPg->flags |= PGHDR_NEED_SYNC;
  4796         -          pPager->needSync = 1;
  4797   4784           }
  4798   4785           PAGERTRACE(("APPEND %d page %d needSync=%d\n",
  4799   4786                   PAGERID(pPager), pPg->pgno,
  4800   4787                  ((pPg->flags&PGHDR_NEED_SYNC)?1:0)));
  4801   4788         }
  4802   4789       }
  4803   4790     
................................................................................
  4882   4869         if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
  4883   4870           if( pg!=PAGER_MJ_PGNO(pPager) ){
  4884   4871             rc = sqlite3PagerGet(pPager, pg, &pPage);
  4885   4872             if( rc==SQLITE_OK ){
  4886   4873               rc = pager_write(pPage);
  4887   4874               if( pPage->flags&PGHDR_NEED_SYNC ){
  4888   4875                 needSync = 1;
  4889         -              assert(pPager->needSync);
  4890   4876               }
  4891   4877               sqlite3PagerUnref(pPage);
  4892   4878             }
  4893   4879           }
  4894   4880         }else if( (pPage = pager_lookup(pPager, pg))!=0 ){
  4895   4881           if( pPage->flags&PGHDR_NEED_SYNC ){
  4896   4882             needSync = 1;
................................................................................
  4910   4896         for(ii=0; ii<nPage; ii++){
  4911   4897           PgHdr *pPage = pager_lookup(pPager, pg1+ii);
  4912   4898           if( pPage ){
  4913   4899             pPage->flags |= PGHDR_NEED_SYNC;
  4914   4900             sqlite3PagerUnref(pPage);
  4915   4901           }
  4916   4902         }
  4917         -      assert(pPager->needSync);
  4918   4903       }
  4919   4904   
  4920   4905       assert( pPager->doNotSyncSpill==1 );
  4921   4906       pPager->doNotSyncSpill--;
  4922   4907     }else{
  4923   4908       rc = pager_write(pDbPage);
  4924   4909     }
................................................................................
  5241   5226         /* Write the master journal name into the journal file. If a master 
  5242   5227         ** journal file name has already been written to the journal file, 
  5243   5228         ** or if zMaster is NULL (no master journal), then this call is a no-op.
  5244   5229         */
  5245   5230         rc = writeMasterJournal(pPager, zMaster);
  5246   5231         if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  5247   5232     
  5248         -      /* Sync the journal file. If the atomic-update optimization is being
  5249         -      ** used, this call will not create the journal file or perform any
  5250         -      ** real IO.
         5233  +      /* Sync the journal file and write all dirty pages to the database.
         5234  +      ** If the atomic-update optimization is being used, this sync will not 
         5235  +      ** create the journal file or perform any real IO.
         5236  +      **
         5237  +      ** Because the change-counter page was just modified, unless the
         5238  +      ** atomic-update optimization is used it is almost certain that the
         5239  +      ** journal requires a sync here. However, in locking_mode=exclusive
         5240  +      ** on a system under memory pressure it is just possible that this is 
         5241  +      ** not the case. In this case it is likely enough that the redundant
         5242  +      ** xSync() call will be changed to a no-op by the OS anyhow. 
  5251   5243         */
  5252   5244         rc = syncJournal(pPager);
  5253   5245         if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  5254         -  
  5255         -      /* Write all dirty pages to the database file. */
         5246  +
  5256   5247         rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
  5257   5248         if( rc!=SQLITE_OK ){
  5258   5249           assert( rc!=SQLITE_IOERR_BLOCKED );
  5259   5250           goto commit_phase_one_exit;
  5260   5251         }
  5261   5252         sqlite3PcacheCleanAll(pPager->pPCache);
  5262   5253     
................................................................................
  5762   5753     ** the journal needs to be sync()ed before database page pPg->pgno 
  5763   5754     ** can be written to. The caller has already promised not to write to it.
  5764   5755     */
  5765   5756     if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
  5766   5757       needSyncPgno = pPg->pgno;
  5767   5758       assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
  5768   5759       assert( pPg->flags&PGHDR_DIRTY );
  5769         -    assert( pPager->needSync );
  5770   5760     }
  5771   5761   
  5772   5762     /* If the cache contains a page with page-number pgno, remove it
  5773         -  ** from its hash chain. Also, if the PgHdr.needSync was set for 
         5763  +  ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for 
  5774   5764     ** page pgno before the 'move' operation, it needs to be retained 
  5775   5765     ** for the page moved there.
  5776   5766     */
  5777   5767     pPg->flags &= ~PGHDR_NEED_SYNC;
  5778   5768     pPgOld = pager_lookup(pPager, pgno);
  5779   5769     assert( !pPgOld || pPgOld->nRef==1 );
  5780   5770     if( pPgOld ){
................................................................................
  5795   5785     pPager->dbModified = 1;
  5796   5786   
  5797   5787     if( needSyncPgno ){
  5798   5788       /* If needSyncPgno is non-zero, then the journal file needs to be 
  5799   5789       ** sync()ed before any data is written to database file page needSyncPgno.
  5800   5790       ** Currently, no such page exists in the page-cache and the 
  5801   5791       ** "is journaled" bitvec flag has been set. This needs to be remedied by
  5802         -    ** loading the page into the pager-cache and setting the PgHdr.needSync 
         5792  +    ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC
  5803   5793       ** flag.
  5804   5794       **
  5805   5795       ** If the attempt to load the page into the page-cache fails, (due
  5806   5796       ** to a malloc() or IO failure), clear the bit in the pInJournal[]
  5807   5797       ** array. Otherwise, if the page is loaded and written again in
  5808   5798       ** this transaction, it may be written to the database file before
  5809   5799       ** it is synced into the journal file. This way, it may end up in
  5810   5800       ** the journal file twice, but that is not a problem.
  5811         -    **
  5812         -    ** The sqlite3PagerGet() call may cause the journal to sync. So make
  5813         -    ** sure the Pager.needSync flag is set too.
  5814   5801       */
  5815   5802       PgHdr *pPgHdr;
  5816         -    assert( pPager->needSync );
  5817   5803       rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
  5818   5804       if( rc!=SQLITE_OK ){
  5819   5805         if( needSyncPgno<=pPager->dbOrigSize ){
  5820   5806           assert( pPager->pTmpSpace!=0 );
  5821   5807           sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
  5822   5808         }
  5823   5809         return rc;
  5824   5810       }
  5825         -    pPager->needSync = 1;
  5826   5811       assert( pPager->noSync==0 && !MEMDB );
  5827   5812       pPgHdr->flags |= PGHDR_NEED_SYNC;
  5828   5813       sqlite3PcacheMakeDirty(pPgHdr);
  5829   5814       sqlite3PagerUnref(pPgHdr);
  5830   5815     }
  5831   5816   
  5832   5817     /*