diff options
Diffstat (limited to 'src/mongo/db/repl/topology_coordinator_impl.cpp')
-rw-r--r-- | src/mongo/db/repl/topology_coordinator_impl.cpp | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/src/mongo/db/repl/topology_coordinator_impl.cpp b/src/mongo/db/repl/topology_coordinator_impl.cpp index e245ddb3276..afd720d7869 100644 --- a/src/mongo/db/repl/topology_coordinator_impl.cpp +++ b/src/mongo/db/repl/topology_coordinator_impl.cpp @@ -2228,24 +2228,37 @@ void TopologyCoordinatorImpl::processLoseElection() { } } -bool TopologyCoordinatorImpl::stepDown(Date_t until, bool force, const OpTime& lastOpApplied) { - bool canStepDown = force; - for (int i = 0; !canStepDown && i < _rsConfig.getNumMembers(); ++i) { - if (i == _selfIndex) { - continue; - } - UnelectableReasonMask reason = _getUnelectableReason(i, lastOpApplied); - if (!reason && _hbdata[i].getAppliedOpTime() >= lastOpApplied) { - canStepDown = true; - } +bool TopologyCoordinatorImpl::stepDown(Date_t until, + bool force, + const OpTime& lastOpApplied, + const OpTime& lastOpCommitted) { + // force==true overrides all other checks. + if (force) { + _stepDownUntil = until; + _stepDownSelfAndReplaceWith(-1); + return true; } - if (!canStepDown) { + // Ensure a majority of caught up nodes. + if (lastOpCommitted < lastOpApplied) { return false; } - _stepDownUntil = until; - _stepDownSelfAndReplaceWith(-1); - return true; + + // Now make sure we also have at least one caught up node that is also electable. + for (int memberIndex = 0; memberIndex < _rsConfig.getNumMembers(); memberIndex++) { + // ignore your self + if (memberIndex == _selfIndex) { + continue; + } + UnelectableReasonMask reason = _getUnelectableReason(memberIndex, lastOpApplied); + if (!reason && _hbdata.at(memberIndex).getAppliedOpTime() >= lastOpApplied) { + // Found a caught up and electable node, succeed with step down. + _stepDownUntil = until; + _stepDownSelfAndReplaceWith(-1); + return true; + } + } + return false; } void TopologyCoordinatorImpl::setFollowerMode(MemberState::MS newMode) { |