summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorWilliam Schultz <william.schultz@mongodb.com>2017-06-02 16:58:37 -0400
committerWilliam Schultz <william.schultz@mongodb.com>2017-06-08 18:19:40 -0400
commit1c56f5dd262111f921203d403f54fedb18772792 (patch)
treef10788ef94495fe6d3c6ef71f1eff77738f86c12 /src/mongo/db
parentcce59be2127c2f30d9e98b895c9d79e0a3b2e157 (diff)
downloadmongo-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.cpp5
-rw-r--r--src/mongo/db/repl/initial_syncer.h4
-rw-r--r--src/mongo/db/repl/initial_syncer_test.cpp26
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp1
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;