summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Mulrow <jack.mulrow@mongodb.com>2022-06-02 16:29:52 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-06-02 19:21:50 +0000
commit5fc426665b3579c7ed58d6db2eb64279d7ae34e6 (patch)
tree84d0633b9ea722a88b32e4ef2db2891a3511303e
parentdb3dfc6264a06cc5bde900b0756eb1150827a949 (diff)
downloadmongo-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.h9
-rw-r--r--src/mongo/db/session_catalog.cpp2
-rw-r--r--src/mongo/db/transaction_participant.cpp20
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});
}