/ Check-in [7d83fbae]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Revert to allowing a cache spill during writes of multiple pages within a single sector as long as the spill does not require a journal sync and a new journal header.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7d83fbae9802a56b2121d0775de54fccd743d971
User & Date: drh 2010-06-24 18:36:33
Context
2010-06-24
19:16
Add test cases to pager1.test and pagerfault.test. check-in: 4941e437 user: dan tags: trunk
18:36
Revert to allowing a cache spill during writes of multiple pages within a single sector as long as the spill does not require a journal sync and a new journal header. check-in: 7d83fbae user: drh tags: trunk
17:37
Modify ctime.test to work with SQLITE_THREADSAFE=2. check-in: c6db3b30 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pager.c.

   301    301   **   then attempts to upgrade to an exclusive lock. If this attempt
   302    302   **   fails, then SQLITE_BUSY may be returned to the user and the user
   303    303   **   may attempt to commit the transaction again later (calling
   304    304   **   CommitPhaseOne() again). This flag is used to ensure that the 
   305    305   **   master journal name is only written to the journal file the first
   306    306   **   time CommitPhaseOne() is called.
   307    307   **
   308         -** doNotSpill
          308  +** doNotSpill, doNotSyncSpill
   309    309   **
   310         -**   When enabled, cache spills are prohibited and the journal file cannot
   311         -**   be synced.  This variable is set and cleared by sqlite3PagerWrite() 
   312         -**   in order to prevent a journal sync from happening in between the
   313         -**   journalling of two pages on the same sector.  It is also set to prevent
   314         -**   pagerStress() from trying to use the journal during a rollback.
          310  +**   When enabled, cache spills are prohibited.  The doNotSpill variable
          311  +**   inhibits all cache spill and doNotSyncSpill inhibits those spills that
          312  +**   would require a journal sync.  The doNotSyncSpill is set and cleared 
          313  +**   by sqlite3PagerWrite() in order to prevent a journal sync from happening 
          314  +**   in between the journalling of two pages on the same sector.  The
          315  +**   doNotSpill value set to prevent pagerStress() from trying to use
          316  +**   the journal during a rollback.
   315    317   **
   316    318   ** needSync
   317    319   **
   318    320   **   TODO: It might be easier to set this variable in writeJournalHdr()
   319    321   **   and writeMasterJournal() only. Change its meaning to "unsynced data
   320    322   **   has been written to the journal".
   321    323   **
................................................................................
   352    354     u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
   353    355     u8 dbModified;              /* True if there are any changes to the Db */
   354    356     u8 needSync;                /* True if an fsync() is needed on the journal */
   355    357     u8 journalStarted;          /* True if header of journal is synced */
   356    358     u8 changeCountDone;         /* Set after incrementing the change-counter */
   357    359     u8 setMaster;               /* True if a m-j name has been written to jrnl */
   358    360     u8 doNotSpill;              /* Do not spill the cache when non-zero */
          361  +  u8 doNotSyncSpill;          /* Do not do a spill that requires jrnl sync */
   359    362     u8 dbSizeValid;             /* Set when dbSize is correct */
   360    363     u8 subjInMemory;            /* True to use in-memory sub-journals */
   361    364     Pgno dbSize;                /* Number of pages in the database */
   362    365     Pgno dbOrigSize;            /* dbSize before the current transaction */
   363    366     Pgno dbFileSize;            /* Number of pages in the database file */
   364    367     int errCode;                /* One of several kinds of errors */
   365    368     int nRec;                   /* Pages journalled since last j-header written */
................................................................................
  3514   3517   static int pagerStress(void *p, PgHdr *pPg){
  3515   3518     Pager *pPager = (Pager *)p;
  3516   3519     int rc = SQLITE_OK;
  3517   3520   
  3518   3521     assert( pPg->pPager==pPager );
  3519   3522     assert( pPg->flags&PGHDR_DIRTY );
  3520   3523   
  3521         -  /* The doNotSpill flag is set during times when writing to the journal
  3522         -  ** is disallowed:  (1) during calls to sqlite3PagerWrite() while it
  3523         -  ** is journalling a set of two or more database pages that are stored
  3524         -  ** on the same disk sector, and (2) while performing a rollback.
         3524  +  /* The doNotSyncSpill flag is set during times when doing a sync of
         3525  +  ** journal (and adding a new header) is not allowed.  This occurs
         3526  +  ** during calls to sqlite3PagerWrite() while trying to journal multiple
         3527  +  ** pages belonging to the same sector.
         3528  +  **
         3529  +  ** The doNotSpill flag inhibits all cache spilling regardless of whether
         3530  +  ** or not a sync is required.  This is set during a rollback.
  3525   3531     **
  3526         -  ** Similarly, if the pager has already entered the error state, do not
  3527         -  ** try to write the contents of pPg to disk.
         3532  +  ** Spilling is also inhibited when in an error state.
  3528   3533     */
  3529         -  if( pPager->errCode || pPager->doNotSpill ){
         3534  +  if( pPager->errCode ) return SQLITE_OK;
         3535  +  if( pPager->doNotSpill ) return SQLITE_OK;
         3536  +  if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){
  3530   3537       return SQLITE_OK;
  3531   3538     }
  3532   3539   
  3533   3540     pPg->pDirty = 0;
  3534   3541     if( pagerUseWal(pPager) ){
  3535   3542       /* Write a single frame for this page to the log. */
  3536   3543       if( subjRequiresPage(pPg) ){ 
................................................................................
  4830   4837     if( nPagePerSector>1 ){
  4831   4838       Pgno nPageCount;          /* Total number of pages in database file */
  4832   4839       Pgno pg1;                 /* First page of the sector pPg is located on. */
  4833   4840       int nPage;                /* Number of pages starting at pg1 to journal */
  4834   4841       int ii;                   /* Loop counter */
  4835   4842       int needSync = 0;         /* True if any page has PGHDR_NEED_SYNC */
  4836   4843   
  4837         -    /* Set the doNotSpill flag to 1. This is because we cannot allow a journal
  4838         -    ** header to be written between the pages journaled by this function.
         4844  +    /* Set the doNotSyncSpill flag to 1. This is because we cannot allow
         4845  +    ** a journal header to be written between the pages journaled by
         4846  +    ** this function.
  4839   4847       */
  4840   4848       assert( !MEMDB );
  4841         -    assert( pPager->doNotSpill==0 );
  4842         -    pPager->doNotSpill++;
         4849  +    assert( pPager->doNotSyncSpill==0 );
         4850  +    pPager->doNotSyncSpill++;
  4843   4851   
  4844   4852       /* This trick assumes that both the page-size and sector-size are
  4845   4853       ** an integer power of 2. It sets variable pg1 to the identifier
  4846   4854       ** of the first page of the sector pPg is located on.
  4847   4855       */
  4848   4856       pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
  4849   4857   
................................................................................
  4897   4905             pPage->flags |= PGHDR_NEED_SYNC;
  4898   4906             sqlite3PagerUnref(pPage);
  4899   4907           }
  4900   4908         }
  4901   4909         assert(pPager->needSync);
  4902   4910       }
  4903   4911   
  4904         -    assert( pPager->doNotSpill==1 );
  4905         -    pPager->doNotSpill--;
         4912  +    assert( pPager->doNotSyncSpill==1 );
         4913  +    pPager->doNotSyncSpill--;
  4906   4914     }else{
  4907   4915       rc = pager_write(pDbPage);
  4908   4916     }
  4909   4917     return rc;
  4910   4918   }
  4911   4919   
  4912   4920   /*