summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuhong Zhang <yuhong.zhang@mongodb.com>2022-03-28 13:20:31 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-06-11 19:18:23 +0000
commit0b631bd20851f04838616a4f00a29ff8a0320767 (patch)
tree9639c3aa0602f6193561be12b76838e26632ca84
parent2f1e8dc34c7ddfa1c9dccab011759a12532c8219 (diff)
downloadmongo-0b631bd20851f04838616a4f00a29ff8a0320767.tar.gz
SERVER-55173 Skip releasing cursors during shutdown to avoid segmentation fault
(cherry picked from commit bc940d6b0adc9254b62e9daf9c92d2c92f8b083d) (cherry picked from commit 7a074786f4048e3ac304dfbab12a5fafd5f14f00)
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp12
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h5
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_session_cache_test.cpp15
3 files changed, 31 insertions, 1 deletions
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
index c80ac13d70b..ff545f445b4 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
@@ -131,6 +131,11 @@ WT_CURSOR* WiredTigerSession::getReadOnceCursor(const std::string& uri, bool all
}
void WiredTigerSession::releaseCursor(uint64_t id, WT_CURSOR* cursor) {
+ // Avoids the cursor already being destroyed during the shutdown.
+ if (_cache->isShuttingDown()) {
+ return;
+ }
+
invariant(_session);
invariant(cursor);
_cursorsOut--;
@@ -227,6 +232,10 @@ void WiredTigerSessionCache::shuttingDown() {
closeAll();
}
+bool WiredTigerSessionCache::isShuttingDown() {
+ return _shuttingDown.load() & kShuttingDownMask;
+}
+
void WiredTigerSessionCache::waitUntilDurable(bool forceCheckpoint, bool stableCheckpoint) {
// For inMemory storage engines, the data is "as durable as it's going to get".
// That is, a restart is equivalent to a complete node failure.
@@ -416,7 +425,8 @@ UniqueWiredTigerSession WiredTigerSessionCache::getSession() {
void WiredTigerSessionCache::releaseSession(WiredTigerSession* session) {
invariant(session);
- invariant(session->cursorsOut() == 0);
+ // 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); });
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h
index 5c44b4cbd08..89d95ad7ed0 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h
@@ -259,6 +259,11 @@ public:
*/
void shuttingDown();
+ /**
+ * True when in the process of shutting down.
+ */
+ bool isShuttingDown();
+
bool isEphemeral();
/**
* Waits until all commits that happened before this call are durable, either by flushing
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache_test.cpp
index 8cfd3d1ddc5..59ad59bb3f8 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache_test.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache_test.cpp
@@ -113,4 +113,19 @@ TEST(WiredTigerSessionCacheTest, CheckSessionCacheCleanup) {
ASSERT_EQUALS(sessionCache->getIdleSessionsCount(), 0U);
}
+TEST(WiredTigerSessionCacheTest, ReleaseCursorDuringShutdown) {
+ WiredTigerSessionCacheHarnessHelper harnessHelper("");
+ WiredTigerSessionCache* sessionCache = harnessHelper.getSessionCache();
+ UniqueWiredTigerSession session = sessionCache->getSession();
+ // Simulates the cursor already being deleted during shutdown.
+ WT_CURSOR* cursor = nullptr;
+
+ sessionCache->shuttingDown();
+ ASSERT(sessionCache->isShuttingDown());
+
+ auto tableIdWeDontCareAbout = WiredTigerSession::genTableId();
+ // Skips actually trying to release the cursor to avoid the segmentation fault.
+ session->releaseCursor(tableIdWeDontCareAbout, cursor);
+}
+
} // namespace mongo