mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Add mutexes to fix a race condition in wal.c. This isn't a very good fix.
FossilOrigin-Name: 3d159939cc2beb18c4ca0c8e9a99a75d4107e6e4
This commit is contained in:
32
manifest
32
manifest
@ -1,8 +1,5 @@
|
|||||||
-----BEGIN PGP SIGNED MESSAGE-----
|
C Add\smutexes\sto\sfix\sa\srace\scondition\sin\swal.c.\sThis\sisn't\sa\svery\sgood\sfix.
|
||||||
Hash: SHA1
|
D 2010-04-26T10:40:52
|
||||||
|
|
||||||
C Change\sthe\snames\sof\sthe\slog.c\sand\slog.h\ssource\sfiles\sto\swal.c\sand\swal.h.
|
|
||||||
D 2010-04-26T00:19:45
|
|
||||||
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
|
||||||
@ -176,7 +173,7 @@ F src/sqliteLimit.h 3afab2291762b5d09ae20c18feb8e9fa935a60a6
|
|||||||
F src/status.c 4df6fe7dce2d256130b905847c6c60055882bdbe
|
F src/status.c 4df6fe7dce2d256130b905847c6c60055882bdbe
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
F src/tclsqlite.c e27e0457109d72c7404df08af1726ff6ddc3d92c
|
F src/tclsqlite.c e27e0457109d72c7404df08af1726ff6ddc3d92c
|
||||||
F src/test1.c 8b4c246c41e75c3ff033edb2e8c2cf15820861ae
|
F src/test1.c 64b5b8135080b94370e8100e5066bb394f5c3122
|
||||||
F src/test2.c b6b43413d495addd039a88b87d65c839f86b18cb
|
F src/test2.c b6b43413d495addd039a88b87d65c839f86b18cb
|
||||||
F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94
|
F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94
|
||||||
F src/test4.c ad03bb987ddedce928f4258c1e7fa4109a73497d
|
F src/test4.c ad03bb987ddedce928f4258c1e7fa4109a73497d
|
||||||
@ -224,8 +221,8 @@ 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 df5283ae70cce52852fd788479bee22994fccbe5 w src/log.c
|
F src/wal.c f93ce8968d6e86378aa2d465f592027e02929a7a
|
||||||
F src/wal.h 1a34bb71642b46af5e6d51c2f69ae0f55268df81 w src/log.h
|
F src/wal.h 1a34bb71642b46af5e6d51c2f69ae0f55268df81
|
||||||
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
||||||
F src/where.c faadd9c2bf08868e5135192b44e0d753e363a885
|
F src/where.c faadd9c2bf08868e5135192b44e0d753e363a885
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
@ -761,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 8dcfd1ce874aead6199fa715ba8e35cfbb3ef766
|
F test/wal.test 7d44c2ee327e86a7c26052795789dd2d472bd1d4
|
||||||
F test/walbak.test f6fde9a5f59d0c697cb1f4af7876178c2f69a7ba
|
F test/walbak.test f6fde9a5f59d0c697cb1f4af7876178c2f69a7ba
|
||||||
F test/walcrash.test f022cee7eb7baa5fb898726120a6a4073dd831d1
|
F test/walcrash.test f022cee7eb7baa5fb898726120a6a4073dd831d1
|
||||||
F test/walhook.test 76a559e262f0715c470bade4a8d8333035f8ee47
|
F test/walhook.test 76a559e262f0715c470bade4a8d8333035f8ee47
|
||||||
F test/walmode.test c2f4e30ad64910b2d8faf6cf4e940b3f201b41df
|
F test/walmode.test c2f4e30ad64910b2d8faf6cf4e940b3f201b41df
|
||||||
F test/walslow.test 38076d5fad49e3678027be0f8110e6a32d531dc2
|
F test/walslow.test 38076d5fad49e3678027be0f8110e6a32d531dc2
|
||||||
F test/walthread.test 27e44ee6fd02f1f494a24f999c97086af3ab739d
|
F test/walthread.test a7962d8b899366cc71f8381d9aeab8ae9e1b544d
|
||||||
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
|
||||||
@ -811,14 +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 f5e615c28c7035a7e6d896790b51cf9bc7371d5f
|
P 56fe5d7624f840417152bcc63efbe21a5f557920
|
||||||
R 993bceae438ad1d8ab0904d8daf11104
|
R 262915592f11e9609982ee307c6e8694
|
||||||
U drh
|
U dan
|
||||||
Z e29cadabf74dbcaa3b3703c56732da89
|
Z 883881034efc398d53801b8849d7e631
|
||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
|
||||||
|
|
||||||
iD8DBQFL1NwloxKgR168RlERAks8AJ9QVBJiBku5alys49Firj8NBRPvlwCfSHT7
|
|
||||||
JCRELzIJ9CW5GkQjtcejMJU=
|
|
||||||
=4Ljy
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
|
@ -1 +1 @@
|
|||||||
56fe5d7624f840417152bcc63efbe21a5f557920
|
3d159939cc2beb18c4ca0c8e9a99a75d4107e6e4
|
@ -5113,6 +5113,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
|||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
extern char sqlite3_query_plan[];
|
extern char sqlite3_query_plan[];
|
||||||
static char *query_plan = sqlite3_query_plan;
|
static char *query_plan = sqlite3_query_plan;
|
||||||
|
extern int sqlite3_walsummary_mmap_incr; /* In wal.c */
|
||||||
#ifdef SQLITE_ENABLE_FTS3
|
#ifdef SQLITE_ENABLE_FTS3
|
||||||
extern int sqlite3_fts3_enable_parentheses;
|
extern int sqlite3_fts3_enable_parentheses;
|
||||||
#endif
|
#endif
|
||||||
@ -5172,6 +5173,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
|||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
Tcl_LinkVar(interp, "sqlite_query_plan",
|
Tcl_LinkVar(interp, "sqlite_query_plan",
|
||||||
(char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
|
(char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
|
||||||
|
Tcl_LinkVar(interp, "sqlite_walsummary_mmap_incr",
|
||||||
|
(char*)&sqlite3_walsummary_mmap_incr, TCL_LINK_INT);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
Tcl_LinkVar(interp, "sqlite_addop_trace",
|
Tcl_LinkVar(interp, "sqlite_addop_trace",
|
||||||
|
30
src/wal.c
30
src/wal.c
@ -119,7 +119,12 @@ struct LogSummaryHdr {
|
|||||||
** A 64 KB log-summary mapping corresponds to a log file containing over
|
** A 64 KB log-summary mapping corresponds to a log file containing over
|
||||||
** 13000 frames, so the mapping size does not need to be increased often.
|
** 13000 frames, so the mapping size does not need to be increased often.
|
||||||
*/
|
*/
|
||||||
#define LOGSUMMARY_MMAP_INCREMENT (64*1024)
|
#ifdef SQLITE_TEST
|
||||||
|
int sqlite3_walsummary_mmap_incr = 128;
|
||||||
|
# define LOGSUMMARY_MMAP_INCREMENT sqlite3_walsummary_mmap_incr
|
||||||
|
#else
|
||||||
|
# define LOGSUMMARY_MMAP_INCREMENT (64*1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** There is one instance of this structure for each log-summary object
|
** There is one instance of this structure for each log-summary object
|
||||||
@ -611,9 +616,10 @@ static int logSummaryEntry(u32 iFrame){
|
|||||||
static void logSummaryAppend(LogSummary *pSummary, u32 iFrame, u32 iPage){
|
static void logSummaryAppend(LogSummary *pSummary, u32 iFrame, u32 iPage){
|
||||||
u32 iSlot = logSummaryEntry(iFrame);
|
u32 iSlot = logSummaryEntry(iFrame);
|
||||||
|
|
||||||
if( (iSlot+128)>=pSummary->nData ){
|
while( (iSlot+128)>=pSummary->nData ){
|
||||||
int nByte = pSummary->nData*4 + LOGSUMMARY_MMAP_INCREMENT;
|
int nByte = pSummary->nData*4 + LOGSUMMARY_MMAP_INCREMENT;
|
||||||
|
|
||||||
|
/* Unmap and remap the log-summary file. */
|
||||||
sqlite3_mutex_enter(pSummary->mutex);
|
sqlite3_mutex_enter(pSummary->mutex);
|
||||||
munmap(pSummary->aData, pSummary->nData*4);
|
munmap(pSummary->aData, pSummary->nData*4);
|
||||||
pSummary->aData = 0;
|
pSummary->aData = 0;
|
||||||
@ -1377,8 +1383,11 @@ int logSummaryTryHdr(Log *pLog, int *pChanged){
|
|||||||
u32 aCksum[2] = {1, 1};
|
u32 aCksum[2] = {1, 1};
|
||||||
u32 aHdr[LOGSUMMARY_HDR_NFIELD+2];
|
u32 aHdr[LOGSUMMARY_HDR_NFIELD+2];
|
||||||
|
|
||||||
/* First try to read the header without a lock. Verify the checksum
|
/* Read the header. The caller may or may not have locked the log-summary
|
||||||
** before returning. This will almost always work.
|
** file, meaning it is possible that an inconsistent snapshot is read
|
||||||
|
** from the file. If this happens, return SQLITE_ERROR. The caller will
|
||||||
|
** retry. Or, if the caller has already locked the file and the header
|
||||||
|
** still looks inconsistent, it will run recovery.
|
||||||
*/
|
*/
|
||||||
memcpy(aHdr, pLog->pSummary->aData, sizeof(aHdr));
|
memcpy(aHdr, pLog->pSummary->aData, sizeof(aHdr));
|
||||||
logChecksumBytes((u8*)aHdr, sizeof(u32)*LOGSUMMARY_HDR_NFIELD, aCksum);
|
logChecksumBytes((u8*)aHdr, sizeof(u32)*LOGSUMMARY_HDR_NFIELD, aCksum);
|
||||||
@ -1410,10 +1419,16 @@ int logSummaryReadHdr(Log *pLog, int *pChanged){
|
|||||||
|
|
||||||
/* First try to read the header without a lock. Verify the checksum
|
/* First try to read the header without a lock. Verify the checksum
|
||||||
** before returning. This will almost always work.
|
** before returning. This will almost always work.
|
||||||
|
**
|
||||||
|
** TODO: Doing this causes a race-condition with the code that resizes
|
||||||
|
** the mapping. Unless Log.pSummary->mutex is held, it is possible that
|
||||||
|
** LogSummary.aData is invalid.
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
if( SQLITE_OK==logSummaryTryHdr(pLog, pChanged) ){
|
if( SQLITE_OK==logSummaryTryHdr(pLog, pChanged) ){
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If the first attempt to read the header failed, lock the log-summary
|
/* If the first attempt to read the header failed, lock the log-summary
|
||||||
** file and try again. If the header checksum verification fails this
|
** file and try again. If the header checksum verification fails this
|
||||||
@ -1502,11 +1517,14 @@ void sqlite3WalCloseSnapshot(Log *pLog){
|
|||||||
*/
|
*/
|
||||||
int sqlite3WalRead(Log *pLog, Pgno pgno, int *pInLog, u8 *pOut){
|
int sqlite3WalRead(Log *pLog, Pgno pgno, int *pInLog, u8 *pOut){
|
||||||
u32 iRead = 0;
|
u32 iRead = 0;
|
||||||
u32 *aData = pLog->pSummary->aData;
|
u32 *aData;
|
||||||
int iFrame = (pLog->hdr.iLastPg & 0xFFFFFF00);
|
int iFrame = (pLog->hdr.iLastPg & 0xFFFFFF00);
|
||||||
|
|
||||||
assert( pLog->isLocked );
|
assert( pLog->isLocked );
|
||||||
|
|
||||||
|
sqlite3_mutex_enter(pLog->pSummary->mutex);
|
||||||
|
aData = pLog->pSummary->aData;
|
||||||
|
|
||||||
/* Do a linear search of the unindexed block of page-numbers (if any)
|
/* Do a linear search of the unindexed block of page-numbers (if any)
|
||||||
** at the end of the log-summary. An alternative to this would be to
|
** at the end of the log-summary. An alternative to this would be to
|
||||||
** build an index in private memory each time a read transaction is
|
** build an index in private memory each time a read transaction is
|
||||||
@ -1549,6 +1567,8 @@ int sqlite3WalRead(Log *pLog, Pgno pgno, int *pInLog, u8 *pOut){
|
|||||||
}
|
}
|
||||||
assert( iRead==0 || aData[logSummaryEntry(iRead)]==pgno );
|
assert( iRead==0 || aData[logSummaryEntry(iRead)]==pgno );
|
||||||
|
|
||||||
|
sqlite3_mutex_leave(pLog->pSummary->mutex);
|
||||||
|
|
||||||
/* If iRead is non-zero, then it is the log frame number that contains the
|
/* If iRead is non-zero, then it is the log frame number that contains the
|
||||||
** required page. Read and return data from the log file.
|
** required page. Read and return data from the log file.
|
||||||
*/
|
*/
|
||||||
|
@ -787,8 +787,9 @@ do_test wal-13.5 {
|
|||||||
execsql { SELECT count(*) FROM t2 }
|
execsql { SELECT count(*) FROM t2 }
|
||||||
} [expr int(pow(2, 15))]
|
} [expr int(pow(2, 15))]
|
||||||
do_test wal-13.6 {
|
do_test wal-13.6 {
|
||||||
file size test.db-wal-summary
|
set sz [file size test.db-wal-summary]
|
||||||
} [expr 192*1024]
|
expr {$sz<=(3*64*1024) && $sz>(2*64*1024)}
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing the operation of the library in
|
# focus of this file is testing the operation of the library in
|
||||||
# "PRAGMA journal_mode=WAL" mode.
|
# "PRAGMA journal_mode=WAL" mode with multiple threads.
|
||||||
#
|
#
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@ -18,6 +18,11 @@ set testdir [file dirname $argv0]
|
|||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
if {[run_thread_tests]==0} { finish_test ; return }
|
if {[run_thread_tests]==0} { finish_test ; return }
|
||||||
|
|
||||||
|
set sqlite_walsummary_mmap_incr 64
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------------
|
||||||
|
# Initialize the database used for the multi-thread test.
|
||||||
|
#
|
||||||
do_test walthread-1.1 {
|
do_test walthread-1.1 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA journal_mode = WAL;
|
PRAGMA journal_mode = WAL;
|
||||||
@ -69,7 +74,6 @@ do_test walthread-1.4 {
|
|||||||
# 1) Execute "CHECKPOINT main 32 -1 1"
|
# 1) Execute "CHECKPOINT main 32 -1 1"
|
||||||
# 2) Sleep for 500 ms.
|
# 2) Sleep for 500 ms.
|
||||||
#
|
#
|
||||||
|
|
||||||
set thread_program {
|
set thread_program {
|
||||||
proc rest {ms} {
|
proc rest {ms} {
|
||||||
set ::rest 0
|
set ::rest 0
|
||||||
|
Reference in New Issue
Block a user