diff options
author | dan <Dan Kennedy> | 2024-09-26 18:02:17 +0000 |
---|---|---|
committer | dan <Dan Kennedy> | 2024-09-26 18:02:17 +0000 |
commit | d0720eee5e19d9d6889b275bdb652e5e0160899c (patch) | |
tree | 32883f27d0150749b75d6bf69dd52a2d0720e835 /src/wal.c | |
parent | 8cd30e3f5b6306b8d657e3dd7376763ab10f0279 (diff) | |
download | sqlite-d0720eee5e19d9d6889b275bdb652e5e0160899c.tar.gz sqlite-d0720eee5e19d9d6889b275bdb652e5e0160899c.zip |
When possible, avoid taking wal file read-lock 0 in sqlite3_snapshot_get().
FossilOrigin-Name: 34b6ac3d76dbc6819778ec2a0f81cbcdcc0cd1a6303381d97f1c479e4ecdd132
Diffstat (limited to 'src/wal.c')
-rw-r--r-- | src/wal.c | 18 |
1 files changed, 16 insertions, 2 deletions
@@ -541,6 +541,7 @@ struct Wal { #endif #ifdef SQLITE_ENABLE_SNAPSHOT WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ + int bGetSnapshot; /* Transaction opened for sqlite3_get_snapshot() */ #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT sqlite3 *db; @@ -3097,7 +3098,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ SEH_INJECT_FAULT; if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame #ifdef SQLITE_ENABLE_SNAPSHOT - && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) + && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) #endif ){ /* The WAL has been completely backfilled (or it is empty). @@ -4497,7 +4498,20 @@ void sqlite3WalSnapshotOpen( Wal *pWal, sqlite3_snapshot *pSnapshot ){ - pWal->pSnapshot = (WalIndexHdr*)pSnapshot; + if( pSnapshot && ((WalIndexHdr*)pSnapshot)->iVersion==0 ){ + /* iVersion==0 means that this is a call to sqlite3_snapshot_get(). In + ** this case set the bGetSnapshot flag so that if the call to + ** sqlite3_snapshot_get() is about to read transaction on this wal + ** file, it does not take read-lock 0 if the wal file has been completely + ** checkpointed. Taking read-lock 0 would work, but then it would be + ** possible for a subsequent writer to destroy the snapshot even while + ** this connection is holding its read-transaction open. This is contrary + ** to user expectations, so we avoid it by not taking read-lock 0. */ + pWal->bGetSnapshot = 1; + }else{ + pWal->pSnapshot = (WalIndexHdr*)pSnapshot; + pWal->bGetSnapshot = 0; + } } /* |