diff options
author | Daniel Gottlieb <daniel.gottlieb@mongodb.com> | 2021-03-23 15:29:54 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-10-06 13:51:14 +0000 |
commit | 28f46cb15f2ff5bbbd22b45006789bb3edb71872 (patch) | |
tree | 708c948e7010396ae2d529378f4c0b21347ce4ad | |
parent | aeb7d315a3e9c8a86dc005cee34a1cc1867b10c8 (diff) | |
download | mongo-28f46cb15f2ff5bbbd22b45006789bb3edb71872.tar.gz |
SERVER-54064: Periodically clear out the logical session cache on arbiters.
(cherry picked from commit 8b64da4e43b7318a7ab8a7580708195b6de91200)
-rw-r--r-- | jstests/noPassthrough/server54064.js | 57 | ||||
-rw-r--r-- | src/mongo/db/logical_session_cache_impl.cpp | 20 | ||||
-rw-r--r-- | src/mongo/shell/servers.js | 4 |
3 files changed, 67 insertions, 14 deletions
diff --git a/jstests/noPassthrough/server54064.js b/jstests/noPassthrough/server54064.js new file mode 100644 index 00000000000..e4bbad6e7fd --- /dev/null +++ b/jstests/noPassthrough/server54064.js @@ -0,0 +1,57 @@ +/** + * Assert that arbiters periodically clear out their logical session cache. Inability to do so + * prohibits new clients from connecting. + * + * @tags: [requires_replication] + */ +(function() { +const name = "server54064"; +const replSet = new ReplSetTest({ + name: name, + nodes: 2, + // `disableLogicalSessionCacheRefresh` is true by default, but is disabled for testing purposes + // in servers spawned from the shell. + nodeOptions: { + setParameter: { + // Each refresh on an arbiter will empty the cache. + logicalSessionRefreshMillis: 10000, + // The number of connections/sessions before the cache is full, prohibiting new clients + // from connecting. + maxSessions: 3, + disableLogicalSessionCacheRefresh: false + } + } +}); +const nodes = replSet.nodeList(); + +replSet.startSet(); +replSet.initiate({ + _id: name, + members: [{_id: 0, host: nodes[0]}, {_id: 1, host: nodes[1], arbiterOnly: true}], +}); + +let arbConn = replSet.getArbiter(); +assert.soon(() => { + // Connect to mongo in a tight loop to exhaust the number of available logical sessions in the + // cache. + const result = new Mongo(arbConn.host).adminCommand({hello: 1}); + if (result['ok'] === 0) { + assert.commandFailedWithCode(result, ErrorCodes.TooManyLogicalSessions); + return true; + } + return false; +}); + +assert.soon(() => { + // Once we observe that the number of sessions is maxed out, loop again to confirm that the + // cache eventually does get cleared. + const result = new Mongo(arbConn.host).adminCommand({hello: 1}); + if (result['ok'] === 0) { + assert.commandFailedWithCode(result, ErrorCodes.TooManyLogicalSessions); + return false; + } + return true; +}); + +replSet.stopSet(); +})(); diff --git a/src/mongo/db/logical_session_cache_impl.cpp b/src/mongo/db/logical_session_cache_impl.cpp index 857e33b1568..349da7906f9 100644 --- a/src/mongo/db/logical_session_cache_impl.cpp +++ b/src/mongo/db/logical_session_cache_impl.cpp @@ -182,19 +182,11 @@ Status LogicalSessionCacheImpl::_reap(Client* client) { try { _sessionsColl->checkSessionsCollectionExists(opCtx); } catch (const DBException& ex) { - if (ex.code() != ErrorCodes::NamespaceNotFound || - ex.code() != ErrorCodes::NamespaceNotSharded) { - LOGV2( - 20712, - "Sessions collection is not set up: {error}; waiting until next sessions reap " - "interval", - "Sessions collection is not set up; waiting until next sessions reap interval", - "error"_attr = redact(ex)); - } else { - LOGV2(20713, - "Sessions collection is not set up because the namespace is either not found" - "or not sharded; waiting until next sessions reap interval"); - } + LOGV2(20712, + "Sessions collection is not set up: {error}; waiting until next sessions reap " + "interval", + "Sessions collection is not set up; waiting until next sessions reap interval", + "error"_attr = redact(ex)); return Status::OK(); } numReaped = _reapSessionsOlderThanFn(opCtx, @@ -235,6 +227,8 @@ void LogicalSessionCacheImpl::_refresh(Client* client) { const auto replCoord = repl::ReplicationCoordinator::get(opCtx); if (replCoord && replCoord->isReplEnabled() && replCoord->getMemberState().arbiter()) { + stdx::lock_guard<Latch> lk(_mutex); + _activeSessions.clear(); return; } diff --git a/src/mongo/shell/servers.js b/src/mongo/shell/servers.js index b5ee35bab4d..a60fcf8fe2a 100644 --- a/src/mongo/shell/servers.js +++ b/src/mongo/shell/servers.js @@ -1137,7 +1137,9 @@ function appendSetParameterArgs(argArray) { } // Disable background cache refreshing to avoid races in tests - argArray.push(...['--setParameter', "disableLogicalSessionCacheRefresh=true"]); + if (!argArrayContainsSetParameterValue('disableLogicalSessionCacheRefresh=')) { + argArray.push(...['--setParameter', "disableLogicalSessionCacheRefresh=true"]); + } } // Since options may not be backward compatible, mongos options are not |