Fix a but in the WAL checkpoint code causing SQLite to use an inconsistent cache in a subsequent transaction.
FossilOrigin-Name: d1cadeed4eea20d8892726cc8c69f4f3f57d0cd4
This commit is contained in:
parent
b4e3a6f72f
commit
31c03907fd
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\stests\sto\swalthread.test.
|
C Fix\sa\sbut\sin\sthe\sWAL\scheckpoint\scode\scausing\sSQLite\sto\suse\san\sinconsistent\scache\sin\sa\ssubsequent\stransaction.
|
||||||
D 2010-04-29T08:47:28
|
D 2010-04-29T14:51:33
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in d83a0ffef3dcbfb08b410a6c6dd6c009ec9167fb
|
F Makefile.in d83a0ffef3dcbfb08b410a6c6dd6c009ec9167fb
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@ -221,7 +221,7 @@ F src/vdbeblob.c 5327132a42a91e8b7acfb60b9d2c3b1c5c863e0e
|
|||||||
F src/vdbemem.c 2a82f455f6ca6f78b59fb312f96054c04ae0ead1
|
F src/vdbemem.c 2a82f455f6ca6f78b59fb312f96054c04ae0ead1
|
||||||
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
|
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
|
||||||
F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda
|
F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda
|
||||||
F src/wal.c d63318e8e73f9ed1a6f3c277f71022024f38a7c3
|
F src/wal.c b1c6868b975a67f6f4dd2cd612eeace4117eb98f
|
||||||
F src/wal.h c60781e78e394af07ece3b64a11192eb442241c1
|
F src/wal.h c60781e78e394af07ece3b64a11192eb442241c1
|
||||||
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
||||||
F src/where.c faadd9c2bf08868e5135192b44e0d753e363a885
|
F src/where.c faadd9c2bf08868e5135192b44e0d753e363a885
|
||||||
@ -758,13 +758,13 @@ F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61
|
|||||||
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||||
F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
|
F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
|
||||||
F test/wal.test bc99b1656b721fddd2dfeea0b0e77b147e40e6da
|
F test/wal.test d6fa4631310f95ac7d22f74b29c4b197f519d65b
|
||||||
F test/walbak.test f6fde9a5f59d0c697cb1f4af7876178c2f69a7ba
|
F test/walbak.test f6fde9a5f59d0c697cb1f4af7876178c2f69a7ba
|
||||||
F test/walcrash.test f022cee7eb7baa5fb898726120a6a4073dd831d1
|
F test/walcrash.test f022cee7eb7baa5fb898726120a6a4073dd831d1
|
||||||
F test/walhook.test 287a69d662939604f2e0452dace2cec8ef634d5e
|
F test/walhook.test 287a69d662939604f2e0452dace2cec8ef634d5e
|
||||||
F test/walmode.test 40119078da084e6a7403ba57485d5a86ee0e2646
|
F test/walmode.test 40119078da084e6a7403ba57485d5a86ee0e2646
|
||||||
F test/walslow.test 38076d5fad49e3678027be0f8110e6a32d531dc2
|
F test/walslow.test 38076d5fad49e3678027be0f8110e6a32d531dc2
|
||||||
F test/walthread.test 8fdce1721bf01e88a1f83a93ce7ae2e7668bcb26
|
F test/walthread.test c9c3b5d19eeb4968254d93f61a7ccd6e8b63f554
|
||||||
F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
|
F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
|
||||||
F test/where2.test 45eacc126aabb37959a387aa83e59ce1f1f03820
|
F test/where2.test 45eacc126aabb37959a387aa83e59ce1f1f03820
|
||||||
F test/where3.test aa44a9b29e8c9f3d7bb94a3bb3a95b31627d520d
|
F test/where3.test aa44a9b29e8c9f3d7bb94a3bb3a95b31627d520d
|
||||||
@ -808,7 +808,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P da229e44bd4a5d512261da05958d560808c9889f
|
P 9e891e7543ea4d7dee76deb2456af940f4cac49b
|
||||||
R f40b5481d2db02fd1a8b59b3cbe35412
|
R 1d9b135e5479cce531b0c9f4c717d59a
|
||||||
U dan
|
U dan
|
||||||
Z 9a86a68774ea80363d82258dc9f803a1
|
Z f79bb92cf1fa704536cc5c5230dfad45
|
||||||
|
@ -1 +1 @@
|
|||||||
9e891e7543ea4d7dee76deb2456af940f4cac49b
|
d1cadeed4eea20d8892726cc8c69f4f3f57d0cd4
|
12
src/wal.c
12
src/wal.c
@ -1880,6 +1880,7 @@ int sqlite3WalCheckpoint(
|
|||||||
void *pBusyHandlerArg /* Argument to pass to xBusyHandler */
|
void *pBusyHandlerArg /* Argument to pass to xBusyHandler */
|
||||||
){
|
){
|
||||||
int rc; /* Return code */
|
int rc; /* Return code */
|
||||||
|
int isChanged = 0; /* True if a new wal-index header is loaded */
|
||||||
|
|
||||||
assert( !pLog->isLocked );
|
assert( !pLog->isLocked );
|
||||||
|
|
||||||
@ -1899,10 +1900,19 @@ int sqlite3WalCheckpoint(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Copy data from the log to the database file. */
|
/* Copy data from the log to the database file. */
|
||||||
rc = logSummaryReadHdr(pLog, 0);
|
rc = logSummaryReadHdr(pLog, &isChanged);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = logCheckpoint(pLog, pFd, sync_flags, zBuf);
|
rc = logCheckpoint(pLog, pFd, sync_flags, zBuf);
|
||||||
}
|
}
|
||||||
|
if( isChanged ){
|
||||||
|
/* If a new wal-index header was loaded before the checkpoint was
|
||||||
|
** performed, then the pager-cache associated with log pLog is now
|
||||||
|
** out of date. So zero the cached wal-index header to ensure that
|
||||||
|
** next time the pager opens a snapshot on this database it knows that
|
||||||
|
** the cache needs to be reset.
|
||||||
|
*/
|
||||||
|
memset(&pLog->hdr, 0, sizeof(LogSummaryHdr));
|
||||||
|
}
|
||||||
|
|
||||||
/* Release the locks. */
|
/* Release the locks. */
|
||||||
logLockRegion(pLog, LOG_REGION_A|LOG_REGION_B|LOG_REGION_C, LOG_UNLOCK);
|
logLockRegion(pLog, LOG_REGION_A|LOG_REGION_B|LOG_REGION_C, LOG_UNLOCK);
|
||||||
|
@ -918,5 +918,50 @@ foreach code [list {
|
|||||||
db close
|
db close
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Check a fun corruption case has been fixed.
|
||||||
|
#
|
||||||
|
# The problem was that after performing a checkpoint using a connection
|
||||||
|
# that had an out-of-date pager-cache, the next time the connection was
|
||||||
|
# used it did not realize the cache was out-of-date and proceeded to
|
||||||
|
# operate with an inconsistent cache. Leading to corruption.
|
||||||
|
#
|
||||||
|
|
||||||
|
catch { db close }
|
||||||
|
catch { db2 close }
|
||||||
|
catch { db3 close }
|
||||||
|
file delete -force test.db test.db-wal
|
||||||
|
sqlite3 db test.db
|
||||||
|
sqlite3 db2 test.db
|
||||||
|
|
||||||
|
do_test wal-14 {
|
||||||
|
execsql {
|
||||||
|
PRAGMA journal_mode = WAL;
|
||||||
|
CREATE TABLE t1(a PRIMARY KEY, b);
|
||||||
|
INSERT INTO t1 VALUES(randomblob(10), randomblob(100));
|
||||||
|
INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1;
|
||||||
|
INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1;
|
||||||
|
INSERT INTO t1 SELECT randomblob(10), randomblob(100) FROM t1;
|
||||||
|
}
|
||||||
|
|
||||||
|
db2 eval {
|
||||||
|
INSERT INTO t1 SELECT randomblob(10), randomblob(100);
|
||||||
|
INSERT INTO t1 SELECT randomblob(10), randomblob(100);
|
||||||
|
INSERT INTO t1 SELECT randomblob(10), randomblob(100);
|
||||||
|
INSERT INTO t1 SELECT randomblob(10), randomblob(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
# After executing the "PRAGMA checkpoint", connection [db] was being
|
||||||
|
# left with an inconsistent cache. Running the CREATE INDEX statement
|
||||||
|
# in this state led to database corruption.
|
||||||
|
catchsql {
|
||||||
|
PRAGMA checkpoint;
|
||||||
|
CREATE INDEX i1 on t1(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
db2 eval { PRAGMA integrity_check }
|
||||||
|
} {ok}
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
|
||||||
|
@ -24,9 +24,10 @@ set sqlite_walsummary_mmap_incr 64
|
|||||||
# How long, in seconds, to run each test for. If a test is set to run for
|
# How long, in seconds, to run each test for. If a test is set to run for
|
||||||
# 0 seconds, it is omitted entirely.
|
# 0 seconds, it is omitted entirely.
|
||||||
#
|
#
|
||||||
set seconds(walthread-1) 0
|
set seconds(walthread-1) 20
|
||||||
set seconds(walthread-2) 0
|
set seconds(walthread-2) 20
|
||||||
set seconds(walthread-3) 20
|
set seconds(walthread-3) 20
|
||||||
|
set seconds(walthread-4) 20
|
||||||
|
|
||||||
# The parameter is the name of a variable in the callers context. The
|
# The parameter is the name of a variable in the callers context. The
|
||||||
# variable may or may not exist when this command is invoked.
|
# variable may or may not exist when this command is invoked.
|
||||||
@ -373,7 +374,7 @@ do_thread_test2 walthread-2 -seconds $seconds(walthread-2) -init {
|
|||||||
set {} "[expr $nRun-$nDel] w, $nDel r"
|
set {} "[expr $nRun-$nDel] w, $nDel r"
|
||||||
}
|
}
|
||||||
|
|
||||||
do_thread_test2 walthread-3 -seconds $seconds(walthread-3) -init {
|
do_thread_test walthread-3 -seconds $seconds(walthread-3) -init {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA journal_mode = WAL;
|
PRAGMA journal_mode = WAL;
|
||||||
CREATE TABLE t1(cnt PRIMARY KEY, sum1, sum2);
|
CREATE TABLE t1(cnt PRIMARY KEY, sum1, sum2);
|
||||||
@ -425,5 +426,33 @@ do_thread_test2 walthread-3 -seconds $seconds(walthread-3) -init {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_thread_test2 walthread-4 -seconds $seconds(walthread-4) -init {
|
||||||
|
execsql {
|
||||||
|
PRAGMA journal_mode = WAL;
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE);
|
||||||
|
}
|
||||||
|
} -thread r 1 {
|
||||||
|
# This connection only ever reads the database. Therefore the
|
||||||
|
# busy-handler is not required. Disable it to check that this is true.
|
||||||
|
db busy {}
|
||||||
|
while {[tt_continue]} integrity_check
|
||||||
|
set {} ok
|
||||||
|
} -thread w 1 {
|
||||||
|
|
||||||
|
proc wal_hook {zDb nEntry} {
|
||||||
|
if {$nEntry>15} { return 1 }
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
db wal_hook wal_hook
|
||||||
|
set row 1
|
||||||
|
while {[tt_continue]} {
|
||||||
|
db eval { REPLACE INTO t1 VALUES($row, randomblob(300)) }
|
||||||
|
incr row
|
||||||
|
if {$row == 10} { set row 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
set {} ok
|
||||||
|
}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user