diff options
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl.cpp | 20 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl.h | 3 |
2 files changed, 16 insertions, 7 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index 7d7ac4a76c6..1e0f241e738 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -651,6 +651,11 @@ void ReplicationCoordinatorImpl::_stopDataReplication(OperationContext* opCtx) { std::shared_ptr<InitialSyncer> initialSyncerCopy; { stdx::lock_guard<stdx::mutex> lk(_mutex); + if (!_startedSteadyStateReplication) { + return; + } + + _startedSteadyStateReplication = false; _initialSyncer.swap(initialSyncerCopy); } if (initialSyncerCopy) { @@ -670,20 +675,24 @@ void ReplicationCoordinatorImpl::_stopDataReplication(OperationContext* opCtx) { void ReplicationCoordinatorImpl::_startDataReplication(OperationContext* opCtx, stdx::function<void()> startCompleted) { - if (_startedSteadyStateReplication.swap(true)) { - // This is not the first call. + stdx::unique_lock<stdx::mutex> lk(_mutex); + if (_startedSteadyStateReplication) { return; } + _startedSteadyStateReplication = true; + // Check to see if we need to do an initial sync. - const auto lastOpTime = getMyLastAppliedOpTime(); + const auto lastOpTime = _getMyLastAppliedOpTime_inlock(); const auto needsInitialSync = lastOpTime.isNull() || _externalState->isInitialSyncFlagSet(opCtx); if (!needsInitialSync) { // Start steady replication, since we already have data. // ReplSetConfig has been installed, so it's either in STARTUP2 or REMOVED. - auto memberState = getMemberState(); + auto memberState = _getMemberState_inlock(); invariant(memberState.startup2() || memberState.removed()); + + lk.unlock(); invariant(setFollowerMode(MemberState::RS_RECOVERING)); _externalState->startSteadyStateReplication(opCtx, this); return; @@ -737,8 +746,6 @@ void ReplicationCoordinatorImpl::_startDataReplication(OperationContext* opCtx, std::shared_ptr<InitialSyncer> initialSyncerCopy; try { { - // Must take the lock to set _initialSyncer, but not call it. - stdx::lock_guard<stdx::mutex> lock(_mutex); if (_inShutdown) { log() << "Initial Sync not starting because replication is shutting down."; return; @@ -755,6 +762,7 @@ void ReplicationCoordinatorImpl::_startDataReplication(OperationContext* opCtx, } // InitialSyncer::startup() must be called outside lock because it uses features (eg. // setting the initial sync flag) which depend on the ReplicationCoordinatorImpl. + lk.unlock(); uassertStatusOK(initialSyncerCopy->startup(opCtx, numInitialSyncAttempts.load())); } catch (...) { auto status = exceptionToStatus(); diff --git a/src/mongo/db/repl/replication_coordinator_impl.h b/src/mongo/db/repl/replication_coordinator_impl.h index 6eddad07885..0056f8658bc 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.h +++ b/src/mongo/db/repl/replication_coordinator_impl.h @@ -1372,7 +1372,8 @@ private: // here so we can update our term to match as part of finishing stepdown. boost::optional<long long> _pendingTermUpdateDuringStepDown; // (M) - AtomicWord<bool> _startedSteadyStateReplication{false}; + // Whether data replication is active. + bool _startedSteadyStateReplication = false; // (M) // If we're in terminal shutdown. If true, we'll refuse to vote in elections. bool _inTerminalShutdown = false; // (M) |