diff options
author | Yuhong Zhang <yuhong.zhang@mongodb.com> | 2022-05-23 13:41:25 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-05-31 18:12:21 +0000 |
commit | b1b34b9541fda4d4c5517aa8dae5c0159bde3cce (patch) | |
tree | ec1fee473f07d4ac878500d7b8ea7ef62eec2ace /src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp | |
parent | 66ab552d94f76d328ab09fb37dffd655884fb262 (diff) | |
download | mongo-b1b34b9541fda4d4c5517aa8dae5c0159bde3cce.tar.gz |
SERVER-66556 Block shutdown when releasing cursors to avoid race conditions
(cherry picked from commit 66e938045f87c72f379eb0def449b62bde97721c)
Diffstat (limited to 'src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp')
-rw-r--r-- | src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp index d7997dee2c5..3ed1d4e985b 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp @@ -137,6 +137,10 @@ WT_CURSOR* WiredTigerSession::getNewCursor(const std::string& uri, const char* c } void WiredTigerSession::releaseCursor(uint64_t id, WT_CURSOR* cursor, const std::string& config) { + // When releasing the cursor, we would want to check if the session cache is already in shutdown + // and prevent the race condition that the shutdown starts after the check. + WiredTigerSessionCache::BlockShutdown blockShutdown(_cache); + // Avoids the cursor already being destroyed during the shutdown. if (_cache->isShuttingDown()) { return; @@ -230,7 +234,7 @@ void WiredTigerSessionCache::shuttingDown() { if (_shuttingDown.fetchAndBitOr(kShuttingDownMask) & kShuttingDownMask) return; - // Spin as long as there are threads in releaseSession + // Spin as long as there are threads blocking shutdown. while (_shuttingDown.load() != kShuttingDownMask) { sleepmillis(1); } @@ -265,12 +269,11 @@ void WiredTigerSessionCache::waitUntilDurable(OperationContext* opCtx, return; } - const int shuttingDown = _shuttingDown.fetchAndAdd(1); - ON_BLOCK_EXIT([this] { _shuttingDown.fetchAndSubtract(1); }); + BlockShutdown blockShutdown(this); uassert(ErrorCodes::ShutdownInProgress, "Cannot wait for durability because a shutdown is in progress", - !(shuttingDown & kShuttingDownMask)); + !isShuttingDown()); // Stable checkpoints are only meaningful in a replica set. Replication sets the "stable // timestamp". If the stable timestamp is unset, WiredTiger takes a full checkpoint, which is @@ -486,10 +489,9 @@ void WiredTigerSessionCache::releaseSession(WiredTigerSession* session) { // We might have skipped releasing some cursors during the shutdown. invariant(session->cursorsOut() == 0 || isShuttingDown()); - const int shuttingDown = _shuttingDown.fetchAndAdd(1); - ON_BLOCK_EXIT([this] { _shuttingDown.fetchAndSubtract(1); }); + BlockShutdown blockShutdown(this); - if (shuttingDown & kShuttingDownMask) { + if (isShuttingDown()) { // There is a race condition with clean shutdown, where the storage engine is ripped from // underneath OperationContexts, which are not "active" (i.e., do not have any locks), but // are just about to delete the recovery unit. See SERVER-16031 for more information. Since |