summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiyuan Zhou <siyuan.zhou@mongodb.com>2020-01-14 22:25:36 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-02-10 23:36:51 +0000
commit1191a063fd235df4ab23bb75e59eb1e530e2e93c (patch)
tree00f4d7b448b8063b644242cc9acda8b1117d0eac
parent4433187014909dc7e83849d7f32c082042b1b2bf (diff)
downloadmongo-1191a063fd235df4ab23bb75e59eb1e530e2e93c.tar.gz
SERVER-34768 Sync source's optime cannot be behind the syncing node even if chaining is disabled.
(cherry picked from commit 319757ebb72611fb91044a2a81d1b77a6f3729c1) SERVER-46050 Use getLastAppliedOpTime rather than getHeartbeatAppliedOpTime for checking primary's position.
-rw-r--r--src/mongo/db/repl/topology_coordinator.cpp9
-rw-r--r--src/mongo/db/repl/topology_coordinator_v1_test.cpp16
2 files changed, 25 insertions, 0 deletions
diff --git a/src/mongo/db/repl/topology_coordinator.cpp b/src/mongo/db/repl/topology_coordinator.cpp
index 841b3d42b7b..24abcf15c68 100644
--- a/src/mongo/db/repl/topology_coordinator.cpp
+++ b/src/mongo/db/repl/topology_coordinator.cpp
@@ -287,6 +287,15 @@ HostAndPort TopologyCoordinator::chooseNewSyncSource(Date_t now,
<< "Cannot select a sync source because chaining is not allowed and we are primary";
_syncSource = HostAndPort();
return _syncSource;
+ } else if (_memberData.at(_currentPrimaryIndex).getLastAppliedOpTime() <
+ lastOpTimeFetched) {
+ LOG(1) << "Cannot select a sync source because chaining is not allowed and the primary "
+ "is behind me. Last oplog optime of primary "
+ << _currentPrimaryMember()->getHostAndPort() << ": "
+ << _memberData.at(_currentPrimaryIndex).getLastAppliedOpTime().toBSON()
+ << ", my last fetched oplog optime: " << lastOpTimeFetched.toBSON();
+ _syncSource = HostAndPort();
+ return _syncSource;
} else {
_syncSource = _currentPrimaryMember()->getHostAndPort();
log() << "chaining not allowed, choosing primary as sync source candidate: "
diff --git a/src/mongo/db/repl/topology_coordinator_v1_test.cpp b/src/mongo/db/repl/topology_coordinator_v1_test.cpp
index c3d88099458..249b59f1eea 100644
--- a/src/mongo/db/repl/topology_coordinator_v1_test.cpp
+++ b/src/mongo/db/repl/topology_coordinator_v1_test.cpp
@@ -633,6 +633,22 @@ TEST_F(TopoCoordTest, ChooseOnlyPrimaryAsSyncSourceWhenChainingIsDisallowed) {
Milliseconds(300));
ASSERT_EQUALS(2, getCurrentPrimaryIndex());
+ // h3 is primary, but its last applied isn't as up-to-date as ours, so it cannot be chosen
+ // as the sync source.
+ ASSERT_EQUALS(HostAndPort(),
+ getTopoCoord().chooseNewSyncSource(
+ now()++,
+ OpTime(Timestamp(10, 0), 0),
+ TopologyCoordinator::ChainingPreference::kUseConfiguration));
+ ASSERT_EQUALS(HostAndPort(), getTopoCoord().getSyncSourceAddress());
+
+ // Update the primary's position.
+ heartbeatFromMember(HostAndPort("h3"),
+ "rs0",
+ MemberState::RS_PRIMARY,
+ OpTime(Timestamp(10, 0), 0),
+ Milliseconds(300));
+
// h3 is primary and should be chosen as the sync source when we are not in catch-up mode,
// despite being further away than h2 and the primary (h3) being behind our most recently
// applied optime.