]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the SQLITE_FCNTL_RESET_CACHE verb. Use it to ensure that the page cache is purged...
authordrh <>
Mon, 26 Dec 2022 16:12:40 +0000 (16:12 +0000)
committerdrh <>
Mon, 26 Dec 2022 16:12:40 +0000 (16:12 +0000)
FossilOrigin-Name: 71dd920f92457a30aff21665de5d6b8fcdcb06119022bb8fd950960c2e041216

ext/recover/recover1.test
ext/recover/sqlite3recover.c
manifest
manifest.uuid
src/btree.c
src/btree.h
src/main.c
src/sqlite.h.in

index 75f5dba1ff33666edb2948c46f7c5427453f67bc..3e8a6914920ca6799ce83f5c514a04b07c1a418f 100644 (file)
@@ -273,5 +273,46 @@ do_execsql_test 15.1 {
 } {}
 do_recover_test 15 
 
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 16.1 {
+  PRAGMA journal_mode = wal;
+  CREATE TABLE t1(x);
+  INSERT INTO t1 VALUES(1), (2), (3);
+} {wal}
+do_test 16.2 {
+  set R [sqlite3_recover_init db main test.db2]
+  $R run
+  $R finish
+} {}
+do_execsql_test 16.3 {
+  SELECT * FROM t1;
+} {1 2 3}
+
+do_execsql_test 16.4 {
+  BEGIN;
+    SELECT * FROM t1;
+} {1 2 3}
+do_test 16.5 {
+  set R [sqlite3_recover_init db main test.db2]
+  $R run
+  list [catch { $R finish } msg] $msg
+} {1 {cannot start a transaction within a transaction}}
+do_execsql_test 16.6 {
+  SELECT * FROM t1;
+} {1 2 3}
+do_execsql_test 16.7 {
+  INSERT INTO t1 VALUES(4);
+}
+do_test 16.8 {
+  set R [sqlite3_recover_init db main test.db2]
+  $R run
+  list [catch { $R finish } msg] $msg
+} {1 {cannot start a transaction within a transaction}}
+do_execsql_test 16.9 {
+  SELECT * FROM t1;
+  COMMIT;
+} {1 2 3 4}
+
 finish_test
 
index 30260f014e6bc81a1d53becf384bab9995f17a34..e62aba752f4dc49e85c3ddff5032b6323e43eb62 100644 (file)
@@ -2017,6 +2017,7 @@ static void recoverFinalCleanup(sqlite3_recover *p){
   p->pTblList = 0;
   sqlite3_finalize(p->pGetPage);
   p->pGetPage = 0;
+  sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0);
 
   {
 #ifndef NDEBUG
@@ -2315,6 +2316,7 @@ static int recoverVfsRead(sqlite3_file *pFd, void *aBuf, int nByte, i64 iOff){
       **
       **   + first freelist page (32-bits at offset 32)
       **   + size of freelist (32-bits at offset 36)
+      **   + the wal-mode flags (16-bits at offset 18)
       **
       ** We also try to preserve the auto-vacuum, incr-value, user-version
       ** and application-id fields - all 32 bit quantities at offsets 
@@ -2378,7 +2380,8 @@ static int recoverVfsRead(sqlite3_file *pFd, void *aBuf, int nByte, i64 iOff){
       if( p->pPage1Cache ){
         p->pPage1Disk = &p->pPage1Cache[nByte];
         memcpy(p->pPage1Disk, aBuf, nByte);
-
+        aHdr[18] = a[18];
+        aHdr[19] = a[19];
         recoverPutU32(&aHdr[28], dbsz);
         recoverPutU32(&aHdr[56], enc);
         recoverPutU16(&aHdr[105], pgsz-nReserve);
@@ -2574,6 +2577,7 @@ static void recoverStep(sqlite3_recover *p){
       recoverOpenOutput(p);
 
       /* Open transactions on both the input and output databases. */
+      sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0);
       recoverExec(p, p->dbIn, "PRAGMA writable_schema = on");
       recoverExec(p, p->dbIn, "BEGIN");
       if( p->errCode==SQLITE_OK ) p->bCloseTransaction = 1;
index 3c8dd3fcafcdcf2bef00c5c6f2c749d145ae2907..345adfe88deccf3dbb784c7e414af112050aae64 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\scorner\scases\sin\sUTF8\shandling\sin\sthe\sREGEXP\sextension.\n[forum:/forumpost/3ffe058b04|Forum\spost\s3ffe058b04].
-D 2022-12-26T16:03:34.506
+C Add\sthe\sSQLITE_FCNTL_RESET_CACHE\sverb.\sUse\sit\sto\sensure\sthat\sthe\spage\scache\sis\spurged\sbefore\sand\safter\sa\sthe\srecovery\sextension\sis\srun.
+D 2022-12-26T16:12:40.344
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -387,7 +387,7 @@ F ext/rbu/sqlite3rbu.c c4ba7901b2d3e0c7845f30840e3ffb35c6f999d6da0d80f121866491f
 F ext/rbu/sqlite3rbu.h 02d981e2d39c151391759e1a400e29c7388730812957ac3db8dad7f6c9f9cfc8
 F ext/rbu/test_rbu.c ee6ede75147bc081fe9bc3931e6b206277418d14d3fbceea6fdc6216d9b47055
 F ext/recover/dbdata.c 8f1f75d636431de69d7977ec50fc41bfdd0c48c510d5ee7eae0cbd4164e1429a
-F ext/recover/recover1.test 02004eb8f9ec2825ba77e24742c18e45162cb21d27e76a3a435b83a759a1131a
+F ext/recover/recover1.test 2a2df2943d6696f9487e75868feae4b1511c4a511b102854ba0d2af0326d9dfb
 F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a
 F ext/recover/recoverclobber.test 3ba6c0c373c5c63d17e82eced64c05c57ccaf26c1abe1ca7141334022a79f32e
 F ext/recover/recovercorrupt.test 64c081ad1200ae77b447da99eb724785d6bf71715f394543dc7689642e92bf49
@@ -399,7 +399,7 @@ F ext/recover/recoverpgsz.test 3658ab8e68475b1bb87d6af88baa04551c84b73280a566a1b
 F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f
 F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411
 F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486
-F ext/recover/sqlite3recover.c 1e4de9cd30daa67e5c1cd0cafb764ddf183087ce037ab47b7c1a7e2921c90d37
+F ext/recover/sqlite3recover.c 6d37a422c8917b793548a7b2c6e7ff8e1af15ba5453eef37bb69331828b73186
 F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959
 F ext/recover/test_recover.c 1a34e2d04533d919a30ae4d5caeb1643f6684e9ccd7597ca27721d8af81f4ade
 F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
@@ -576,8 +576,8 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
 F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7
 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
 F src/btmutex.c 6ffb0a22c19e2f9110be0964d0731d2ef1c67b5f7fabfbaeb7b9dabc4b7740ca
-F src/btree.c 6321ff29261bf9726e6b231058ff21b1ccf9f441a0b718b76c37341b16fa14ce
-F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
+F src/btree.c 0d2aa1331a63eefc054faa8701cfe3ba1cbe27540cb02f65c61b0605bf6b5004
+F src/btree.h edfb08230b6fd6b0a165ba82defd3471b0e71d577d0c66807d4994d4aade4332
 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e
 F src/build.c d3e43e950e4e377c1d451a4862556792acdef1faba14a03f899d30d09731c48b
 F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a
@@ -600,7 +600,7 @@ F src/insert.c 90a32bc7faa755cd5292ade21d2b3c6edba8fd1d70754a364caccabfde2c3bb2
 F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 25663175950c5c4404b9377840b7b4c6fe5c53b415caf43634c62f442c02a9a7
-F src/main.c fa53bb2ae09549dab5629271c3cfd681f89059f5192afaaaf5c0d396bb3957fe
+F src/main.c 954490392b74fb215378af3c75a9e1f4f559f19cb1567e5d77f3fbbb63909b4d
 F src/malloc.c dfddca1e163496c0a10250cedeafaf56dff47673e0f15888fb0925340a8e3f90
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -639,7 +639,7 @@ F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
 F src/select.c 9886d6669f5787471aab6ae52af76fad90b53edb1c218fc9ed9d953363bc5184
 F src/shell.c.in f2736e84caf751e94477776df8ab0e4ebc8311de00594d997abd81533debc85c
-F src/sqlite.h.in bdb10b78166f5b735318667eb16c84ac90d9e0de88cc25c193eeb4379a126945
+F src/sqlite.h.in b729158b4c018117fe318f0be60a8c0da10e53cb2153f8349d05fde7ceb0d15b
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h c4b9fa7a7e2bcdf850cfeb4b8a91d5ec47b7a00033bc996fd2ee96cbf2741f5f
 F src/sqliteInt.h 2c24ba38f78e32fe5d7ec136321a6ad827698b33ca98664970a8b7274d69ef7c
@@ -2055,9 +2055,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P cbcd7d9be5e5fa6c55fa53a868ff07ee2c1725fc27c57a4bb390072e369b2be4
-Q +abb18f61c5cec0f524acc41453b4c06b61c5af51ff46417588837fc0c3967288
-R 5f18be7e6ce38d41b3bb5a844923b1e4
+P 93e68b398329dcdd25758065c5f45b0e8c43368ab7a034201a244c7b3ac5b3dd
+Q +6db0bc4bc0d272b610bef2aeeae43f539ed6e7cc0a9cc767d5af85ecb0019d5f
+R 6541c042c6881343061ead3cde9d9b14
 U drh
-Z da0736ec3d4438c4303b366a0507405c
+Z 5aba8c4a6cc90f0296c6d0975dc5fc81
 # Remove this line to create a well-formed Fossil manifest.
index b510257e3ea35ccd3d9e2b7b322472fed1e25901..1ead9e82748322611130f512ae08db53598afda1 100644 (file)
@@ -1 +1 @@
-93e68b398329dcdd25758065c5f45b0e8c43368ab7a034201a244c7b3ac5b3dd
\ No newline at end of file
+71dd920f92457a30aff21665de5d6b8fcdcb06119022bb8fd950960c2e041216
\ No newline at end of file
index df24b7b33c2de01c66b095f437b5107a2d9ee08c..9f1bc56f6d9bdd0339aa7ed47a466b24d8129156 100644 (file)
@@ -11072,6 +11072,17 @@ int sqlite3BtreeIsReadonly(Btree *p){
 */
 int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
 
+/*
+** If no transaction is active and the database is not a temp-db, clear
+** the in-memory pager cache.
+*/
+void sqlite3BtreeClearCache(Btree *p){
+  BtShared *pBt = p->pBt;
+  if( pBt->inTransaction==TRANS_NONE ){
+    sqlite3PagerClearCache(pBt->pPager);
+  }
+}
+
 #if !defined(SQLITE_OMIT_SHARED_CACHE)
 /*
 ** Return true if the Btree passed as the only argument is sharable.
index f80ba4a97b242e02c01bb3aed5421b30b4b1482a..bb29870d24aa863f64f66aa11d71799b9690962d 100644 (file)
@@ -368,6 +368,8 @@ void sqlite3BtreeCursorList(Btree*);
 
 int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64);
 
+void sqlite3BtreeClearCache(Btree*);
+
 /*
 ** If we are not using shared cache, then there is no need to
 ** use mutexes to access the BtShared structures.  So make the
index b0645efe61155b4bba798b2aabeb57d503bc4402..67dd60ae7e591f053c97e0724460898427d1f3a7 100644 (file)
@@ -3950,6 +3950,9 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
         sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0);
       }
       rc = SQLITE_OK;
+    }else if( op==SQLITE_FCNTL_RESET_CACHE ){
+      sqlite3BtreeClearCache(pBtree);
+      rc = SQLITE_OK;
     }else{
       int nSave = db->busyHandler.nBusy;
       rc = sqlite3OsFileControl(fd, op, pArg);
index c2bbc8ee3aca1dadafb8ef6f3f231d8225349d01..0d3040a4b32cb10ab167992b24b97a12821ee070 100644 (file)
@@ -1192,6 +1192,12 @@ struct sqlite3_io_methods {
 **
 ** <li>[[SQLITE_FCNTL_CKSM_FILE]]
 ** Used by the cksmvfs VFS module only.
+**
+** <li>[[SQLITE_FCNTL_RESET_CACHE]]
+** If there is currently no transaction open on the database, and the 
+** database is not a temp db, then this file-control purges the contents
+** of the in-memory page cache. If there is an open transaction, or if
+** the db is a temp-db, it is a no-op, not an error.
 ** </ul>
 */
 #define SQLITE_FCNTL_LOCKSTATE               1
@@ -1234,6 +1240,7 @@ struct sqlite3_io_methods {
 #define SQLITE_FCNTL_CKPT_START             39
 #define SQLITE_FCNTL_EXTERNAL_READER        40
 #define SQLITE_FCNTL_CKSM_FILE              41
+#define SQLITE_FCNTL_RESET_CACHE            42
 
 /* deprecated names */
 #define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE