]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Delay the decision to restart the log file until data is actually ready to be written...
authordan <dan@noemail.net>
Tue, 1 Jun 2010 15:44:57 +0000 (15:44 +0000)
committerdan <dan@noemail.net>
Tue, 1 Jun 2010 15:44:57 +0000 (15:44 +0000)
FossilOrigin-Name: b1abfaaf5309cc0d0dda4fb2c237862c8cf83261

manifest
manifest.uuid
src/wal.c

index 80de0fa85079c2ad7adc392a2c72f35bd8cb2976..9824a84442b246e012a425f0117d2c1fa4e62a10 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,5 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C The\sincremental\scheckpoint\sfeature\sis\snot\sperfect\syet,\sbut\sit\sis\sworking\nwell\senough\sto\smerge\sit\sinto\sthe\strunk.
-D 2010-06-01T15:24:30
+C Delay\sthe\sdecision\sto\srestart\sthe\slog\sfile\suntil\sdata\sis\sactually\sready\sto\sbe\swritten\sto\sthe\slog\sfile\s(instead\sof\sat\sthe\sstart\sof\sa\swrite\stransaction).
+D 2010-06-01T15:44:57
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -227,7 +224,7 @@ F src/vdbeblob.c 5327132a42a91e8b7acfb60b9d2c3b1c5c863e0e
 F src/vdbemem.c 2a82f455f6ca6f78b59fb312f96054c04ae0ead1
 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
 F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda
-F src/wal.c 131a5eaa59935cb3792ceed95a2b161a862c63f6
+F src/wal.c 2bd4ef3bfeb2481e9edd3d1858ff8db0bc3a650d
 F src/wal.h 1c1c9feb629b7f4afcbe0b47f80f47c5551d3a02
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
 F src/where.c 75fee9e255b62f773fcadd1d1f25b6f63ac7a356
@@ -818,14 +815,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 15abbc34168f7a5bd418254c2b16aac97029e6ea f4b9003a2d3db88eaabb4b291e6cea8e8ea6ff51
-R 858d8d9dc0b3efa473b8ec6d14fcb8f5
-U drh
-Z a6bb738fb568ab52924e606c6a5ae6d0
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFMBSYyoxKgR168RlERAlrVAJ9V4XzYgJAVXjVRCX0qxlsuSjehHgCdFXEg
-GoCrBmurJgvyGZW2vBLkX4A=
-=Giju
------END PGP SIGNATURE-----
+P 1d3e569e59ba89cc167f0a48951ecd82f10322ba
+R b704a2554ef7915333dfdde871fa034e
+U dan
+Z 3d2943f29bb11a4315abddbe2964e6d2
index 593dda50461eba40fa20524fee637c32893e087c..798ada6560bb99f6e2589b32e789022b82900348 100644 (file)
@@ -1 +1 @@
-1d3e569e59ba89cc167f0a48951ecd82f10322ba
\ No newline at end of file
+b1abfaaf5309cc0d0dda4fb2c237862c8cf83261
\ No newline at end of file
index dbac31ae3507e8dfe5e6334f4edac8303f44c448..dc143b4b17626e5cb35273baf01bae49edc22905 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -2002,7 +2002,6 @@ void sqlite3WalDbsize(Wal *pWal, Pgno *pPgno){
 */
 int sqlite3WalBeginWriteTransaction(Wal *pWal){
   int rc;
-  volatile WalCkptInfo *pInfo;
 
   /* Cannot start a write transaction without first holding a read
   ** transaction. */
@@ -2030,39 +2029,9 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
   if( memcmp(&pWal->hdr, (void*)pWal->pWiData, sizeof(WalIndexHdr))!=0 ){
     walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
     pWal->writeLock = 0;
-    walIndexUnmap(pWal);
-    return SQLITE_BUSY;
+    rc = SQLITE_BUSY;
   }
 
-  pInfo = walCkptInfo(pWal);
-  if( pWal->readLock==0 ){
-    assert( pInfo->nBackfill==pWal->hdr.mxFrame );
-    if( pInfo->nBackfill>0 ){
-      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
-      if( rc==SQLITE_OK ){
-        /* If all readers are using WAL_READ_LOCK(0) (in other words if no
-        ** readers are currently using the WAL) */
-        pWal->nCkpt++;
-        pWal->hdr.mxFrame = 0;
-        sqlite3Put4byte((u8*)pWal->hdr.aSalt,
-                         1 + sqlite3Get4byte((u8*)pWal->hdr.aSalt));
-        sqlite3_randomness(4, &pWal->hdr.aSalt[1]);
-        walIndexWriteHdr(pWal);
-        pInfo->nBackfill = 0;
-        memset((void*)&pInfo->aReadMark[1], 0,
-               sizeof(pInfo->aReadMark)-sizeof(u32));
-        rc = sqlite3OsTruncate(pWal->pDbFd, 
-                               ((i64)pWal->hdr.nPage*(i64)pWal->szPage));
-        walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
-      }
-    }
-    walUnlockShared(pWal, WAL_READ_LOCK(0));
-    pWal->readLock = -1;
-    do{
-      int notUsed;
-      rc = walTryBeginRead(pWal, &notUsed, 1);
-    }while( rc==WAL_RETRY );
-  }
   walIndexUnmap(pWal);
   return rc;
 }
@@ -2150,9 +2119,66 @@ int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
   return rc;
 }
 
+/*
+** This function is called just before writing a set of frames to the log
+** file (see sqlite3WalFrames()). It checks to see if, instead of appending
+** to the current log file, it is possible to overwrite the start of the
+** existing log file with the new frames (i.e. "reset" the log). If so,
+** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left
+** unchanged.
+**
+** SQLITE_OK is returned if no error is encountered (regardless of whether
+** or not pWal->hdr.mxFrame is modified). An SQLite error code is returned
+** if some error 
+*/
+static int walRestartLog(Wal *pWal){
+  int rc = SQLITE_OK;
+  if( pWal->readLock==0 
+   && SQLITE_OK==(rc = walIndexMap(pWal, walMappingSize(pWal->hdr.mxFrame)))
+  ){
+    volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
+    assert( pInfo->nBackfill==pWal->hdr.mxFrame );
+    if( pInfo->nBackfill>0 ){
+      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
+      if( rc==SQLITE_OK ){
+        /* If all readers are using WAL_READ_LOCK(0) (in other words if no
+        ** readers are currently using the WAL), then the transactions
+        ** frames will overwrite the start of the existing log. Update the
+        ** wal-index header to reflect this.
+        **
+        ** In theory it would be Ok to update the cache of the header only
+        ** at this point. But updating the actual wal-index header is also
+        ** safe and means there is no special case for sqlite3WalUndo()
+        ** to handle if this transaction is rolled back.
+        */
+        u32 *aSalt = pWal->hdr.aSalt;       /* Big-endian salt values */
+        pWal->nCkpt++;
+        pWal->hdr.mxFrame = 0;
+        sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
+        sqlite3_randomness(4, &aSalt[1]);
+        walIndexWriteHdr(pWal);
+        memset((void*)pInfo, 0, sizeof(*pInfo));
+        walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
+      }
+    }
+    walUnlockShared(pWal, WAL_READ_LOCK(0));
+    pWal->readLock = -1;
+    do{
+      int notUsed;
+      rc = walTryBeginRead(pWal, &notUsed, 1);
+    }while( rc==WAL_RETRY );
+
+    /* Unmap the wal-index before returning. Otherwise the VFS layer may
+    ** hold a mutex for the duration of the IO performed by WalFrames().
+    */
+    walIndexUnmap(pWal);
+  }
+  return rc;
+}
+
 /* 
 ** Write a set of frames to the log. The caller must hold the write-lock
-** on the log file (obtained using sqlite3WalWriteLock()).
+** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
 */
 int sqlite3WalFrames(
   Wal *pWal,                      /* Wal handle to write to */
@@ -2180,6 +2206,15 @@ int sqlite3WalFrames(
   }
 #endif
 
+  /* See if it is possible to write these frames into the start of the
+  ** log file, instead of appending to it at pWal->hdr.mxFrame.
+  */
+  if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){
+    assert( pWal->pWiData==0 );
+    return rc;
+  }
+  assert( pWal->pWiData==0 && pWal->readLock>0 );
+
   /* If this is the first frame written into the log, write the WAL
   ** header to the start of the WAL file. See comments at the top of
   ** this source file for a description of the WAL header format.
@@ -2203,7 +2238,7 @@ int sqlite3WalFrames(
   }
   assert( pWal->szPage==szPage );
 
-    /* Write the log file. */
+  /* Write the log file. */
   for(p=pList; p; p=p->pDirty){
     u32 nDbsize;                  /* Db-size field for frame header */
     i64 iOffset;                  /* Write offset in log file */