From: dan Date: Wed, 15 Dec 2021 12:51:02 +0000 (+0000) Subject: Fix a problem causing one wal file to be deleted without being checkpointed on close... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=348093c7197ba505f8d65832aa318505a08bcdd8;p=thirdparty%2Fsqlite.git Fix a problem causing one wal file to be deleted without being checkpointed on close in cases where the last connection to close the db does so with an out of date wal-index header in memory. FossilOrigin-Name: b0a70a2356c44d65c54c6d9bdf05972071462e72c28d6c6e593147ffa3d27ef2 --- diff --git a/manifest b/manifest index 7588404f42..3a8447f4d3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sversion\s3.37.0\sinto\sthe\swal2\sbranch. -D 2021-11-27T15:00:54.793 +C Fix\sa\sproblem\scausing\sone\swal\sfile\sto\sbe\sdeleted\swithout\sbeing\scheckpointed\son\sclose\sin\scases\swhere\sthe\slast\sconnection\sto\sclose\sthe\sdb\sdoes\sso\swith\san\sout\sof\sdate\swal-index\sheader\sin\smemory. +D 2021-12-15T12:51:02.972 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -636,7 +636,7 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c F src/vtab.c 9d5c3f49d3a6959b6eef287bb8fa773563102a80a835c3314c57144412709e78 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c ebd6d4c0e47a752a4f38fa486bf7243d2af1a8323b5a98c4a1dacdc590d87716 +F src/wal.c c373a0c800337f512672bc0365bc95a915df43d2e45f1427f1a02bf5e98edcee F src/wal.h d01234e828943e002040c22a7e017642962f9fd9b2dc142fa599769ae4e459e9 F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c de0d4ff409c7b62a8803f9f267cc2c7fedddbc00de9ab7b5382c507383c18665 @@ -1726,12 +1726,13 @@ F test/wal2.test 31f6e2c404b9f2cdf9ca19b105a1742fdc19653c2c936da39e3658c61752404 F test/wal2big.test 0b4ec526f9ca4bbabc355042c38045ae2e253fb46eb327bb7693d0122bc6968b F test/wal2fault.test 2e8e60cacd5bcd451618aeffd05f676894d17202d3e2986e288d36e2c5993249 F test/wal2lock.test 0ef98d72dc6bcf7711dedd684760488400d9a9a6eec0dc5d3822060437793552 +F test/wal2openclose.test 2b26be723ea7f4263c8d5d70b37efd1c359561a0526e39466c45fe8e6478daee F test/wal2recover.test ba8f4bc9397c838734619f9e759bd98b00e355347b3cf80a2e677610d231d5d8 F test/wal2recover2.test 0c46afc759e4392a3c12fba17432b880c93a13bf4246d1be5101b00bae4c5f01 F test/wal2rewrite.test 6ca6f631ffcf871240beab5f02608913fd075c6d0d31310b026c8383c65c9f9c F test/wal2rollback.test 23adc4a099b23f6aaea8b04fdca1c35861d887dd80f8be7da2d5273eb777e428 F test/wal2savepoint.test 2c82bd6a6ee5066c156040d2e9c2415646fcf96116ae7ad127eaf0c0b4a85f22 -F test/wal2simple.test 4a9bfc34dc888e75acb4e7bdce0bf15e960cbee02f185c07a396b35c49d4431d +F test/wal2simple.test 320a08927f307d0ead26fa3fcef4e3f64279f49be9504f918cb33294f75aeec8 F test/wal2snapshot.test 7a5f4629a3c43a43c3440b8b2ea9f07de91a46b0b9eea5f08f62b5bf5b6468df F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c @@ -1945,7 +1946,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 135133b7a65c652e95b0642bc2358425af72e46b1b6b64d256547b5e5e8f7e41 bd41822c7424d393a30e92ff6cb254d25c26769889c1499a18a0b9339f5d6c8a -R 201b14339f58661bd2f967a1bd6734d2 -U drh -Z 71b7d59afa12a68b678449df3fa88a69 +P 3425af625bac6c89950a50c2a22c4b7f66b0080811fe16ec8879158420641d5c +R 3f40ea32fb804a93691154c1384222dd +U dan +Z 459a6eb607efc418f73088930cf8495d diff --git a/manifest.uuid b/manifest.uuid index 62aa877b1a..038301ccda 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3425af625bac6c89950a50c2a22c4b7f66b0080811fe16ec8879158420641d5c \ No newline at end of file +b0a70a2356c44d65c54c6d9bdf05972071462e72c28d6c6e593147ffa3d27ef2 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 23e1a98065..d9b71117bd 100644 --- a/src/wal.c +++ b/src/wal.c @@ -794,6 +794,7 @@ struct Wal { #ifdef SQLITE_ENABLE_SNAPSHOT WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ #endif + int bClosing; /* Set to true at start of sqlite3WalClose() */ int bWal2; /* bWal2 flag passed to WalOpen() */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT sqlite3 *db; @@ -2850,6 +2851,7 @@ int sqlite3WalClose( int rc = SQLITE_OK; if( pWal ){ int isDelete = 0; /* True to unlink wal and wal-index files */ + pWal->bClosing = 1; /* If an EXCLUSIVE lock can be obtained on the database file (using the ** ordinary, rollback-mode locking methods, this guarantees that the @@ -4770,13 +4772,17 @@ int sqlite3WalCheckpoint( } } - if( isChanged ){ + if( isChanged && pWal->bClosing==0 ){ /* If a new wal-index header was loaded before the checkpoint was ** performed, then the pager-cache associated with pWal 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. - */ + ** + ** Except, do not do this if the wal is being closed. In this case + ** the caller needs the wal-index header to check if the database is + ** in wal2 mode and the "other" wal file also needs to be checkpointed. + ** Besides, the pager cache will not be used again in this case. */ memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); } diff --git a/test/wal2openclose.test b/test/wal2openclose.test new file mode 100644 index 0000000000..66e5875813 --- /dev/null +++ b/test/wal2openclose.test @@ -0,0 +1,81 @@ +# 2017 September 19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing the operation of the library in +# "PRAGMA journal_mode=WAL2" mode. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +source $testdir/malloc_common.tcl +source $testdir/wal_common.tcl + +set testprefix wal2openclose +ifcapable !wal {finish_test ; return } + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c); + PRAGMA journal_mode = wal2; + PRAGMA wal_autocheckpoint = 0; + PRAGMA journal_size_limit = 75000; +} {wal2 0 75000} + +do_test 1.1 { + for {set ii 1} {$ii <= 200} {incr ii} { + execsql { + INSERT INTO t1 VALUES($ii, $ii, $ii); + } + } + expr ([file size test.db-wal2] - 75000) > 30000 +} {1} + +do_test 1.2 { + db close + list [file exists test.db-wal] [file exists test.db-wal2] +} {0 0} + +sqlite3 db test.db +do_execsql_test 1.3 { + SELECT sum(c) FROM t1 +} {20100} +db close + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a, b, c); + PRAGMA journal_mode = wal2; + INSERT INTO t1 VALUES(1, 2, 3); +} {wal2} +db_save_and_close + +db_restore_and_reopen +do_execsql_test 2.1 { + SELECT * FROM t1; +} {1 2 3} + +do_test 2.2 { + sqlite3 db2 test.db + db2 eval {INSERT INTO t1 VALUES(4, 5, 6)} + db2 close +} {} + +breakpoint +db close +sqlite3 db test.db +do_execsql_test 2.2 { + SELECT * FROM t1; +} {1 2 3 4 5 6} + + + +finish_test diff --git a/test/wal2simple.test b/test/wal2simple.test index e17fb66ec9..e63f4e1759 100644 --- a/test/wal2simple.test +++ b/test/wal2simple.test @@ -361,23 +361,23 @@ do_test 7.3.1 { SELECT count(*) FROM t1; } db2 list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {12608 3176 11264} +} {12608 3176 12288} do_test 7.3.2 { execsql { PRAGMA wal_checkpoint } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {12608 3176 21504} +} {12608 3176 22528} do_test 7.3.3 { execsql { INSERT INTO t1 VALUES(randomblob(10000)); INSERT INTO t1 VALUES(randomblob(500)); } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {12608 18896 21504} +} {12608 18896 22528} do_test 7.3.4 { execsql END db2 execsql { INSERT INTO t1 VALUES(randomblob(5000)); } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {12608 18896 21504} +} {12608 18896 22528} # Connection db2 is holding a PART2 lock. # @@ -406,22 +406,22 @@ do_test 7.4.1 { SELECT count(*) FROM t1; } db2 list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {12608 12608 44032} +} {12608 12608 50176} do_test 7.4.2 { execsql { INSERT INTO t1 VALUES(randomblob(5000)); } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {12608 12608 44032} +} {12608 12608 50176} do_test 7.4.3 { execsql { PRAGMA wal_checkpoint } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {12608 12608 44032} +} {12608 12608 50176} do_test 7.4.4 { execsql END db2 execsql { PRAGMA wal_checkpoint } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {12608 12608 54272} +} {12608 12608 60416} # Connection db2 is holding a PART1_FULL2 lock. # @@ -451,24 +451,24 @@ do_test 7.5.1 { SELECT count(*) FROM t1; } db2 list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {12608 12608 64512} +} {12608 12608 76800} do_test 7.5.2 { execsql { PRAGMA wal_checkpoint } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {12608 12608 75776} +} {12608 12608 87040} do_test 7.5.3.1 { execsql { INSERT INTO t1 VALUES(randomblob(5000)) } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {14704 12608 75776} +} {14704 12608 87040} do_test 7.5.3.2 { execsql { INSERT INTO t1 VALUES(randomblob(5000)) } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {22040 12608 75776} +} {22040 12608 87040} do_test 7.5.4 { execsql END db2 execsql { INSERT INTO t1 VALUES(randomblob(5000)) } list [file size test.db-wal] [file size test.db-wal2] [file size test.db] -} {22040 12608 75776} +} {22040 12608 87040} finish_test