From be0eb178a1c599497a307a5b114d112343fab9c1 Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Tue, 21 Apr 2020 18:43:41 -0400 Subject: SERVER-47613 Fix invariant when a removed member votes (cherry picked from commit cc814e4c87c1ae20ef7c0840344496043dbdf18d) --- src/mongo/db/repl/replication_coordinator_impl.cpp | 5 +++ .../db/repl/replication_coordinator_impl_test.cpp | 42 +++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index ebf06782013..6f6394c43eb 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -3506,6 +3506,11 @@ Status ReplicationCoordinatorImpl::processReplSetRequestVotes( return Status(ErrorCodes::ShutdownInProgress, "In the process of shutting down"); } + if (_selfIndex == -1) { + return Status(ErrorCodes::InvalidReplicaSetConfig, + "Invalid replica set config, or this node is not a member"); + } + _topCoord->processReplSetRequestVotes(args, response); } diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp index e4f6bca7fed..987f38392a2 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp @@ -6138,7 +6138,7 @@ TEST_F(ReplCoordTest, NodeFailsVoteRequestIfItFailsToStoreLastVote) { ASSERT_EQUALS(lastVote.getCandidateIndex(), 0); } -TEST_F(ReplCoordTest, NodeNodesNotGrantVoteIfInTerminalShutdown) { +TEST_F(ReplCoordTest, NodeDoesNotGrantVoteIfInTerminalShutdown) { // Set up a 2-node replica set config. assertStartSuccess(BSON("_id" << "mySet" @@ -6190,6 +6190,46 @@ TEST_F(ReplCoordTest, NodeNodesNotGrantVoteIfInTerminalShutdown) { ASSERT_EQUALS(ErrorCodes::ShutdownInProgress, r.code()); } +TEST_F(ReplCoordTest, RemovedNodeDoesNotGrantVote) { + // A 1-node set. This node is not a member. + assertStartSuccess(BSON("_id" + << "mySet" + << "version" + << 1 + << "members" + << BSON_ARRAY(BSON("host" + << "node1:12345" + << "_id" + << 0))), + HostAndPort("node2", 12345)); + + ASSERT_OK(getReplCoord()->setFollowerMode(MemberState::RS_REMOVED)); + ReplSetRequestVotesArgs args; + ASSERT_OK(args.initialize(BSON("replSetRequestVotes" << 1 << "setName" + << "mySet" + << "term" + << 2 + << "candidateIndex" + << 0LL + << "configVersion" + << 1LL + << "dryRun" + << false + << "lastCommittedOp" + << OpTime().toBSON()))); + + ReplSetRequestVotesResponse response; + auto opCtx = makeOperationContext(); + auto r = getReplCoord()->processReplSetRequestVotes(opCtx.get(), args, &response); + ASSERT_NOT_OK(r); + ASSERT_EQUALS("Invalid replica set config, or this node is not a member", r.reason()); + ASSERT_EQUALS(ErrorCodes::InvalidReplicaSetConfig, r.code()); + + // Vote was not recorded. + ServiceContext* svcCtx = getServiceContext(); + ASSERT(ReplicationMetrics::get(svcCtx).getElectionParticipantMetricsBSON().isEmpty()); +} + // TODO(schwerin): Unit test election id updating } // namespace } // namespace repl -- cgit v1.2.1