-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
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
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
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 */
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()).
}
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 */
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;
}
#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;
}