]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Proposed changes that ensure that the WAL header is written prior to the
authordrh <drh@noemail.net>
Fri, 16 Dec 2011 19:34:36 +0000 (19:34 +0000)
committerdrh <drh@noemail.net>
Fri, 16 Dec 2011 19:34:36 +0000 (19:34 +0000)
first commit mark.

FossilOrigin-Name: 91d0437c0702904d27f0ef7b1b52d0797efe1826

manifest
manifest.uuid
src/wal.c

index 66736fbb7389d91f0961f0eca5dc3d004fe7435e..8c212674dbbe23f163da80f4bb4499ba85906b32 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\sthe\sfix\sfor\s[a1fa75cbdd02]\sfrom\sthe\sexperimental\sbranch.\s\sAlso\nfix\sthe\spersistent-wal\smode\sfeature\sof\struncating\sthe\sWAL\son\sclose\sso\sthat\nit\salways\struncates\sthe\sWAL\sto\szero\sbytes.
-D 2011-12-16T15:38:52.854
+C Proposed\schanges\sthat\sensure\sthat\sthe\sWAL\sheader\sis\swritten\sprior\sto\sthe\nfirst\scommit\smark.
+D 2011-12-16T19:34:36.384
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -250,7 +250,7 @@ F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56
 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790
 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843
 F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a
-F src/wal.c 8575f2bdaed48e7ffbea8608b614bb7abd382a54
+F src/wal.c a1157f289ef700ce9148d8448916799cb364c20f
 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
 F src/where.c af623942514571895818b9b7ae11db95ae3b3d88
@@ -984,7 +984,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P b1005ef46cc2b46dd8e448ae1a9a9508bd5666ab 6492af76ea6585a1b377d69751af930c0ccfe688
-R 5e90bbe7156facb03e2de52b2217bc8c
+P 09ccc4a1be7ba81890f10aac6623dd90dab4f990
+R e39509fa33546fba87ec45fa63df451b
+T *branch * wal-header-sync
+T *sym-wal-header-sync *
+T -sym-trunk *
 U drh
-Z 290df3a9d2eb83a09d72442af4b2f315
+Z 6469301a128bde2c8fea4c5b47d61847
index 689e39e8ad533d50777bae02c2f1acd3cfa7faaf..cf227b205ff12c77d7f557d4ba1dffb111e05137 100644 (file)
@@ -1 +1 @@
-09ccc4a1be7ba81890f10aac6623dd90dab4f990
\ No newline at end of file
+91d0437c0702904d27f0ef7b1b52d0797efe1826
\ No newline at end of file
index 0fae6cbc7440af97adb8dcac01f792c8532ac2f0..915e014aaa374aec7f36fafc09aec378c01dc658 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -414,6 +414,7 @@ struct Wal {
   u32 iCallback;             /* Value to pass to log callback (or 0) */
   i64 mxWalSize;             /* Truncate WAL to this size upon reset */
   int nWiData;               /* Size of array apWiData */
+  int szFirstBlock;          /* Size of first block written to WAL file */
   volatile u32 **apWiData;   /* Pointer to wal-index content in memory */
   u32 szPage;                /* Database page size */
   i16 readLock;              /* Which read lock is being held.  -1 for none */
@@ -2617,6 +2618,40 @@ static int walRestartLog(Wal *pWal){
   return rc;
 }
 
+/*
+** Write iAmt bytes of content into the WAL file beginning at iOffset.
+**
+** When crossing the boundary between the first and second sectors of the
+** file, first write all of the first sector content, then fsync(), then
+** continue writing content for the second sector.  This ensures that
+** the WAL header is overwritten before the first commit mark.
+*/
+static int walWriteToLog(
+  Wal *pWal,                 /* WAL to write to */
+  void *pContent,            /* Content to be written */
+  int iAmt,                  /* Number of bytes to write */
+  sqlite3_int64 iOffset      /* Start writing at this offset */
+){
+  int rc;
+  if( iOffset>=pWal->szFirstBlock || iOffset+iAmt<pWal->szFirstBlock ){
+    /* The common and fast case.  Just write the data. */
+    rc = sqlite3OsWrite(pWal->pWalFd, pContent, iAmt, iOffset);
+  }else{
+    /* If this write will cross the first sector boundary, it has to
+    ** be split it two with a sync in between. */
+    int iFirstAmt = pWal->szFirstBlock - iOffset;
+    assert( iFirstAmt>0 && iFirstAmt<iAmt );
+    rc = sqlite3OsWrite(pWal->pWalFd, pContent, iFirstAmt, iOffset);
+    if( rc ) return rc;
+    rc = sqlite3OsSync(pWal->pWalFd, SQLITE_SYNC_NORMAL);
+    if( rc ) return rc;
+    pContent = (void*)(iFirstAmt + (char*)pContent);
+    rc = sqlite3OsWrite(pWal->pWalFd, pContent,
+                        iAmt-iFirstAmt, iOffset+iFirstAmt);
+  }
+  return rc;
+}
+
 /* 
 ** Write a set of frames to the log. The caller must hold the write-lock
 ** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
@@ -2686,6 +2721,10 @@ int sqlite3WalFrames(
   }
   assert( (int)pWal->szPage==szPage );
 
+  /* The size of the block containing the WAL header */
+  pWal->szFirstBlock = sqlite3OsSectorSize(pWal->pWalFd);
+  if( szPage>pWal->szFirstBlock ) pWal->szFirstBlock = szPage;
+
   /* Write the log file. */
   for(p=pList; p; p=p->pDirty){
     u32 nDbsize;                  /* Db-size field for frame header */
@@ -2703,13 +2742,13 @@ int sqlite3WalFrames(
     pData = p->pData;
 #endif
     walEncodeFrame(pWal, p->pgno, nDbsize, pData, aFrame);
-    rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset);
+    rc = walWriteToLog(pWal, aFrame, sizeof(aFrame), iOffset);
     if( rc!=SQLITE_OK ){
       return rc;
     }
 
     /* Write the page data */
-    rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset+sizeof(aFrame));
+    rc = walWriteToLog(pWal, pData, szPage, iOffset+sizeof(aFrame));
     if( rc!=SQLITE_OK ){
       return rc;
     }
@@ -2734,12 +2773,12 @@ int sqlite3WalFrames(
 #endif
       walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame);
       /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
-      rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset);
+      rc = walWriteToLog(pWal, aFrame, sizeof(aFrame), iOffset);
       if( rc!=SQLITE_OK ){
         return rc;
       }
       iOffset += WAL_FRAME_HDRSIZE;
-      rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset); 
+      rc = walWriteToLog(pWal, pData, szPage, iOffset);
       if( rc!=SQLITE_OK ){
         return rc;
       }