mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
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
This commit is contained in:
15
manifest
15
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.
|
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-09T16:39:29.213
|
D 2016-01-09T18:57:35.280
|
||||||
F Makefile.in 7c8cc4c2f0179efc6fa9492141d1fb65f4807054
|
F Makefile.in 7c8cc4c2f0179efc6fa9492141d1fb65f4807054
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc e45d8b9b56dfa3f2cd860b2c28bd9d304513b042
|
F Makefile.msc e45d8b9b56dfa3f2cd860b2c28bd9d304513b042
|
||||||
@@ -409,7 +409,7 @@ F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d
|
|||||||
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
||||||
F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
|
F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
|
||||||
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||||
F src/wal.c 88661c24c86d88e40560c0be5df39d902502a29a
|
F src/wal.c 38ca0c41b510b636dfada0801fad8a99a982dfa6
|
||||||
F src/wal.h 907943dfdef10b583e81906679a347e0ec6f1b1b
|
F src/wal.h 907943dfdef10b583e81906679a347e0ec6f1b1b
|
||||||
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
||||||
F src/where.c c6d3d2f6af57d574a7365ee2b225a5024f2a6bec
|
F src/where.c c6d3d2f6af57d574a7365ee2b225a5024f2a6bec
|
||||||
@@ -1407,10 +1407,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P 52c166039831cc8423e2252019ef64a21b9d7c2a
|
P 5d113aef2c7d746e8eda88d4e36c04a39b0a11be
|
||||||
R 7ec438cc7bd0e0a87d33dca3e9bb783a
|
R 68fe235d45cc69355e6b4ad2de6e1633
|
||||||
T *branch * wal-overwrite-frames
|
|
||||||
T *sym-wal-overwrite-frames *
|
|
||||||
T -sym-trunk *
|
|
||||||
U dan
|
U dan
|
||||||
Z eba50524221f3f22640b286e867693f1
|
Z 339ef03cecb2ba4cae1a0043b973d562
|
||||||
|
@@ -1 +1 @@
|
|||||||
5d113aef2c7d746e8eda88d4e36c04a39b0a11be
|
16b34f2537bbc7846d8e6dc2b35daae5af241c1b
|
71
src/wal.c
71
src/wal.c
@@ -445,6 +445,7 @@ struct Wal {
|
|||||||
u8 padToSectorBoundary; /* Pad transactions out to the next sector */
|
u8 padToSectorBoundary; /* Pad transactions out to the next sector */
|
||||||
WalIndexHdr hdr; /* Wal-index header for current transaction */
|
WalIndexHdr hdr; /* Wal-index header for current transaction */
|
||||||
u32 minFrame; /* Ignore wal frames before this one */
|
u32 minFrame; /* Ignore wal frames before this one */
|
||||||
|
u32 iReCksum; /* On commit, recalculate checksums from here */
|
||||||
const char *zWalName; /* Name of WAL file */
|
const char *zWalName; /* Name of WAL file */
|
||||||
u32 nCkpt; /* Checkpoint sequence counter in the wal-header */
|
u32 nCkpt; /* Checkpoint sequence counter in the wal-header */
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
@@ -462,13 +463,6 @@ struct Wal {
|
|||||||
#define WAL_EXCLUSIVE_MODE 1
|
#define WAL_EXCLUSIVE_MODE 1
|
||||||
#define WAL_HEAPMEMORY_MODE 2
|
#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
|
** Possible values for WAL.readOnly
|
||||||
*/
|
*/
|
||||||
@@ -705,14 +699,16 @@ static void walEncodeFrame(
|
|||||||
assert( WAL_FRAME_HDRSIZE==24 );
|
assert( WAL_FRAME_HDRSIZE==24 );
|
||||||
sqlite3Put4byte(&aFrame[0], iPage);
|
sqlite3Put4byte(&aFrame[0], iPage);
|
||||||
sqlite3Put4byte(&aFrame[4], nTruncate);
|
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);
|
nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
|
||||||
walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
|
walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
|
||||||
walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
|
walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
|
||||||
|
|
||||||
sqlite3Put4byte(&aFrame[16], aCksum[0]);
|
sqlite3Put4byte(&aFrame[16], aCksum[0]);
|
||||||
sqlite3Put4byte(&aFrame[20], aCksum[1]);
|
sqlite3Put4byte(&aFrame[20], aCksum[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2639,6 +2635,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
|
|||||||
/* Cannot start a write transaction without first holding a read
|
/* Cannot start a write transaction without first holding a read
|
||||||
** transaction. */
|
** transaction. */
|
||||||
assert( pWal->readLock>=0 );
|
assert( pWal->readLock>=0 );
|
||||||
|
assert( pWal->writeLock==0 && pWal->iReCksum==0 );
|
||||||
|
|
||||||
if( pWal->readOnly ){
|
if( pWal->readOnly ){
|
||||||
return SQLITE_READONLY;
|
return SQLITE_READONLY;
|
||||||
@@ -2674,6 +2671,7 @@ int sqlite3WalEndWriteTransaction(Wal *pWal){
|
|||||||
if( pWal->writeLock ){
|
if( pWal->writeLock ){
|
||||||
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
|
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
|
||||||
pWal->writeLock = 0;
|
pWal->writeLock = 0;
|
||||||
|
pWal->iReCksum = 0;
|
||||||
pWal->truncateOnCommit = 0;
|
pWal->truncateOnCommit = 0;
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@@ -2895,41 +2893,40 @@ static int walWriteOneFrame(
|
|||||||
/*
|
/*
|
||||||
** This function is called as part of committing a transaction within which
|
** This function is called as part of committing a transaction within which
|
||||||
** one or more frames have been overwritten. It updates the checksums for
|
** one or more frames have been overwritten. It updates the checksums for
|
||||||
** all frames written to the wal file by the current transaction.
|
** all frames written to the wal file by the current transaction starting
|
||||||
**
|
** with the earliest to have been overwritten.
|
||||||
** 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.
|
|
||||||
**
|
**
|
||||||
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
|
** 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 */
|
const int szPage = pWal->szPage;/* Database page size */
|
||||||
int rc = SQLITE_OK; /* Return code */
|
int rc = SQLITE_OK; /* Return code */
|
||||||
u8 *aBuf; /* Buffer to load data from wal file into */
|
u8 *aBuf; /* Buffer to load data from wal file into */
|
||||||
u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-headers in */
|
u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-headers in */
|
||||||
u32 iRead; /* Next frame to read from wal file */
|
u32 iRead; /* Next frame to read from wal file */
|
||||||
|
i64 iCksumOff;
|
||||||
|
|
||||||
aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
|
aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
|
||||||
if( aBuf==0 ) return SQLITE_NOMEM;
|
if( aBuf==0 ) return SQLITE_NOMEM;
|
||||||
|
|
||||||
/* Find the checksum values to use as input for the checksum of the
|
/* Find the checksum values to use as input for the recalculating the
|
||||||
** first frame written by this transaction. If that frame is frame 1
|
** first checksum. If the first frame is frame 1 (implying that the current
|
||||||
** (implying that the current transaction restarted the wal file),
|
** transaction restarted the wal file), these values must be read from the
|
||||||
** these values must be read from the wal-file header. If the first
|
** wal-file header. Otherwise, read them from the frame header of the
|
||||||
** frame to update the checksum of is not frame 1, then the initial
|
** previous frame. */
|
||||||
** checksum values can be copied from pLive. */
|
assert( pWal->iReCksum>0 );
|
||||||
if( pLive->mxFrame==0 ){
|
if( pWal->iReCksum==1 ){
|
||||||
rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, 24);
|
iCksumOff = 24;
|
||||||
pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf);
|
|
||||||
pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]);
|
|
||||||
}else{
|
}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);
|
i64 iOff = walFrameOffset(iRead, szPage);
|
||||||
rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff);
|
rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
@@ -3065,7 +3062,9 @@ int sqlite3WalFrames(
|
|||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
if( iWrite>=iFirst ){
|
if( iWrite>=iFirst ){
|
||||||
i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE;
|
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);
|
rc = sqlite3OsWrite(pWal->pWalFd, p->pData, szPage, iOff);
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
p->flags &= ~PGHDR_WAL_APPEND;
|
p->flags &= ~PGHDR_WAL_APPEND;
|
||||||
@@ -3084,8 +3083,8 @@ int sqlite3WalFrames(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Recalculate checksums within the wal file if required. */
|
/* Recalculate checksums within the wal file if required. */
|
||||||
if( isCommit && pWal->writeLock==WAL_WRITELOCK_RECKSUM ){
|
if( isCommit && pWal->iReCksum ){
|
||||||
rc = walRewriteChecksums(pWal, pLive, iFrame);
|
rc = walRewriteChecksums(pWal, iFrame);
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user