From d5f4a148778c761dbee720106786c8290fec428b Mon Sep 17 00:00:00 2001 From: Louis Williams Date: Fri, 24 Feb 2023 15:16:51 +0000 Subject: SERVER-65106 Periodically wake to check if prepared transaction has ended --- src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp') diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp index 5fbfe2b8a7c..175337a743b 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp @@ -368,9 +368,17 @@ void WiredTigerSessionCache::waitUntilDurable(OperationContext* opCtx, void WiredTigerSessionCache::waitUntilPreparedUnitOfWorkCommitsOrAborts(OperationContext* opCtx, std::uint64_t lastCount) { invariant(opCtx); + + // It is possible for a prepared transaction to block on bonus eviction inside WiredTiger after + // it commits or rolls-back, but this delays it from signalling us to wake up. In the very + // worst case that the only evictable page is the one pinned by our cursor, AND there are no + // other prepared transactions committing or aborting, we could reach a deadlock. Since the + // caller is already expecting spurious wakeups, we impose a large timeout to periodically force + // the caller to retry its operation. + const auto deadline = Date_t::now() + Seconds(1); stdx::unique_lock lk(_prepareCommittedOrAbortedMutex); if (lastCount == _prepareCommitOrAbortCounter.loadRelaxed()) { - opCtx->waitForConditionOrInterrupt(_prepareCommittedOrAbortedCond, lk, [&] { + opCtx->waitForConditionOrInterruptUntil(_prepareCommittedOrAbortedCond, lk, deadline, [&] { return _prepareCommitOrAbortCounter.loadRelaxed() > lastCount; }); } -- cgit v1.2.1