summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Jesse Jiryu Davis <jesse@mongodb.com>2020-12-02 13:52:21 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-12-02 19:03:28 +0000
commita574d23ec0b7d06b8d872bf64136308f541a796d (patch)
treebcaf115cef814544a76cc6d845ab5d645439db8d
parent28bd503024df528e29ea07f5d966411b15db2be8 (diff)
downloadmongo-a574d23ec0b7d06b8d872bf64136308f541a796d.tar.gz
SERVER-53026 Fix "resync" command
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp20
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.h3
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 22699a68a6f..fdc10af2565 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -633,6 +633,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) {
@@ -652,20 +657,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();
invariantOK(setFollowerMode(MemberState::RS_RECOVERING));
_externalState->startSteadyStateReplication(opCtx, this);
return;
@@ -719,8 +728,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);
initialSyncerCopy = std::make_shared<InitialSyncer>(
createInitialSyncerOptions(this, _externalState.get()),
stdx::make_unique<DataReplicatorExternalStateInitialSync>(this,
@@ -732,6 +739,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 105269b8855..cd690f6d4df 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.h
+++ b/src/mongo/db/repl/replication_coordinator_impl.h
@@ -1383,7 +1383,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)