-C If\sa\ssingle\spage\sis\swritten\sto\sthe\swal\sfile\smore\sthan\sonce,\shave\seach\ssubsequent\scopy\soverwrite\sthe\soriginal\sframe.
-D 2016-01-09T16:39:29.213
+C If\sit\sis\sknown\sthat\schecksums\swill\sbe\srecalculated\son\stransaction\scommit,\sskip\scalculating\schecksums\swhen\sappending\sframes\sto\sthe\swal\sfile.\sWhen\srecalculating\schecksums,\srecalculate\sthem\sstarting\swith\sthe\sfirst\soverwritten\sframe\s-\snot\sthe\sfirst\sframe\sin\sthe\stransaction.
+D 2016-01-09T18:57:35.280
F Makefile.in 7c8cc4c2f0179efc6fa9492141d1fb65f4807054
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc e45d8b9b56dfa3f2cd860b2c28bd9d304513b042
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
-F src/wal.c 88661c24c86d88e40560c0be5df39d902502a29a
+F src/wal.c 38ca0c41b510b636dfada0801fad8a99a982dfa6
F src/wal.h 907943dfdef10b583e81906679a347e0ec6f1b1b
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
F src/where.c c6d3d2f6af57d574a7365ee2b225a5024f2a6bec
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 52c166039831cc8423e2252019ef64a21b9d7c2a
-R 7ec438cc7bd0e0a87d33dca3e9bb783a
-T *branch * wal-overwrite-frames
-T *sym-wal-overwrite-frames *
-T -sym-trunk *
+P 5d113aef2c7d746e8eda88d4e36c04a39b0a11be
+R 68fe235d45cc69355e6b4ad2de6e1633
U dan
-Z eba50524221f3f22640b286e867693f1
+Z 339ef03cecb2ba4cae1a0043b973d562
u8 padToSectorBoundary; /* Pad transactions out to the next sector */
WalIndexHdr hdr; /* Wal-index header for current transaction */
u32 minFrame; /* Ignore wal frames before this one */
+ u32 iReCksum; /* On commit, recalculate checksums from here */
const char *zWalName; /* Name of WAL file */
u32 nCkpt; /* Checkpoint sequence counter in the wal-header */
#ifdef SQLITE_DEBUG
#define WAL_EXCLUSIVE_MODE 1
#define WAL_HEAPMEMORY_MODE 2
-/*
-** Values for Wal.writeLock.
-*/
-#define WAL_WRITELOCK_UNLOCKED 0
-#define WAL_WRITELOCK_LOCKED 1
-#define WAL_WRITELOCK_RECKSUM 2
-
/*
** Possible values for WAL.readOnly
*/
assert( WAL_FRAME_HDRSIZE==24 );
sqlite3Put4byte(&aFrame[0], iPage);
sqlite3Put4byte(&aFrame[4], nTruncate);
- memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
+ if( pWal->iReCksum==0 ){
+ memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
- nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
- walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
- walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
+ nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
+ walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
+ walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
- sqlite3Put4byte(&aFrame[16], aCksum[0]);
- sqlite3Put4byte(&aFrame[20], aCksum[1]);
+ sqlite3Put4byte(&aFrame[16], aCksum[0]);
+ sqlite3Put4byte(&aFrame[20], aCksum[1]);
+ }
}
/*
/* Cannot start a write transaction without first holding a read
** transaction. */
assert( pWal->readLock>=0 );
+ assert( pWal->writeLock==0 && pWal->iReCksum==0 );
if( pWal->readOnly ){
return SQLITE_READONLY;
if( pWal->writeLock ){
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
pWal->writeLock = 0;
+ pWal->iReCksum = 0;
pWal->truncateOnCommit = 0;
}
return SQLITE_OK;
/*
** This function is called as part of committing a transaction within which
** one or more frames have been overwritten. It updates the checksums for
-** all frames written to the wal file by the current transaction.
-**
-** Argument pLive is a pointer to the first wal-index header in shared
-** memory (the copy readers will see if they open a read-transaction now,
-** before the current commit is finished). This is safe to use because the
-** caller holds the WRITER lock. The first frame to update the checksum
-** for is (pLive->mxFrame+1). The last is argument iLast.
+** all frames written to the wal file by the current transaction starting
+** with the earliest to have been overwritten.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
-static int walRewriteChecksums(Wal *pWal, WalIndexHdr *pLive, u32 iLast){
+static int walRewriteChecksums(Wal *pWal, u32 iLast){
const int szPage = pWal->szPage;/* Database page size */
int rc = SQLITE_OK; /* Return code */
u8 *aBuf; /* Buffer to load data from wal file into */
u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-headers in */
u32 iRead; /* Next frame to read from wal file */
+ i64 iCksumOff;
aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
if( aBuf==0 ) return SQLITE_NOMEM;
- /* Find the checksum values to use as input for the checksum of the
- ** first frame written by this transaction. If that frame is frame 1
- ** (implying that the current transaction restarted the wal file),
- ** these values must be read from the wal-file header. If the first
- ** frame to update the checksum of is not frame 1, then the initial
- ** checksum values can be copied from pLive. */
- if( pLive->mxFrame==0 ){
- rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, 24);
- pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf);
- pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]);
+ /* Find the checksum values to use as input for the recalculating the
+ ** first checksum. If the first frame is frame 1 (implying that the current
+ ** transaction restarted the wal file), these values must be read from the
+ ** wal-file header. Otherwise, read them from the frame header of the
+ ** previous frame. */
+ assert( pWal->iReCksum>0 );
+ if( pWal->iReCksum==1 ){
+ iCksumOff = 24;
}else{
- memcpy(pWal->hdr.aFrameCksum, pLive->aFrameCksum, sizeof(u32)*2);
+ iCksumOff = walFrameOffset(pWal->iReCksum-1, szPage) + 16;
}
+ rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff);
+ pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf);
+ pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]);
- for(iRead=pLive->mxFrame+1; rc==SQLITE_OK && iRead<=iLast; iRead++){
+ iRead = pWal->iReCksum;
+ pWal->iReCksum = 0;
+ for(; rc==SQLITE_OK && iRead<=iLast; iRead++){
i64 iOff = walFrameOffset(iRead, szPage);
rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff);
if( rc==SQLITE_OK ){
if( rc ) return rc;
if( iWrite>=iFirst ){
i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE;
- pWal->writeLock = WAL_WRITELOCK_RECKSUM;
+ if( pWal->iReCksum==0 || iWrite<pWal->iReCksum ){
+ pWal->iReCksum = iWrite;
+ }
rc = sqlite3OsWrite(pWal->pWalFd, p->pData, szPage, iOff);
if( rc ) return rc;
p->flags &= ~PGHDR_WAL_APPEND;
}
/* Recalculate checksums within the wal file if required. */
- if( isCommit && pWal->writeLock==WAL_WRITELOCK_RECKSUM ){
- rc = walRewriteChecksums(pWal, pLive, iFrame);
+ if( isCommit && pWal->iReCksum ){
+ rc = walRewriteChecksums(pWal, iFrame);
if( rc ) return rc;
}