summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Milkie <milkie@10gen.com>2014-09-23 14:45:08 -0400
committerEric Milkie <milkie@10gen.com>2014-09-24 13:39:30 -0400
commit03d22b14a74564e686fad7b75c093eaf8371321b (patch)
treecadf7a4a6cd4ef37a557c9bc0ce0977d7cb3724e
parentae200202f572851c22a82372b871f7981c8cea86 (diff)
downloadmongo-03d22b14a74564e686fad7b75c093eaf8371321b.tar.gz
SERVER-15089 add shouldChangeSyncSource() to topocoord
-rw-r--r--src/mongo/db/repl/topology_coordinator.h7
-rw-r--r--src/mongo/db/repl/topology_coordinator_impl.cpp39
-rw-r--r--src/mongo/db/repl/topology_coordinator_impl.h1
3 files changed, 47 insertions, 0 deletions
diff --git a/src/mongo/db/repl/topology_coordinator.h b/src/mongo/db/repl/topology_coordinator.h
index b26c0ab5198..29e8316257a 100644
--- a/src/mongo/db/repl/topology_coordinator.h
+++ b/src/mongo/db/repl/topology_coordinator.h
@@ -125,6 +125,13 @@ namespace repl {
virtual void blacklistSyncSource(const HostAndPort& host, Date_t until) = 0;
/**
+ * Determine if a new sync source should be chosen, if a better candidate sync source is
+ * available. If the current sync source's last optime is more than _maxSyncSourceLagSecs
+ * behind any syncable source, this function returns true.
+ */
+ virtual bool shouldChangeSyncSource(const HostAndPort& currentSource) const = 0;
+
+ /**
* Sets the earliest time the current node will stand for election to "newTime".
*
* Does not affect the node's state or the process of any elections in flight.
diff --git a/src/mongo/db/repl/topology_coordinator_impl.cpp b/src/mongo/db/repl/topology_coordinator_impl.cpp
index f8af3ae40f9..bce89586277 100644
--- a/src/mongo/db/repl/topology_coordinator_impl.cpp
+++ b/src/mongo/db/repl/topology_coordinator_impl.cpp
@@ -1562,5 +1562,44 @@ namespace {
return _maintenanceModeCalls;
}
+ bool TopologyCoordinatorImpl::shouldChangeSyncSource(const HostAndPort& currentSource) const
+ {
+ // Methodology:
+ // If there exists a viable sync source member other than currentSource, whose oplog has
+ // reached an optime greater than _maxSyncSourceLagSecs later than currentSource's, return
+ // true.
+ const int currentMemberIndex = findMemberIndexForHostAndPort(_currentConfig, currentSource);
+ if (currentMemberIndex == -1) {
+ return true;
+ }
+ OpTime currentOpTime = _hbdata[currentMemberIndex].getOpTime();
+ if (currentOpTime.isNull()) {
+ // Haven't received a heartbeat from the sync source yet, so can't tell if we should
+ // change.
+ return false;
+ }
+ unsigned int currentSecs = currentOpTime.getSecs();
+ unsigned int goalSecs = currentSecs + _maxSyncSourceLagSecs.total_seconds();
+
+ for (std::vector<MemberHeartbeatData>::const_iterator it = _hbdata.begin();
+ it != _hbdata.end();
+ ++it) {
+ const MemberConfig& candidateConfig = _currentConfig.getMemberAt(it->getConfigIndex());
+ if (it->up() &&
+ (candidateConfig.shouldBuildIndexes() || !_selfConfig().shouldBuildIndexes()) &&
+ it->getState().readable() &&
+ goalSecs < it->getOpTime().getSecs()) {
+ log() << "changing sync target because current sync target's most recent OpTime is "
+ << currentOpTime.toStringLong() << " which is more than "
+ << _maxSyncSourceLagSecs.total_seconds() << " seconds behind member "
+ << candidateConfig.getHostAndPort().toString()
+ << " whose most recent OpTime is " << it->getOpTime().toStringLong();
+ return true;
+ }
+ }
+ return false;
+ }
+
+
} // namespace repl
} // namespace mongo
diff --git a/src/mongo/db/repl/topology_coordinator_impl.h b/src/mongo/db/repl/topology_coordinator_impl.h
index b3f8087508c..6c21f246df6 100644
--- a/src/mongo/db/repl/topology_coordinator_impl.h
+++ b/src/mongo/db/repl/topology_coordinator_impl.h
@@ -130,6 +130,7 @@ namespace repl {
virtual HostAndPort chooseNewSyncSource(Date_t now,
const OpTime& lastOpApplied);
virtual void blacklistSyncSource(const HostAndPort& host, Date_t until);
+ virtual bool shouldChangeSyncSource(const HostAndPort& currentSource) const;
virtual void setStepDownTime(Date_t newTime);
virtual void setFollowerMode(MemberState::MS newMode);
virtual void adjustMaintenanceCountBy(int inc);