summaryrefslogtreecommitdiff
path: root/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
diff options
context:
space:
mode:
authorYuhong Zhang <yuhong.zhang@mongodb.com>2022-05-23 13:41:25 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-05-31 18:12:21 +0000
commitb1b34b9541fda4d4c5517aa8dae5c0159bde3cce (patch)
treeec1fee473f07d4ac878500d7b8ea7ef62eec2ace /src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
parent66ab552d94f76d328ab09fb37dffd655884fb262 (diff)
downloadmongo-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.cpp16
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