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-13 00:20:03 +0000
commit68bf17aa3b19d0b7f53b7a1b6fe1ebbafdf558d2 (patch)
treee9b5654498a7b850ee9b7f41cfc0342813163602
parent5fbb02045b2775ae69376c8c60bf20df90c99383 (diff)
downloadmongo-68bf17aa3b19d0b7f53b7a1b6fe1ebbafdf558d2.tar.gz
SERVER-53026 Fix "resync" command
(cherry picked from commit a574d23ec0b7d06b8d872bf64136308f541a796d)
-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 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)