diff options
author | Luis Osta <luis.osta@mongodb.com> | 2021-10-07 19:14:32 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-10-07 19:28:29 +0000 |
commit | b59d2547c281c42e61b52d44291d500f4dad21e4 (patch) | |
tree | e4c2fa42215737104fb9302b77d9a9f11a4e983d | |
parent | 642531a44a0d6675f028f6affc4c3fcac36c67c2 (diff) | |
download | mongo-b59d2547c281c42e61b52d44291d500f4dad21e4.tar.gz |
SERVER-54064 Clear out the logical session cache on refresh in arbiters
-rw-r--r-- | jstests/noPassthrough/server54064.js | 60 | ||||
-rw-r--r-- | src/mongo/db/logical_session_cache_impl.cpp | 9 | ||||
-rw-r--r-- | src/mongo/shell/servers.js | 4 |
3 files changed, 66 insertions, 7 deletions
diff --git a/jstests/noPassthrough/server54064.js b/jstests/noPassthrough/server54064.js new file mode 100644 index 00000000000..e08449a79bf --- /dev/null +++ b/jstests/noPassthrough/server54064.js @@ -0,0 +1,60 @@ +/** + * 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 f59be6f4bef..40f015940f8 100644 --- a/src/mongo/db/logical_session_cache_impl.cpp +++ b/src/mongo/db/logical_session_cache_impl.cpp @@ -250,12 +250,7 @@ Status LogicalSessionCacheImpl::_reap(Client* client) { StringData notSetUpWarning = "Sessions collection is not set up; " "waiting until next sessions reap interval"; - if (existsStatus.code() != ErrorCodes::NamespaceNotFound || - existsStatus.code() != ErrorCodes::NamespaceNotSharded) { - log() << notSetUpWarning << ": " << existsStatus.reason(); - } else { - log() << notSetUpWarning; - } + log() << notSetUpWarning << ": " << existsStatus.reason(); return Status::OK(); } @@ -299,6 +294,8 @@ void LogicalSessionCacheImpl::_refresh(Client* client) { const auto replCoord = repl::ReplicationCoordinator::get(opCtx); if (replCoord && replCoord->isReplEnabled() && replCoord->getMemberState().arbiter()) { + stdx::lock_guard<stdx::mutex> lk(_mutex); + _activeSessions.clear(); return; } diff --git a/src/mongo/shell/servers.js b/src/mongo/shell/servers.js index 51c016b146d..7c873be9f0c 100644 --- a/src/mongo/shell/servers.js +++ b/src/mongo/shell/servers.js @@ -1106,7 +1106,9 @@ var MongoRunner, _startMongod, startMongoProgram, runMongoProgram, startMongoPro } // 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 |