1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-10 01:02:56 +03:00

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
This commit is contained in:
dan
2021-12-15 12:51:02 +00:00
parent b90edad19d
commit 348093c719
5 changed files with 112 additions and 24 deletions

View File

@@ -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));
}