aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <Dan Kennedy>2022-11-28 18:41:41 +0000
committerdan <Dan Kennedy>2022-11-28 18:41:41 +0000
commit1b3d13e65e125500d1034e889b37363baa8f1e38 (patch)
tree81840dd9a80fe5015dbd1ae798fe620876f38667 /src
parente862b5fe1d2bda6ef7d557471c150c82ec453455 (diff)
downloadsqlite-1b3d13e65e125500d1034e889b37363baa8f1e38.tar.gz
sqlite-1b3d13e65e125500d1034e889b37363baa8f1e38.zip
Add the SQLITE_FCNTL_RESET_CACHE verb. Use it to ensure that the page cache is purged before and after a the recovery extension is run.
FossilOrigin-Name: 6db0bc4bc0d272b610bef2aeeae43f539ed6e7cc0a9cc767d5af85ecb0019d5f
Diffstat (limited to 'src')
-rw-r--r--src/btree.c11
-rw-r--r--src/btree.h2
-rw-r--r--src/main.c3
-rw-r--r--src/sqlite.h.in7
4 files changed, 23 insertions, 0 deletions
diff --git a/src/btree.c b/src/btree.c
index cabcf675e..c949001b8 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -11083,6 +11083,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.
diff --git a/src/btree.h b/src/btree.h
index 7f31c6020..c9b9d8017 100644
--- a/src/btree.h
+++ b/src/btree.h
@@ -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
diff --git a/src/main.c b/src/main.c
index b0645efe6..67dd60ae7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index c2fc4e5a6..369d6b602 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -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