summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl
diff options
context:
space:
mode:
authorMatthew Russotto <matthew.russotto@mongodb.com>2022-05-18 14:36:27 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-06-01 15:47:09 +0000
commit0dae18bfa7ecba8820f032a0a53efa6cc02e4b0c (patch)
tree69a48b06fc0954c200bcf8286e8170a75a943594 /src/mongo/db/repl
parent52defdf7c5793de48a4aea976cc73569e83c2133 (diff)
downloadmongo-0dae18bfa7ecba8820f032a0a53efa6cc02e4b0c.tar.gz
SERVER-65671 Use _termShadow in updateTerm and processReplSetMetadata
Diffstat (limited to 'src/mongo/db/repl')
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp26
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.h7
2 files changed, 27 insertions, 6 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index ca7b9e692c7..5c1e3eb8778 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -3369,13 +3369,15 @@ void ReplicationCoordinatorImpl::processReplSetGetConfig(BSONObjBuilder* result,
void ReplicationCoordinatorImpl::processReplSetMetadata(const rpc::ReplSetMetadata& replMetadata) {
EventHandle evh;
- {
- stdx::lock_guard<Latch> lock(_mutex);
- evh = _processReplSetMetadata_inlock(replMetadata);
- }
+ if (_needToUpdateTerm(replMetadata.getTerm())) {
+ {
+ stdx::lock_guard<Latch> lock(_mutex);
+ evh = _processReplSetMetadata_inlock(replMetadata);
+ }
- if (evh) {
- _replExecutor->waitForEvent(evh);
+ if (evh) {
+ _replExecutor->waitForEvent(evh);
+ }
}
}
@@ -3386,6 +3388,9 @@ void ReplicationCoordinatorImpl::cancelAndRescheduleElectionTimeout() {
EventHandle ReplicationCoordinatorImpl::_processReplSetMetadata_inlock(
const rpc::ReplSetMetadata& replMetadata) {
+ // Note that public method processReplSetMetadata() above depends on this method not needing
+ // to do anything when the term is up to date. If that changes, be sure to update that
+ // method as well.
return _updateTerm_inlock(replMetadata.getTerm());
}
@@ -5902,6 +5907,11 @@ Status ReplicationCoordinatorImpl::updateTerm(OperationContext* opCtx, long long
// Check we haven't acquired any lock, because potential stepdown needs global lock.
dassert(!opCtx->lockState()->isLocked() || opCtx->lockState()->isNoop());
+
+ // If the term is already up to date, we can skip the update and the mutex acquisition.
+ if (!_needToUpdateTerm(term))
+ return Status::OK();
+
TopologyCoordinator::UpdateTermResult updateTermResult;
EventHandle finishEvh;
@@ -5923,6 +5933,10 @@ Status ReplicationCoordinatorImpl::updateTerm(OperationContext* opCtx, long long
return Status::OK();
}
+bool ReplicationCoordinatorImpl::_needToUpdateTerm(long long term) {
+ return term > _termShadow.load();
+}
+
EventHandle ReplicationCoordinatorImpl::_updateTerm_inlock(
long long term, TopologyCoordinator::UpdateTermResult* updateTermResult) {
diff --git a/src/mongo/db/repl/replication_coordinator_impl.h b/src/mongo/db/repl/replication_coordinator_impl.h
index 7c6a70868e0..a6dc8fe9066 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.h
+++ b/src/mongo/db/repl/replication_coordinator_impl.h
@@ -1434,6 +1434,13 @@ private:
*/
void _updateLastCommittedOpTimeAndWallTime(WithLock lk);
+ /** Terms only increase, so if an incoming term is less than or equal to our
+ * current term (_termShadow), there is no need to take the mutex and call _updateTerm_inlock.
+ * Since _termShadow may be lagged, this may return true when the term does not need to be
+ * updated, which is harmless because _updateTerm_inlock will do nothing in that case.
+ */
+ bool _needToUpdateTerm(long long term);
+
/**
* Callback that attempts to set the current term in topology coordinator and
* relinquishes primary if the term actually changes and we are primary.