From: dan Date: Sat, 9 Jan 2016 18:57:35 +0000 (+0000) Subject: If it is known that checksums will be recalculated on transaction commit, skip calcul... X-Git-Tag: version-3.11.0~169^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c9a9022b216aab23fb756d4a6a47c14cfeb69da7;p=thirdparty%2Fsqlite.git If it is known that checksums will be recalculated on transaction commit, skip calculating checksums when appending frames to the wal file. When recalculating checksums, recalculate them starting with the first overwritten frame - not the first frame in the transaction. FossilOrigin-Name: 16b34f2537bbc7846d8e6dc2b35daae5af241c1b --- diff --git a/manifest b/manifest index 929a82b2bd..0d9cd20891 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -409,7 +409,7 @@ F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d 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 @@ -1407,10 +1407,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f 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 diff --git a/manifest.uuid b/manifest.uuid index 2b25ead966..44ce854f87 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d113aef2c7d746e8eda88d4e36c04a39b0a11be \ No newline at end of file +16b34f2537bbc7846d8e6dc2b35daae5af241c1b \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index c900879d12..d3e2908ba1 100644 --- a/src/wal.c +++ b/src/wal.c @@ -445,6 +445,7 @@ struct Wal { 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 @@ -462,13 +463,6 @@ struct Wal { #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 */ @@ -705,14 +699,16 @@ static void walEncodeFrame( 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]); + } } /* @@ -2639,6 +2635,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){ /* 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; @@ -2674,6 +2671,7 @@ int sqlite3WalEndWriteTransaction(Wal *pWal){ if( pWal->writeLock ){ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); pWal->writeLock = 0; + pWal->iReCksum = 0; pWal->truncateOnCommit = 0; } return SQLITE_OK; @@ -2895,41 +2893,40 @@ static int walWriteOneFrame( /* ** 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 ){ @@ -3065,7 +3062,9 @@ int sqlite3WalFrames( if( rc ) return rc; if( iWrite>=iFirst ){ i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE; - pWal->writeLock = WAL_WRITELOCK_RECKSUM; + if( pWal->iReCksum==0 || iWriteiReCksum ){ + pWal->iReCksum = iWrite; + } rc = sqlite3OsWrite(pWal->pWalFd, p->pData, szPage, iOff); if( rc ) return rc; p->flags &= ~PGHDR_WAL_APPEND; @@ -3084,8 +3083,8 @@ int sqlite3WalFrames( } /* 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; }