[SERVER-46354] Abstract away 'votes' and 'newlyAdded' fields so it is impossible to mis-count votes Created: 24/Feb/20  Updated: 27/Oct/23  Resolved: 10/Jun/20

Status: Closed
Project: Core Server
Component/s: Replication
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Judah Schvimer Assignee: Vesselina Ratcheva (Inactive)
Resolution: Gone away Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Sprint: Repl 2020-05-18, Repl 2020-06-15
Participants:

 Description   

Otherwise it would be easy to incorrectly calculate the majority number of the replica set by not considering the ‘newlyAdded’ field.



 Comments   
Comment by Vesselina Ratcheva (Inactive) [ 10/Jun/20 ]

I concluded that no changes are needed here, as SERVER-47091 managed to tighten things a lot here and there are no longer any ways to miscalculate votes.

In order to find out if an individual node is voting or not, we use either either the isVoter or the getNumVotes (one uses the other, and the only real difference is that one returns a bool and the other an int). For purposes like write concern satisfiability, we use tags. There was a point where we weren't updating the tags along with changes to newlyAdded (SERVER-47499), but that was fixed in SERVER-47091. The $voter and $configVoter tags themselves uses isVoter (see https://github.com/mongodb/mongo/blob/ad170b9f34c828ec25404f600e95416639e1fecd/src/mongo/db/repl/member_config.cpp#L144-L162).

The MemberConfig class also has a getNewlyAdded() method, but it is not used outside of it.

I went through and enumerated/audited all places that I could think of that need some sort of voter check or count. All of them are using the above methods (or derivatives).

ReplSetConfig:

  • validate: uses isVoter
  • checkIfWriteConcernCanBeSatisfied: uses tags
  • _calculateMajorities: uses isVoter, results exposed in the voter count methods we know and love:
    • getMajorityVoteCount()
    • getWriteMajority()
    • getTotalVotingMembers()
    • getWritableVotingMembersCount()
  • _addInternalWriteConcernModes: uses tags
  • votingMembers: uses getNumVotes

repl_set_config_checks.cpp:

  • validateSingleNodeChange: uses ReplSetConfig::votingMembers() (which uses getNumVotes)

QuorumChecker:

  • constructor: uses isVoter to populate _voters, which is read throughout the file
  • _tabulateHeartbeatResponse: same as above
  • hasReceivedSufficientResponses: uses _voters

VoteRequester:

  • Algorithm (constructor): uses isVoter to populate _targets, which is read throughout the file

TopologyCoordinator: (too many to enumerate, so I'm summarizing some of those)

  • _aMajoritySeemsToBeUp: uses getNumVotes
  • prepareStatusResponse: uses the four counter methods listed above
  • a few other instances of those
  • the rest use isVoter

ReplicationCoordinator:

  • processReplSetReconfig: uses isVoter
  • doReplSetReconfig: uses isVoter
  • various read/write concern functions that (now) all use tags
  • a few instances of the four horsemen of vote counting
Generated at Thu Feb 08 05:11:14 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.