diff options
author | Eric Milkie <milkie@10gen.com> | 2014-09-23 14:45:08 -0400 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2014-09-24 13:39:30 -0400 |
commit | 03d22b14a74564e686fad7b75c093eaf8371321b (patch) | |
tree | cadf7a4a6cd4ef37a557c9bc0ce0977d7cb3724e | |
parent | ae200202f572851c22a82372b871f7981c8cea86 (diff) | |
download | mongo-03d22b14a74564e686fad7b75c093eaf8371321b.tar.gz |
SERVER-15089 add shouldChangeSyncSource() to topocoord
-rw-r--r-- | src/mongo/db/repl/topology_coordinator.h | 7 | ||||
-rw-r--r-- | src/mongo/db/repl/topology_coordinator_impl.cpp | 39 | ||||
-rw-r--r-- | src/mongo/db/repl/topology_coordinator_impl.h | 1 |
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); |