From ded1959120db41174d720fc3a157cc648694d6f9 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 May 2025 20:52:18 +0000 Subject: If blocking locks are enabled, avoid using the busy handler when blocked by another process running recovery. FossilOrigin-Name: a35236757ab57c4c9b34e47c5dbc10d8f1220f8152955f5303cf9c3902ee169b --- src/btree.c | 5 ++--- src/os_unix.c | 5 +++-- src/pager.c | 9 +++++++++ src/wal.c | 3 ++- 4 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/btree.c b/src/btree.c index 064856635..25a9b1b4a 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3697,11 +3697,10 @@ static SQLITE_NOINLINE int btreeBeginTrans( (void)sqlite3PagerWalWriteLock(pPager, 0); unlockBtreeIfUnused(pBt); } -#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_ENABLE_SNAPSHOT) +#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) if( rc==SQLITE_BUSY_TIMEOUT ){ /* If a blocking lock timed out, break out of the loop here so that - ** the busy-handler is not invoked. This can only happen when opening - ** a transaction on a snapshot. */ + ** the busy-handler is not invoked. */ break; } #endif diff --git a/src/os_unix.c b/src/os_unix.c index 1146545fe..5bbd7ceb6 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5043,13 +5043,14 @@ static int unixShmLock( ** occur later in the above list than the lock being obtained may be ** held. ** - ** It is not permitted to block on the RECOVER lock. + ** It is not permitted to block on the RECOVER lock if any other + ** locks are held. */ #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) { u16 lockMask = (p->exclMask|p->sharedMask); assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( - (ofst!=2) /* not RECOVER */ + (ofst!=2 || lockMask==0) /* not RECOVER */ && (ofst!=1 || lockMask==0 || lockMask==2) && (ofst!=0 || lockMask<3) && (ofst<3 || lockMask<(1<fd, pPager->zWal, pPager->exclusiveMode, pPager->journalSizeLimit, &pPager->pWal ); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_OK ){ + sqlite3WalDb(pPager->pWal, pPager->dbWal); + } +#endif } pagerFixMaplimit(pPager); @@ -7700,6 +7708,7 @@ int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){ ** blocking locks are required. */ void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ + pPager->dbWal = db; if( pagerUseWal(pPager) ){ sqlite3WalDb(pPager->pWal, db); } diff --git a/src/wal.c b/src/wal.c index 5fe2296d6..fc176988b 100644 --- a/src/wal.c +++ b/src/wal.c @@ -3062,7 +3062,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ rc = walIndexReadHdr(pWal, pChanged); } #ifdef SQLITE_ENABLE_SETLK_TIMEOUT - walDisableBlocking(pWal); if( rc==SQLITE_BUSY_TIMEOUT ){ rc = SQLITE_BUSY; *pCnt |= WAL_RETRY_BLOCKED_MASK; @@ -3077,6 +3076,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ ** WAL_RETRY this routine will be called again and will probably be ** right on the second iteration. */ + walEnableBlocking(pWal); if( pWal->apWiData[0]==0 ){ /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. ** We assume this is a transient condition, so return WAL_RETRY. The @@ -3093,6 +3093,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ rc = SQLITE_BUSY_RECOVERY; } } + walDisableBlocking(pWal); if( rc!=SQLITE_OK ){ return rc; } -- cgit v1.2.3