diff options
author | Jack Mulrow <jack.mulrow@mongodb.com> | 2022-06-02 16:29:52 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-06-02 19:21:50 +0000 |
commit | 5fc426665b3579c7ed58d6db2eb64279d7ae34e6 (patch) | |
tree | 84d0633b9ea722a88b32e4ef2db2891a3511303e | |
parent | db3dfc6264a06cc5bde900b0756eb1150827a949 (diff) | |
download | mongo-5fc426665b3579c7ed58d6db2eb64279d7ae34e6.tar.gz |
SERVER-66960 Cache highest child txnNumber on checked out sessions
(cherry picked from commit b2f773225a555d581e547527a8cb67bdeed7fadc)
-rw-r--r-- | src/mongo/db/session.h | 9 | ||||
-rw-r--r-- | src/mongo/db/session_catalog.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/transaction_participant.cpp | 20 |
3 files changed, 19 insertions, 12 deletions
diff --git a/src/mongo/db/session.h b/src/mongo/db/session.h index 256f7ff28b1..14b6a9839ef 100644 --- a/src/mongo/db/session.h +++ b/src/mongo/db/session.h @@ -62,6 +62,10 @@ public: return _parentSession; } + int getCachedHighestTxnNumberWithChildSessions() { + return _cachedHighestTxnNumberWithChildSessions; + } + private: // The session id of the transaction session that this object represents. const LogicalSessionId _sessionId; @@ -74,6 +78,11 @@ private: // Counts how many threads are blocked waiting for this Session to become available. Used to // block reaping of this Session from the SessionCatalog. int _numWaitingToCheckOut{0}; + + // Cache of the highest txnNumber on seen on a child session for this session's logical session. + // Cached to avoid taking the session catalog mutex to read and because this is only best + // effort to minimize sessions read when refreshing a transaction participant. + int _cachedHighestTxnNumberWithChildSessions{kUninitializedTxnNumber}; }; } // namespace mongo diff --git a/src/mongo/db/session_catalog.cpp b/src/mongo/db/session_catalog.cpp index bc5b97b8566..032e9d8b90e 100644 --- a/src/mongo/db/session_catalog.cpp +++ b/src/mongo/db/session_catalog.cpp @@ -105,6 +105,7 @@ SessionCatalog::ScopedCheckedOutSession SessionCatalog::_checkOutSessionInner( sri->checkoutOpCtx = opCtx; sri->lastCheckout = Date_t::now(); + session->_cachedHighestTxnNumberWithChildSessions = sri->highestTxnNumberWithChildSessions; return ScopedCheckedOutSession(*this, std::move(sri), session, std::move(killToken)); } @@ -321,6 +322,7 @@ void SessionCatalog::_releaseSession(SessionRuntimeInfo* sri, } sri->checkoutOpCtx = nullptr; + session->_cachedHighestTxnNumberWithChildSessions = kUninitializedTxnNumber; sri->availableCondVar.notify_all(); if (killToken) { diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp index d7f95a93fa9..6aba931a08b 100644 --- a/src/mongo/db/transaction_participant.cpp +++ b/src/mongo/db/transaction_participant.cpp @@ -334,14 +334,8 @@ ActiveTransactionHistory fetchActiveTransactionHistory(OperationContext* opCtx, * found in the session catalog and the config.transactions collection. */ TxnNumber fetchHighestTxnNumberWithInternalSessions(OperationContext* opCtx, - const LogicalSessionId& parentLsid) { - TxnNumber highestTxnNumber{kUninitializedTxnNumber}; - - const auto sessionCatalog = SessionCatalog::get(opCtx); - sessionCatalog->scanSession(parentLsid, [&](const ObservableSession& osession) { - highestTxnNumber = osession.getHighestTxnNumberWithChildSessions(); - }); - + const LogicalSessionId& parentLsid, + TxnNumber cachedHighestTxnNumber) { try { performReadWithNoTimestampDBDirectClient(opCtx, [&](DBDirectClient* client) { FindCommandRequest findRequest{NamespaceString::kSessionTransactionsTableNamespace}; @@ -349,7 +343,7 @@ TxnNumber fetchHighestTxnNumberWithInternalSessions(OperationContext* opCtx, << parentLsid.toBSON() << (SessionTxnRecord::kSessionIdFieldName + "." + LogicalSessionId::kTxnNumberFieldName) - << BSON("$gte" << highestTxnNumber))); + << BSON("$gte" << cachedHighestTxnNumber))); findRequest.setSort(BSON((SessionTxnRecord::kSessionIdFieldName + "." + LogicalSessionId::kTxnNumberFieldName) << -1)); @@ -363,7 +357,8 @@ TxnNumber fetchHighestTxnNumberWithInternalSessions(OperationContext* opCtx, const auto doc = cursor->next(); const auto childLsid = LogicalSessionId::parse( IDLParserErrorContext("LogicalSessionId"), doc.getObjectField("_id")); - highestTxnNumber = std::max(highestTxnNumber, *childLsid.getTxnNumber()); + cachedHighestTxnNumber = + std::max(cachedHighestTxnNumber, *childLsid.getTxnNumber()); invariant(!cursor->more()); } }); @@ -372,7 +367,7 @@ TxnNumber fetchHighestTxnNumberWithInternalSessions(OperationContext* opCtx, throw; } - return highestTxnNumber; + return cachedHighestTxnNumber; } void updateSessionEntry(OperationContext* opCtx, @@ -2857,7 +2852,8 @@ void TransactionParticipant::Participant::_refreshSelfFromStorageIfNeeded(Operat if (feature_flags::gFeatureFlagInternalTransactions.isEnabled( serverGlobalParams.featureCompatibility) && !_isInternalSession()) { - const auto txnNumber = fetchHighestTxnNumberWithInternalSessions(opCtx, _sessionId()); + const auto txnNumber = fetchHighestTxnNumberWithInternalSessions( + opCtx, _sessionId(), _session()->getCachedHighestTxnNumberWithChildSessions()); if (txnNumber > o().activeTxnNumberAndRetryCounter.getTxnNumber()) { _setNewTxnNumberAndRetryCounter(opCtx, {txnNumber, kUninitializedTxnRetryCounter}); } |