diff options
-rw-r--r-- | src/mongo/db/SConscript | 34 | ||||
-rw-r--r-- | src/mongo/db/logical_session_cache_factory_mongod.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/session_catalog_mongod.cpp | 129 | ||||
-rw-r--r-- | src/mongo/db/session_catalog_mongod.h | 10 | ||||
-rw-r--r-- | src/mongo/db/session_catalog_mongod_test.cpp (renamed from src/mongo/db/transaction_reaper_d_test.cpp) | 9 | ||||
-rw-r--r-- | src/mongo/db/transaction_reaper_d.cpp | 133 | ||||
-rw-r--r-- | src/mongo/db/transaction_reaper_d.h | 46 | ||||
-rw-r--r-- | src/mongo/s/server.cpp | 13 | ||||
-rw-r--r-- | src/mongo/s/session_catalog_router.cpp | 6 | ||||
-rw-r--r-- | src/mongo/s/session_catalog_router.h | 13 |
10 files changed, 162 insertions, 235 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index 93928f28e42..3f987df8840 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -1544,28 +1544,10 @@ env.Library( ], ) -env.Library( - target='transaction_reaper_d', - source=[ - 'transaction_reaper_d.cpp', - ], - LIBDEPS_PRIVATE=[ - '$BUILD_DIR/mongo/db/repl/repl_coordinator_interface', - '$BUILD_DIR/mongo/idl/server_parameter', - '$BUILD_DIR/mongo/s/client/shard_interface', - '$BUILD_DIR/mongo/s/coreshard', - 'dbdirectclient', - 'logical_session_id', - 'sessions_collection', - 'write_ops', - ], -) - envWithAsio.CppUnitTest( target='logical_session_cache_test', source=[ 'logical_session_cache_test.cpp', - 'transaction_reaper_d_test.cpp', ], LIBDEPS=[ '$BUILD_DIR/mongo/executor/async_timer_mock', @@ -1582,7 +1564,6 @@ envWithAsio.CppUnitTest( 'service_context_d_test_fixture', 'service_liaison_mock', 'sessions_collection_mock', - 'transaction_reaper_d', 'transaction', ], ) @@ -1602,7 +1583,7 @@ envWithAsio.Library( 'sessions_collection_standalone', ], LIBDEPS_PRIVATE=[ - 'transaction_reaper_d', + 'transaction', ], ) @@ -2083,18 +2064,27 @@ env.CppUnitTest( env.CppUnitTest( target='transaction_participant_test', - source=[ + source=[ 'transaction_participant_test.cpp', 'transaction_participant_retryable_writes_test.cpp', + 'session_catalog_mongod_test.cpp', ], - LIBDEPS=[ + LIBDEPS_PRIVATE=[ '$BUILD_DIR/mongo/client/read_preference', + '$BUILD_DIR/mongo/idl/server_parameter', '$BUILD_DIR/mongo/util/clock_source_mock', 'auth/authmocks', + 'dbdirectclient', + 'logical_session_id', 'op_observer', 'query_exec', 'repl/mock_repl_coord_server_fixture', + 'repl/repl_coordinator_interface', + 'service_liaison_mock', + 'sessions_collection_mock', + 'sessions_collection', 'transaction', + 'write_ops', ], ) diff --git a/src/mongo/db/logical_session_cache_factory_mongod.cpp b/src/mongo/db/logical_session_cache_factory_mongod.cpp index 2d9870e258a..b54b3119b03 100644 --- a/src/mongo/db/logical_session_cache_factory_mongod.cpp +++ b/src/mongo/db/logical_session_cache_factory_mongod.cpp @@ -35,11 +35,11 @@ #include "mongo/db/logical_session_cache_impl.h" #include "mongo/db/service_liaison_mongod.h" +#include "mongo/db/session_catalog_mongod.h" #include "mongo/db/sessions_collection_config_server.h" #include "mongo/db/sessions_collection_rs.h" #include "mongo/db/sessions_collection_sharded.h" #include "mongo/db/sessions_collection_standalone.h" -#include "mongo/db/transaction_reaper_d.h" #include "mongo/stdx/memory.h" #include "mongo/util/log.h" @@ -64,7 +64,7 @@ std::unique_ptr<LogicalSessionCache> makeLogicalSessionCacheD(LogicalSessionCach }(); return std::make_unique<LogicalSessionCacheImpl>( - std::move(liaison), std::move(sessionsColl), TransactionReaperD::reapSessionsOlderThan); + std::move(liaison), std::move(sessionsColl), MongoDSessionCatalog::reapSessionsOlderThan); } } // namespace mongo diff --git a/src/mongo/db/session_catalog_mongod.cpp b/src/mongo/db/session_catalog_mongod.cpp index 39880028b28..89508662baa 100644 --- a/src/mongo/db/session_catalog_mongod.cpp +++ b/src/mongo/db/session_catalog_mongod.cpp @@ -33,16 +33,23 @@ #include "mongo/db/session_catalog_mongod.h" +#include "mongo/bson/bsonmisc.h" #include "mongo/db/catalog_raii.h" #include "mongo/db/client.h" #include "mongo/db/dbdirectclient.h" +#include "mongo/db/dbdirectclient.h" #include "mongo/db/namespace_string.h" #include "mongo/db/operation_context.h" +#include "mongo/db/ops/write_ops.h" #include "mongo/db/service_context.h" +#include "mongo/db/session_txn_record_gen.h" +#include "mongo/db/sessions_collection.h" #include "mongo/db/transaction_participant.h" #include "mongo/rpc/get_status_from_command_result.h" +#include "mongo/s/write_ops/batched_command_response.h" #include "mongo/util/concurrency/thread_pool.h" #include "mongo/util/log.h" +#include "mongo/util/scopeguard.h" namespace mongo { namespace { @@ -74,10 +81,9 @@ auto getThreadPool(OperationContext* opCtx) { return &sessionTasksExecutor(opCtx->getServiceContext()).threadPool; } -void killSessionTokensFunction( - OperationContext* opCtx, - std::shared_ptr<std::vector<SessionCatalog::KillToken>> sessionKillTokens) { - if (sessionKillTokens->empty()) +void killSessionTokens(OperationContext* opCtx, + std::vector<SessionCatalog::KillToken> sessionKillTokens) { + if (sessionKillTokens.empty()) return; getThreadPool(opCtx)->schedule( @@ -85,28 +91,80 @@ void killSessionTokensFunction( sessionKillTokens = std::move(sessionKillTokens) ](auto status) mutable { invariant(status); - auto uniqueClient = service->makeClient("Kill-Session"); - auto uniqueOpCtx = uniqueClient->makeOperationContext(); + ThreadClient tc("Kill-Sessions", service); + auto uniqueOpCtx = tc->makeOperationContext(); const auto opCtx = uniqueOpCtx.get(); const auto catalog = SessionCatalog::get(opCtx); - for (auto& sessionKillToken : *sessionKillTokens) { + for (auto& sessionKillToken : sessionKillTokens) { auto session = catalog->checkOutSessionForKill(opCtx, std::move(sessionKillToken)); - - TransactionParticipant::get(session).invalidate(opCtx); + auto participant = TransactionParticipant::get(session); + participant.invalidate(opCtx); } }); } +const auto kIdProjection = BSON(SessionTxnRecord::kSessionIdFieldName << 1); +const auto kSortById = BSON(SessionTxnRecord::kSessionIdFieldName << 1); +const auto kLastWriteDateFieldName = SessionTxnRecord::kLastWriteDateFieldName; + +/** + * Removes the specified set of session ids from the persistent sessions collection and returns the + * number of sessions actually removed. + */ +int removeSessionsTransactionRecords(OperationContext* opCtx, + SessionsCollection& sessionsCollection, + const LogicalSessionIdSet& sessionIdsToRemove) { + if (sessionIdsToRemove.empty()) + return 0; + + // From the passed-in sessions, find the ones which are actually expired/removed + auto expiredSessionIds = + uassertStatusOK(sessionsCollection.findRemovedSessions(opCtx, sessionIdsToRemove)); + + if (expiredSessionIds.empty()) + return 0; + + write_ops::Delete deleteOp(NamespaceString::kSessionTransactionsTableNamespace); + deleteOp.setWriteCommandBase([] { + write_ops::WriteCommandBase base; + base.setOrdered(false); + return base; + }()); + deleteOp.setDeletes([&] { + std::vector<write_ops::DeleteOpEntry> entries; + for (const auto& lsid : expiredSessionIds) { + entries.emplace_back(BSON(LogicalSessionRecord::kIdFieldName << lsid.toBSON()), + false /* multi = false */); + } + return entries; + }()); + + BSONObj result; + + DBDirectClient client(opCtx); + client.runCommand(NamespaceString::kSessionTransactionsTableNamespace.db().toString(), + deleteOp.toBSON({}), + result); + + BatchedCommandResponse response; + std::string errmsg; + uassert(ErrorCodes::FailedToParse, + str::stream() << "Failed to parse response " << result, + response.parseBSON(result, &errmsg)); + uassertStatusOK(response.getTopLevelStatus()); + + return response.getN(); +} + } // namespace void MongoDSessionCatalog::onStepUp(OperationContext* opCtx) { // Invalidate sessions that could have a retryable write on it, so that we can refresh from disk // in case the in-memory state was out of sync. const auto catalog = SessionCatalog::get(opCtx); - // The use of shared_ptr here is in order to work around the limitation of stdx::function that - // the functor must be copyable. - auto sessionKillTokens = std::make_shared<std::vector<SessionCatalog::KillToken>>(); + + std::vector<SessionCatalog::KillToken> sessionKillTokens; // Scan all sessions and reacquire locks for prepared transactions. // There may be sessions that are checked out during this scan, but none of them @@ -119,14 +177,14 @@ void MongoDSessionCatalog::onStepUp(OperationContext* opCtx) { catalog->scanSessions(matcher, [&](const ObservableSession& session) { const auto txnParticipant = TransactionParticipant::get(session); if (!txnParticipant.inMultiDocumentTransaction()) { - sessionKillTokens->emplace_back(session.kill()); + sessionKillTokens.emplace_back(session.kill()); } if (txnParticipant.transactionIsPrepared()) { sessionIdToReacquireLocks.emplace_back(session.getSessionId()); } }); - killSessionTokensFunction(opCtx, sessionKillTokens); + killSessionTokens(opCtx, std::move(sessionKillTokens)); { // Create a new opCtx because we need an empty locker to refresh the locks. @@ -197,9 +255,7 @@ void MongoDSessionCatalog::invalidateSessions(OperationContext* opCtx, const auto catalog = SessionCatalog::get(opCtx); - // The use of shared_ptr here is in order to work around the limitation of stdx::function that - // the functor must be copyable. - auto sessionKillTokens = std::make_shared<std::vector<SessionCatalog::KillToken>>(); + std::vector<SessionCatalog::KillToken> sessionKillTokens; if (singleSessionDoc) { const auto lsid = LogicalSessionId::parse(IDLParserErrorContext("lsid"), @@ -211,17 +267,50 @@ void MongoDSessionCatalog::invalidateSessions(OperationContext* opCtx, << session.getSessionId().getId() << " because it is in the prepared state", !participant.transactionIsPrepared()); - sessionKillTokens->emplace_back(session.kill()); + sessionKillTokens.emplace_back(session.kill()); }); } else { SessionKiller::Matcher matcher( KillAllSessionsByPatternSet{makeKillAllSessionsByPattern(opCtx)}); catalog->scanSessions(matcher, [&sessionKillTokens](const ObservableSession& session) { - sessionKillTokens->emplace_back(session.kill()); + sessionKillTokens.emplace_back(session.kill()); }); } + killSessionTokens(opCtx, std::move(sessionKillTokens)); +} + +int MongoDSessionCatalog::reapSessionsOlderThan(OperationContext* opCtx, + SessionsCollection& sessionsCollection, + Date_t possiblyExpired) { + // Scan for records older than the minimum lifetime and uses a sort to walk the '_id' index + DBDirectClient client(opCtx); + auto cursor = + client.query(NamespaceString::kSessionTransactionsTableNamespace, + Query(BSON(kLastWriteDateFieldName << LT << possiblyExpired)).sort(kSortById), + 0, + 0, + &kIdProjection); + + // The max batch size is chosen so that a single batch won't exceed the 16MB BSON object + // size limit + LogicalSessionIdSet lsids; + const int kMaxBatchSize = 10'000; + + int numReaped = 0; + while (cursor->more()) { + auto transactionSession = SessionsCollectionFetchResultIndividualResult::parse( + "TransactionSession"_sd, cursor->next()); + + lsids.insert(transactionSession.get_id()); + if (lsids.size() > kMaxBatchSize) { + numReaped += removeSessionsTransactionRecords(opCtx, sessionsCollection, lsids); + lsids.clear(); + } + } + + numReaped += removeSessionsTransactionRecords(opCtx, sessionsCollection, lsids); - killSessionTokensFunction(opCtx, sessionKillTokens); + return numReaped; } MongoDOperationContextSession::MongoDOperationContextSession(OperationContext* opCtx) diff --git a/src/mongo/db/session_catalog_mongod.h b/src/mongo/db/session_catalog_mongod.h index e43c2ae84c9..e1eb6d8b4fc 100644 --- a/src/mongo/db/session_catalog_mongod.h +++ b/src/mongo/db/session_catalog_mongod.h @@ -33,6 +33,8 @@ namespace mongo { +class SessionsCollection; + class MongoDSessionCatalog { public: /** @@ -62,6 +64,14 @@ public: */ static void invalidateSessions(OperationContext* opCtx, boost::optional<BSONObj> singleSessionDoc); + + /** + * Locates session entries from the in-memory catalog and in 'config.transactions' which have + * not been referenced before 'possiblyExpired' and deletes them. + */ + static int reapSessionsOlderThan(OperationContext* OperationContext, + SessionsCollection& sessionsCollection, + Date_t possiblyExpired); }; /** diff --git a/src/mongo/db/transaction_reaper_d_test.cpp b/src/mongo/db/session_catalog_mongod_test.cpp index 165ed3597a0..415e1e4ac07 100644 --- a/src/mongo/db/transaction_reaper_d_test.cpp +++ b/src/mongo/db/session_catalog_mongod_test.cpp @@ -32,15 +32,15 @@ #include "mongo/db/dbdirectclient.h" #include "mongo/db/repl/replication_coordinator_mock.h" #include "mongo/db/service_context_d_test_fixture.h" +#include "mongo/db/session_catalog_mongod.h" #include "mongo/db/session_txn_record_gen.h" #include "mongo/db/sessions_collection_mock.h" -#include "mongo/db/transaction_reaper_d.h" #include "mongo/util/clock_source_mock.h" namespace mongo { namespace { -class TransactionReaperTest : public ServiceContextMongoDTest { +class MongoDSessionCatalogTest : public ServiceContextMongoDTest { protected: void setUp() override { const auto service = getServiceContext(); @@ -65,7 +65,7 @@ protected: std::make_shared<MockSessionsCollection>(_collectionMock)}; }; -TEST_F(TransactionReaperTest, ReapSomeExpiredSomeNot) { +TEST_F(MongoDSessionCatalogTest, ReapSomeExpiredSomeNot) { // Create some "old" sessions DBDirectClient client(_opCtx); SessionTxnRecord txn1( @@ -81,9 +81,8 @@ TEST_F(TransactionReaperTest, ReapSomeExpiredSomeNot) { _collectionMock->add(LogicalSessionRecord(makeLogicalSessionIdForTest(), clock()->now())); _collectionMock->add(LogicalSessionRecord(makeLogicalSessionIdForTest(), clock()->now())); - ASSERT_EQ(2, - TransactionReaperD::reapSessionsOlderThan( + MongoDSessionCatalog::reapSessionsOlderThan( _opCtx, *_collection, clock()->now() - Minutes{30})); } diff --git a/src/mongo/db/transaction_reaper_d.cpp b/src/mongo/db/transaction_reaper_d.cpp deleted file mode 100644 index 1370c60c4f6..00000000000 --- a/src/mongo/db/transaction_reaper_d.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Copyright (C) 2019-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/db/transaction_reaper_d.h" - -#include "mongo/bson/bsonmisc.h" -#include "mongo/db/dbdirectclient.h" -#include "mongo/db/operation_context.h" -#include "mongo/db/ops/write_ops.h" -#include "mongo/db/session_txn_record_gen.h" -#include "mongo/db/sessions_collection.h" -#include "mongo/s/write_ops/batched_command_response.h" -#include "mongo/util/scopeguard.h" - -namespace mongo { -namespace { - -const auto kIdProjection = BSON(SessionTxnRecord::kSessionIdFieldName << 1); -const auto kSortById = BSON(SessionTxnRecord::kSessionIdFieldName << 1); -const auto kLastWriteDateFieldName = SessionTxnRecord::kLastWriteDateFieldName; - -/** - * Removes the specified set of session ids from the persistent sessions collection and returns the - * number of sessions actually removed. - */ -int removeSessionsTransactionRecords(OperationContext* opCtx, - SessionsCollection& sessionsCollection, - const LogicalSessionIdSet& sessionIdsToRemove) { - if (sessionIdsToRemove.empty()) { - return 0; - } - - // From the passed-in sessions, find the ones which are actually expired/removed - auto expiredSessionIds = - uassertStatusOK(sessionsCollection.findRemovedSessions(opCtx, sessionIdsToRemove)); - - write_ops::Delete deleteOp(NamespaceString::kSessionTransactionsTableNamespace); - deleteOp.setWriteCommandBase([] { - write_ops::WriteCommandBase base; - base.setOrdered(false); - return base; - }()); - deleteOp.setDeletes([&] { - std::vector<write_ops::DeleteOpEntry> entries; - for (auto it = expiredSessionIds.begin(); it != expiredSessionIds.end(); ++it) { - entries.emplace_back(BSON(LogicalSessionRecord::kIdFieldName << it->toBSON()), - false /* multi = false */); - } - return entries; - }()); - - BSONObj result; - - DBDirectClient client(opCtx); - client.runCommand(NamespaceString::kSessionTransactionsTableNamespace.db().toString(), - deleteOp.toBSON({}), - result); - - BatchedCommandResponse response; - std::string errmsg; - uassert(ErrorCodes::FailedToParse, - str::stream() << "Failed to parse response " << result, - response.parseBSON(result, &errmsg)); - uassertStatusOK(response.getTopLevelStatus()); - - return response.getN(); -} - -} // namespace - -int TransactionReaperD::reapSessionsOlderThan(OperationContext* opCtx, - SessionsCollection& sessionsCollection, - Date_t possiblyExpired) { - // Scan for records older than the minimum lifetime and uses a sort to walk the '_id' index - DBDirectClient client(opCtx); - auto cursor = - client.query(NamespaceString::kSessionTransactionsTableNamespace, - Query(BSON(kLastWriteDateFieldName << LT << possiblyExpired)).sort(kSortById), - 0, - 0, - &kIdProjection); - - // The max batch size is chosen so that a single batch won't exceed the 16MB BSON object - // size limit - LogicalSessionIdSet lsids; - const int kMaxBatchSize = 10'000; - - int numReaped = 0; - while (cursor->more()) { - auto transactionSession = SessionsCollectionFetchResultIndividualResult::parse( - "TransactionSession"_sd, cursor->next()); - - lsids.insert(transactionSession.get_id()); - if (lsids.size() > kMaxBatchSize) { - numReaped += removeSessionsTransactionRecords(opCtx, sessionsCollection, lsids); - lsids.clear(); - } - } - - numReaped += removeSessionsTransactionRecords(opCtx, sessionsCollection, lsids); - - return numReaped; -} - -} // namespace mongo diff --git a/src/mongo/db/transaction_reaper_d.h b/src/mongo/db/transaction_reaper_d.h deleted file mode 100644 index 057583b0ec9..00000000000 --- a/src/mongo/db/transaction_reaper_d.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (C) 2019-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include "mongo/util/time_support.h" - -namespace mongo { - -class SessionsCollection; -class OperationContext; - -class TransactionReaperD { -public: - static int reapSessionsOlderThan(OperationContext* OperationContext, - SessionsCollection& sessionsCollection, - Date_t possiblyExpired); -}; - -} // namespace mongo diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp index 6580faeb0c5..bbec88abfae 100644 --- a/src/mongo/s/server.cpp +++ b/src/mongo/s/server.cpp @@ -85,6 +85,7 @@ #include "mongo/s/query/cluster_cursor_cleanup_job.h" #include "mongo/s/query/cluster_cursor_manager.h" #include "mongo/s/service_entry_point_mongos.h" +#include "mongo/s/session_catalog_router.h" #include "mongo/s/sharding_egress_metadata_hook_for_mongos.h" #include "mongo/s/sharding_initialization.h" #include "mongo/s/sharding_uptime_reporter.h" @@ -500,13 +501,11 @@ ExitCode runMongosServer(ServiceContext* serviceContext) { SessionKiller::set(serviceContext, std::make_shared<SessionKiller>(serviceContext, killSessionsRemote)); - LogicalSessionCache::set(serviceContext, - stdx::make_unique<LogicalSessionCacheImpl>( - stdx::make_unique<ServiceLiaisonMongos>(), - stdx::make_unique<SessionsCollectionSharded>(), - [](OperationContext*, SessionsCollection&, Date_t) { - return 0; /* No op*/ - })); + LogicalSessionCache::set( + serviceContext, + stdx::make_unique<LogicalSessionCacheImpl>(stdx::make_unique<ServiceLiaisonMongos>(), + stdx::make_unique<SessionsCollectionSharded>(), + RouterSessionCatalog::reapSessionsOlderThan)); status = serviceContext->getServiceExecutor()->start(); if (!status.isOK()) { diff --git a/src/mongo/s/session_catalog_router.cpp b/src/mongo/s/session_catalog_router.cpp index dd514fb2a40..f88372078e4 100644 --- a/src/mongo/s/session_catalog_router.cpp +++ b/src/mongo/s/session_catalog_router.cpp @@ -35,6 +35,12 @@ namespace mongo { +int RouterSessionCatalog::reapSessionsOlderThan(OperationContext* OperationContext, + SessionsCollection& sessionsCollection, + Date_t possiblyExpired) { + return 0; +} + RouterOperationContextSession::RouterOperationContextSession(OperationContext* opCtx) : _operationContextSession(opCtx) {} diff --git a/src/mongo/s/session_catalog_router.h b/src/mongo/s/session_catalog_router.h index 10ddcc51ede..75a19324fd1 100644 --- a/src/mongo/s/session_catalog_router.h +++ b/src/mongo/s/session_catalog_router.h @@ -33,6 +33,19 @@ namespace mongo { +class SessionsCollection; + +class RouterSessionCatalog { +public: + /** + * Locates session entries from the in-memory catalog which have not been referenced before + * 'possiblyExpired' and deletes them. + */ + static int reapSessionsOlderThan(OperationContext* OperationContext, + SessionsCollection& sessionsCollection, + Date_t possiblyExpired); +}; + /** * Scoped object, which checks out the session specified in the passed operation context and stores * it for later access by the command. The session is installed at construction time and is removed |