diff options
author | A. Jesse Jiryu Davis <jesse@mongodb.com> | 2020-04-21 18:43:41 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-04-25 02:22:46 +0000 |
commit | be0eb178a1c599497a307a5b114d112343fab9c1 (patch) | |
tree | 0892ecd512337e15f42a28647738ba85f20e1ccb /src/mongo | |
parent | 7bffc86bd02fb992f14bcce7bf686ca67adbf6a7 (diff) | |
download | mongo-be0eb178a1c599497a307a5b114d112343fab9c1.tar.gz |
SERVER-47613 Fix invariant when a removed member votes
(cherry picked from commit cc814e4c87c1ae20ef7c0840344496043dbdf18d)
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl_test.cpp | 42 |
2 files changed, 46 insertions, 1 deletions
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 |