diff options
author | Xuerui Fa <xuerui.fa@mongodb.com> | 2020-05-18 18:06:04 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-05-18 22:29:48 +0000 |
commit | b3148d848547358244f055b25cbabe147f244a43 (patch) | |
tree | 03813b26ee13aaa1d1b10e097f34bf6bb2dc464b | |
parent | 2153f72a96906ec4ca30e45fc21f68008aa08d73 (diff) | |
download | mongo-b3148d848547358244f055b25cbabe147f244a43.tar.gz |
SERVER-47454: Stop re-evaluting sync source if max num changes was exceeded
-rw-r--r-- | src/mongo/db/repl/topology_coordinator.cpp | 17 | ||||
-rw-r--r-- | src/mongo/db/repl/topology_coordinator.h | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/topology_coordinator_v1_test.cpp | 51 |
3 files changed, 63 insertions, 7 deletions
diff --git a/src/mongo/db/repl/topology_coordinator.cpp b/src/mongo/db/repl/topology_coordinator.cpp index bbe49703822..5159d57b1f7 100644 --- a/src/mongo/db/repl/topology_coordinator.cpp +++ b/src/mongo/db/repl/topology_coordinator.cpp @@ -3033,12 +3033,11 @@ bool TopologyCoordinator::shouldChangeSyncSource(const HostAndPort& currentSourc return false; } -bool TopologyCoordinator::shouldChangeSyncSourceDueToPingTime( - const HostAndPort& currentSource, - const MemberState& memberState, - const OpTime& lastOpTimeFetched, - Date_t now, - const ReadPreference readPreference) const { +bool TopologyCoordinator::shouldChangeSyncSourceDueToPingTime(const HostAndPort& currentSource, + const MemberState& memberState, + const OpTime& lastOpTimeFetched, + Date_t now, + const ReadPreference readPreference) { // If the ping time for currentSource is longer than 'changeSyncSourceThresholdMillis' and we // find an eligible sync source that has a ping time shorter than // 'changeSyncSourceThresholdMillis', return true. @@ -3054,6 +3053,12 @@ bool TopologyCoordinator::shouldChangeSyncSourceDueToPingTime( return false; } + // If we have already changed sync sources more than 'maxNumSyncSourceChangesPerHour' in the + // past hour, do not re-evaluate our sync source. + if (_recentSyncSourceChanges.changedTooOftenRecently(now)) { + return false; + } + const bool primaryOnly = (readPreference == ReadPreference::PrimaryOnly); const bool primaryPreferredAndAlreadySyncing = (readPreference == ReadPreference::PrimaryPreferred && diff --git a/src/mongo/db/repl/topology_coordinator.h b/src/mongo/db/repl/topology_coordinator.h index 56ec2fd881b..87aacd5aa12 100644 --- a/src/mongo/db/repl/topology_coordinator.h +++ b/src/mongo/db/repl/topology_coordinator.h @@ -279,7 +279,7 @@ public: const MemberState& memberState, const OpTime& lastOpTimeFetched, Date_t now, - const ReadPreference readPreference) const; + const ReadPreference readPreference); /** * Sets the reported mode of this node to one of RS_SECONDARY, RS_STARTUP2, RS_ROLLBACK or diff --git a/src/mongo/db/repl/topology_coordinator_v1_test.cpp b/src/mongo/db/repl/topology_coordinator_v1_test.cpp index 302de461df1..d28062c4fb6 100644 --- a/src/mongo/db/repl/topology_coordinator_v1_test.cpp +++ b/src/mongo/db/repl/topology_coordinator_v1_test.cpp @@ -4362,6 +4362,57 @@ TEST_F(ReevalSyncSourceTest, NoChangeWhenNodeNotFoundInConfig) { ReadPreference::Nearest)); } +TEST_F(ReevalSyncSourceTest, NoChangeWhenChangedTooManyTimesRecently) { + getTopoCoord().setPing_forTest(HostAndPort("host2"), pingTimeAboveThreshold); + getTopoCoord().setPing_forTest(HostAndPort("host3"), pingTimeBelowThreshold); + + auto recentSyncSourceChanges = getTopoCoord().getRecentSyncSourceChanges_forTest(); + + auto first = Date_t::now(); + recentSyncSourceChanges->addNewEntry(first); + + auto second = Date_t::now(); + recentSyncSourceChanges->addNewEntry(second); + + auto third = Date_t::now(); + recentSyncSourceChanges->addNewEntry(third); + + assertTimesEqual({first, second, third}, recentSyncSourceChanges->getChanges_forTest()); + ASSERT_TRUE(recentSyncSourceChanges->changedTooOftenRecently(now())); + + // We should not change sync sources because we have already changed sync sources more than + // 'maxNumSyncSourceChangesPerHour' in the past hour. + ASSERT_FALSE(getTopoCoord().shouldChangeSyncSourceDueToPingTime(HostAndPort("host2"), + MemberState::RS_SECONDARY, + lastOpTimeFetched, + now(), + ReadPreference::Nearest)); +} + +TEST_F(ReevalSyncSourceTest, ChangeWhenHaveNotChangedTooManyTimesRecently) { + getTopoCoord().setPing_forTest(HostAndPort("host2"), pingTimeAboveThreshold); + getTopoCoord().setPing_forTest(HostAndPort("host3"), pingTimeBelowThreshold); + + auto recentSyncSourceChanges = getTopoCoord().getRecentSyncSourceChanges_forTest(); + + auto first = Date_t::now(); + recentSyncSourceChanges->addNewEntry(first); + + auto second = Date_t::now(); + recentSyncSourceChanges->addNewEntry(second); + + assertTimesEqual({first, second}, recentSyncSourceChanges->getChanges_forTest()); + ASSERT_FALSE(recentSyncSourceChanges->changedTooOftenRecently(now())); + + // We should allow changing sync sources because we have not yet changed sync sources more times + // than 'maxNumSyncSourceChangesPerHour' in the past hour. + ASSERT_TRUE(getTopoCoord().shouldChangeSyncSourceDueToPingTime(HostAndPort("host2"), + MemberState::RS_SECONDARY, + lastOpTimeFetched, + now(), + ReadPreference::Nearest)); +} + class HeartbeatResponseReconfigTestV1 : public TopoCoordTest { public: virtual void setUp() { |