diff options
author | William Schultz <william.schultz@mongodb.com> | 2017-06-02 16:58:37 -0400 |
---|---|---|
committer | William Schultz <william.schultz@mongodb.com> | 2017-06-08 18:19:40 -0400 |
commit | 1c56f5dd262111f921203d403f54fedb18772792 (patch) | |
tree | f10788ef94495fe6d3c6ef71f1eff77738f86c12 /src/mongo/db | |
parent | cce59be2127c2f30d9e98b895c9d79e0a3b2e157 (diff) | |
download | mongo-1c56f5dd262111f921203d403f54fedb18772792.tar.gz |
SERVER-28677 InitialSyncer should reset optimes on every attempt
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/repl/initial_syncer.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/repl/initial_syncer.h | 4 | ||||
-rw-r--r-- | src/mongo/db/repl/initial_syncer_test.cpp | 26 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl.cpp | 1 |
4 files changed, 36 insertions, 0 deletions
diff --git a/src/mongo/db/repl/initial_syncer.cpp b/src/mongo/db/repl/initial_syncer.cpp index 3923d3402b7..66742d8cada 100644 --- a/src/mongo/db/repl/initial_syncer.cpp +++ b/src/mongo/db/repl/initial_syncer.cpp @@ -218,6 +218,7 @@ InitialSyncer::InitialSyncer( uassert(ErrorCodes::BadValue, "invalid replication process", _replicationProcess); uassert(ErrorCodes::BadValue, "invalid getMyLastOptime function", _opts.getMyLastOptime); uassert(ErrorCodes::BadValue, "invalid setMyLastOptime function", _opts.setMyLastOptime); + uassert(ErrorCodes::BadValue, "invalid resetOptimes function", _opts.resetOptimes); uassert(ErrorCodes::BadValue, "invalid getSlaveDelay function", _opts.getSlaveDelay); uassert(ErrorCodes::BadValue, "invalid sync source selector", _opts.syncSourceSelector); uassert(ErrorCodes::BadValue, "callback function cannot be null", _onCompletion); @@ -447,8 +448,12 @@ void InitialSyncer::_startInitialSyncAttemptCallback( LOG(2) << "Resetting sync source so a new one can be chosen for this initial sync attempt."; _syncSource = HostAndPort(); + // Reset all optimes before a new initial sync attempt. + _opts.resetOptimes(); _lastApplied = {}; _lastFetched = {}; + + // Clear the oplog buffer. _oplogBuffer->clear(makeOpCtx().get()); // Get sync source. diff --git a/src/mongo/db/repl/initial_syncer.h b/src/mongo/db/repl/initial_syncer.h index b438a0c97e1..8ee406d8876 100644 --- a/src/mongo/db/repl/initial_syncer.h +++ b/src/mongo/db/repl/initial_syncer.h @@ -81,6 +81,9 @@ struct InitialSyncerOptions { /** Function to update optime of last operation applied on this node */ using SetMyLastOptimeFn = stdx::function<void(const OpTime&)>; + /** Function to reset all optimes on this node (e.g. applied & durable). */ + using ResetOptimesFn = stdx::function<void()>; + /** Function to sets this node into a specific follower mode. */ using SetFollowerModeFn = stdx::function<bool(const MemberState&)>; @@ -109,6 +112,7 @@ struct InitialSyncerOptions { GetMyLastOptimeFn getMyLastOptime; SetMyLastOptimeFn setMyLastOptime; + ResetOptimesFn resetOptimes; GetSlaveDelayFn getSlaveDelay; SyncSourceSelector* syncSourceSelector = nullptr; diff --git a/src/mongo/db/repl/initial_syncer_test.cpp b/src/mongo/db/repl/initial_syncer_test.cpp index 570c57840e5..c549bfbe391 100644 --- a/src/mongo/db/repl/initial_syncer_test.cpp +++ b/src/mongo/db/repl/initial_syncer_test.cpp @@ -293,6 +293,7 @@ protected: options.initialSyncRetryWait = Milliseconds(1); options.getMyLastOptime = [this]() { return _myLastOpTime; }; options.setMyLastOptime = [this](const OpTime& opTime) { _setMyLastOptime(opTime); }; + options.resetOptimes = [this]() { _setMyLastOptime(OpTime()); }; options.getSlaveDelay = [this]() { return Seconds(0); }; options.syncSourceSelector = this; @@ -526,6 +527,7 @@ TEST_F(InitialSyncerTest, InvalidConstruction) { InitialSyncerOptions options; options.getMyLastOptime = []() { return OpTime(); }; options.setMyLastOptime = [](const OpTime&) {}; + options.resetOptimes = []() {}; options.getSlaveDelay = []() { return Seconds(0); }; options.syncSourceSelector = this; auto callback = [](const StatusWith<OpTimeWithHash>&) {}; @@ -732,6 +734,30 @@ TEST_F(InitialSyncerTest, << progress; } +TEST_F(InitialSyncerTest, InitialSyncerResetsOptimesOnNewAttempt) { + auto initialSyncer = &getInitialSyncer(); + auto opCtx = makeOpCtx(); + + _syncSourceSelector->setChooseNewSyncSourceResult_forTest(HostAndPort()); + + const std::uint32_t initialSyncMaxAttempts = 1U; + ASSERT_OK(initialSyncer->startup(opCtx.get(), initialSyncMaxAttempts)); + + auto net = getNet(); + auto origOptime = OpTime(Timestamp(1000, 1), 1); + + _setMyLastOptime(origOptime); + + // Simulate a failed initial sync attempt + _simulateChooseSyncSourceFailure(net, _options.syncSourceRetryWait); + advanceClock(net, _options.initialSyncRetryWait); + + initialSyncer->join(); + + // Make sure the initial sync attempt reset optimes. + ASSERT_EQUALS(OpTime(), _options.getMyLastOptime()); +} + TEST_F(InitialSyncerTest, InitialSyncerReturnsCallbackCanceledIfShutdownWhileRetryingSyncSourceSelection) { auto initialSyncer = &getInitialSyncer(); diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index 1dbb34349bf..18121b41c07 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -265,6 +265,7 @@ InitialSyncerOptions createInitialSyncerOptions( replCoord->setMyLastAppliedOpTime(opTime); externalState->setGlobalTimestamp(replCoord->getServiceContext(), opTime.getTimestamp()); }; + options.resetOptimes = [replCoord]() { replCoord->resetMyLastOpTimes(); }; options.getSlaveDelay = [replCoord]() { return replCoord->getSlaveDelaySecs(); }; options.syncSourceSelector = replCoord; options.replBatchLimitBytes = dur::UncommittedBytesLimit; |