/ Check-in [9687b305]
Login

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

Overview
Comment:In persistent WAL mode, truncate the WAL file to the size specified by the journal_size_limit pragma when disconnecting from the WAL.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9687b305c2320109a8649612181eecd2e0da7c7b
User & Date: drh 2011-12-08 19:50:32
Context
2011-12-08
20:41
Hand merge the zone allocator for MacOS from the apple-osx branch. check-in: 0d955c20 user: drh tags: trunk
19:50
In persistent WAL mode, truncate the WAL file to the size specified by the journal_size_limit pragma when disconnecting from the WAL. check-in: 9687b305 user: drh tags: trunk
03:51
Follow the previously established pattern for detecting preprocessor defines for specific flavors of Windows (for NT in this case). check-in: a0d92193 user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/wal.c.

  1776   1776       }
  1777   1777     }
  1778   1778   
  1779   1779    walcheckpoint_out:
  1780   1780     walIteratorFree(pIter);
  1781   1781     return rc;
  1782   1782   }
         1783  +
         1784  +/*
         1785  +** Attempt to limit the WAL size to the size limit defined by
         1786  +** PRAGMA journal_size_limit.
         1787  +*/
         1788  +static void walLimitSize(Wal *pWal){
         1789  +  if( pWal->mxWalSize>=0 ){
         1790  +    i64 sz;
         1791  +    int rx;
         1792  +    sqlite3BeginBenignMalloc();
         1793  +    rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
         1794  +    if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){
         1795  +      rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize);
         1796  +    }
         1797  +    sqlite3EndBenignMalloc();
         1798  +    if( rx ){
         1799  +      sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
         1800  +    }
         1801  +  }
         1802  +}
  1783   1803   
  1784   1804   /*
  1785   1805   ** Close a connection to a log file.
  1786   1806   */
  1787   1807   int sqlite3WalClose(
  1788   1808     Wal *pWal,                      /* Wal to close */
  1789   1809     int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
................................................................................
  1810   1830         }
  1811   1831         rc = sqlite3WalCheckpoint(
  1812   1832             pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
  1813   1833         );
  1814   1834         sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersistWal);
  1815   1835         if( rc==SQLITE_OK && bPersistWal!=1 ){
  1816   1836           isDelete = 1;
         1837  +      }else{
         1838  +        walLimitSize(pWal);
  1817   1839         }
  1818   1840       }
  1819   1841   
  1820   1842       walIndexClose(pWal, isDelete);
  1821   1843       sqlite3OsClose(pWal->pWalFd);
  1822   1844       if( isDelete ){
  1823   1845         sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0);
................................................................................
  2513   2535       pWal->hdr.aFrameCksum[0] = aWalData[1];
  2514   2536       pWal->hdr.aFrameCksum[1] = aWalData[2];
  2515   2537       walCleanupHash(pWal);
  2516   2538     }
  2517   2539   
  2518   2540     return rc;
  2519   2541   }
         2542  +
  2520   2543   
  2521   2544   /*
  2522   2545   ** This function is called just before writing a set of frames to the log
  2523   2546   ** file (see sqlite3WalFrames()). It checks to see if, instead of appending
  2524   2547   ** to the current log file, it is possible to overwrite the start of the
  2525   2548   ** existing log file with the new frames (i.e. "reset" the log). If so,
  2526   2549   ** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left
................................................................................
  2551   2574           ** at this point. But updating the actual wal-index header is also
  2552   2575           ** safe and means there is no special case for sqlite3WalUndo()
  2553   2576           ** to handle if this transaction is rolled back.
  2554   2577           */
  2555   2578           int i;                    /* Loop counter */
  2556   2579           u32 *aSalt = pWal->hdr.aSalt;       /* Big-endian salt values */
  2557   2580   
  2558         -        /* Limit the size of WAL file if the journal_size_limit PRAGMA is
  2559         -        ** set to a non-negative value.  Log errors encountered
  2560         -        ** during the truncation attempt. */
  2561         -        if( pWal->mxWalSize>=0 ){
  2562         -          i64 sz;
  2563         -          int rx;
  2564         -          sqlite3BeginBenignMalloc();
  2565         -          rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
  2566         -          if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){
  2567         -            rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize);
  2568         -          }
  2569         -          sqlite3EndBenignMalloc();
  2570         -          if( rx ){
  2571         -            sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
  2572         -          }
  2573         -        }
  2574         -
         2581  +        walLimitSize(pWal);
  2575   2582           pWal->nCkpt++;
  2576   2583           pWal->hdr.mxFrame = 0;
  2577   2584           sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
  2578   2585           aSalt[1] = salt1;
  2579   2586           walIndexWriteHdr(pWal);
  2580   2587           pInfo->nBackfill = 0;
  2581   2588           for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;

Changes to test/walpersist.test.

    63     63     file_control_persist_wal db 1
    64     64   } {0 1}
    65     65   do_test walpersist-1.11 {
    66     66     db close
    67     67     list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm]
    68     68   } {1 1 1}
    69     69   
    70         -  
    71         -
           70  +# Make sure the journal_size_limit works to limit the size of the
           71  +# persisted wal file.
           72  +forcedelete test.db test.db-shm test.db-wal
           73  +do_test walpersist-2.1 {
           74  +  sqlite3 db test.db
           75  +  db eval {
           76  +    PRAGMA journal_mode=WAL;
           77  +    PRAGMA wal_autocheckpoint=OFF;
           78  +    PRAGMA journal_size_limit=12000;
           79  +    CREATE TABLE t1(x);
           80  +    INSERT INTO t1 VALUES(randomblob(50000));
           81  +    UPDATE t1 SET x=randomblob(50000);
           82  +  }
           83  +  expr {[file size test.db-wal]>100000}
           84  +} {1}
           85  +do_test walpersist-2.2 {
           86  +  file_control_persist_wal db 1
           87  +  db close
           88  +  file size test.db-wal
           89  +} {12000}
    72     90   
    73     91   finish_test