diff options
author | Eric Milkie <milkie@10gen.com> | 2017-11-10 11:12:23 -0500 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2017-11-13 12:54:15 -0500 |
commit | 9fbb130337619500dfe153bf3fc856d1852cc0ce (patch) | |
tree | ff3506b210c54eb455da08f794e38b2b3b3bdbe8 | |
parent | 9a1f209aa8e47587af6ad81e991b101abea1f677 (diff) | |
download | mongo-9fbb130337619500dfe153bf3fc856d1852cc0ce.tar.gz |
SERVER-31899 make getTerm() use an Atomic rather than lock the replcoord mutex
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl.h | 6 |
2 files changed, 15 insertions, 2 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index 27a8a17e028..27a10f50e1b 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -354,6 +354,8 @@ ReplicationCoordinatorImpl::ReplicationCoordinatorImpl( _storage(storage), _random(prngSeed) { + _termShadow.store(OpTime::kUninitializedTerm); + invariant(_service); if (!isReplEnabled()) { @@ -2825,6 +2827,10 @@ ReplicationCoordinatorImpl::_setCurrentRSConfig_inlock(OperationContext* opCtx, _setConfigState_inlock(kConfigSteady); _topCoord->updateConfig(newConfig, myIndex, _replExecutor->now()); + + // updateConfig() can change terms, so update our term shadow to match. + _termShadow.store(_topCoord->getTerm()); + const ReplSetConfig oldConfig = _rsConfig; _rsConfig = newConfig; _protVersion.store(_rsConfig.getProtocolVersion()); @@ -3384,8 +3390,8 @@ void ReplicationCoordinatorImpl::summarizeAsHtml(ReplSetHtmlSummary* output) { } long long ReplicationCoordinatorImpl::getTerm() { - stdx::lock_guard<stdx::mutex> lock(_mutex); - return _topCoord->getTerm(); + // Note: no mutex acquisition here, as we are reading an Atomic variable. + return _termShadow.load(); } EventHandle ReplicationCoordinatorImpl::updateTerm_forTest( @@ -3447,6 +3453,7 @@ EventHandle ReplicationCoordinatorImpl::_updateTerm_inlock( TopologyCoordinator::UpdateTermResult localUpdateTermResult = _topCoord->updateTerm(term, now); { if (localUpdateTermResult == TopologyCoordinator::UpdateTermResult::kUpdatedTerm) { + _termShadow.store(term); _cancelPriorityTakeover_inlock(); _cancelAndRescheduleElectionTimeout_inlock(); } diff --git a/src/mongo/db/repl/replication_coordinator_impl.h b/src/mongo/db/repl/replication_coordinator_impl.h index bacbfda9fe3..69b57830d69 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.h +++ b/src/mongo/db/repl/replication_coordinator_impl.h @@ -1341,6 +1341,12 @@ private: // The catchup state including all catchup logic. The presence of a non-null pointer indicates // that the node is currently in catchup mode. std::unique_ptr<CatchupState> _catchupState; // (X) + + // Atomic-synchronized copy of Topology Coordinator's _term, for use by the public getTerm() + // function. + // This variable must be written immediately after _term, and thus its value can lag. + // Reading this value does not require the replication coordinator mutex to be locked. + AtomicInt64 _termShadow; // (S) }; } // namespace repl |