@@ -1043,107 +1043,56 @@ HeartbeatResponseAction TopologyCoordinatorImpl::_updatePrimaryFromHBDataV1(
10431043 const MemberState& originalState,
10441044 Date_t now,
10451045 const OpTime& lastOpApplied) {
1046- // This method has two interrelated responsibilities, performed in two phases.
10471046 //
1048- // First, it updates the local notion of which remote node, if any is primary.
1047+ // Updates the local notion of which remote node, if any is primary.
1048+ // Start the priority takeover process if we are eligible.
10491049 //
1050- // Second, if there is no remote primary, and the local node is not primary, it considers
1051- // whether or not to stand for election.
1050+
10521051 invariant (updatedConfigIndex != _selfIndex);
10531052
1054- // We are missing from the config, so do not participate in primary maintenance or election.
1053+ // If we are missing from the config, do not participate in primary maintenance or election.
10551054 if (_selfIndex == -1 ) {
10561055 return HeartbeatResponseAction::makeNoAction ();
10571056 }
1058-
1059- // //////////////////
1060- // Phase 1
1061- // //////////////////
1062-
1063- // If we believe the node whose data was just updated is primary, confirm that
1064- // the updated data supports that notion. If not, erase our notion of who is primary.
1065- if (updatedConfigIndex == _currentPrimaryIndex) {
1066- const MemberHeartbeatData& updatedHBData = _hbdata[updatedConfigIndex];
1067- if (!updatedHBData.up () || !updatedHBData.getState ().primary ()) {
1068- _currentPrimaryIndex = -1 ;
1069- }
1057+ // If we are the primary, there must be no other primary, otherwise its higher term would
1058+ // have already made us step down.
1059+ if (_currentPrimaryIndex == _selfIndex) {
1060+ return HeartbeatResponseAction::makeNoAction ();
10701061 }
10711062
10721063 // Scan the member list's heartbeat data for who is primary, and update _currentPrimaryIndex.
1073- if (_currentPrimaryIndex != _selfIndex) {
1074- int remotePrimaryIndex = -1 ;
1075- for (std::vector<MemberHeartbeatData>::const_iterator it = _hbdata.begin ();
1076- it != _hbdata.end ();
1077- ++it) {
1078- const int itIndex = indexOfIterator (_hbdata, it);
1079- if (itIndex == _selfIndex) {
1080- continue ;
1081- }
1082-
1083- if (it->getState ().primary () && it->up ()) {
1084- if (remotePrimaryIndex == -1 ||
1085- _hbdata[remotePrimaryIndex].getTerm () < it->getTerm ()) {
1086- remotePrimaryIndex = itIndex;
1087- }
1064+ int primaryIndex = -1 ;
1065+ for (size_t i = 0 ; i < _hbdata.size (); i++) {
1066+ const MemberHeartbeatData& member = _hbdata[i];
1067+ if (member.getState ().primary () && member.up ()) {
1068+ if (primaryIndex == -1 || _hbdata[primaryIndex].getTerm () < member.getTerm ()) {
1069+ primaryIndex = i;
10881070 }
10891071 }
1090-
1091- if (remotePrimaryIndex != -1 ) {
1092- // Clear last heartbeat message on ourselves.
1093- setMyHeartbeatMessage (now, " " );
1094-
1095- _currentPrimaryIndex = remotePrimaryIndex;
1096-
1097- // Priority takeover when the replset is stable.
1098- //
1099- // Take over the primary only if the remote primary is in the latest term I know.
1100- // Otherwise, there must be an outstanding election, which may succeed or not, but
1101- // the remote primary will become aware of that election eventually and step down.
1102- if (_hbdata[remotePrimaryIndex].getTerm () == _term &&
1103- _rsConfig.getMemberAt (remotePrimaryIndex).getPriority () <
1104- _rsConfig.getMemberAt (_selfIndex).getPriority ()) {
1105- LOG (4 ) << " I can take over the primary due to higher priority."
1106- << " Current primary index: " << remotePrimaryIndex << " in term "
1107- << _hbdata[remotePrimaryIndex].getTerm ();
1108-
1109- return HeartbeatResponseAction::makePriorityTakeoverAction ();
1110- }
1111- return HeartbeatResponseAction::makeNoAction ();
1112- }
11131072 }
1114-
1115- // //////////////////
1116- // Phase 2
1117- // //////////////////
1118-
1119- // We do not believe any remote to be primary.
1120-
1121- // Return if we are primary. The stepdown decision is based on liveness rather than
1122- // heartbeats in pv 1.
1123- if (_iAmPrimary ()) {
1073+ _currentPrimaryIndex = primaryIndex;
1074+ if (_currentPrimaryIndex == -1 ) {
11241075 return HeartbeatResponseAction::makeNoAction ();
11251076 }
11261077
1127- fassert (28798 , _currentPrimaryIndex == -1 );
1078+ // Clear last heartbeat message on ourselves.
1079+ setMyHeartbeatMessage (now, " " );
11281080
1129- const MemberState currentState = getMemberState ();
1130- if (originalState.recovering () && currentState.secondary ()) {
1131- // We just transitioned from RECOVERING to SECONDARY, this can only happen if we
1132- // received a heartbeat with an auth error when previously all the heartbeats we'd
1133- // received had auth errors. In this case, don't return makeElectAction() because
1134- // that could cause the election to start before the ReplicationCoordinator has updated
1135- // its notion of the member state to SECONDARY. Instead return noAction so that the
1136- // ReplicationCoordinator knows to update its tracking of the member state off of the
1137- // TopologyCoordinator, and leave starting the election until the next heartbeat comes
1138- // back.
1139- return HeartbeatResponseAction::makeNoAction ();
1140- }
1141-
1142- // At this point, there is no primary anywhere. Check to see if we should become a candidate.
1143- if (!checkShouldStandForElection (now, lastOpApplied)) {
1144- return HeartbeatResponseAction::makeNoAction ();
1081+ // Priority takeover when the replset is stable.
1082+ //
1083+ // Take over the primary only if the remote primary is in the latest term I know.
1084+ // Otherwise, there must be an outstanding election, which may succeed or not, but
1085+ // the remote primary will become aware of that election eventually and step down.
1086+ if (_hbdata[primaryIndex].getTerm () == _term &&
1087+ _rsConfig.getMemberAt (primaryIndex).getPriority () <
1088+ _rsConfig.getMemberAt (_selfIndex).getPriority ()) {
1089+ LOG (4 ) << " I can take over the primary due to higher priority."
1090+ << " Current primary index: " << primaryIndex << " in term "
1091+ << _hbdata[primaryIndex].getTerm ();
1092+
1093+ return HeartbeatResponseAction::makePriorityTakeoverAction ();
11451094 }
1146- return HeartbeatResponseAction::makeScheduleElectionAction ();
1095+ return HeartbeatResponseAction::makeNoAction ();
11471096}
11481097
11491098HeartbeatResponseAction TopologyCoordinatorImpl::_updatePrimaryFromHBData (
0 commit comments