summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Jesse Jiryu Davis <jesse@mongodb.com>2020-04-21 18:43:41 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-04-24 19:06:55 +0000
commitfe855c5d116316c50905cf5900c23801fd0c6f68 (patch)
tree946d5d92a0e74eb86f7479a65afa713db0cc2ab2
parent23f28ec9b46619d9b2cf6784b344c62bd0ffccaa (diff)
downloadmongo-fe855c5d116316c50905cf5900c23801fd0c6f68.tar.gz
SERVER-47613 Fix invariant when a removed member votes
(cherry picked from commit cc814e4c87c1ae20ef7c0840344496043dbdf18d) # Conflicts: # src/mongo/db/repl/replication_coordinator_impl.cpp # src/mongo/db/repl/replication_coordinator_impl_test.cpp # src/mongo/db/repl/topology_coordinator_v1_test.cpp
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp5
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_test.cpp32
2 files changed, 36 insertions, 1 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index dec850a385c..8368d7dc3b9 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -3869,6 +3869,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 7d3525da122..9b347f968a1 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
@@ -5964,7 +5964,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"
@@ -6006,6 +6006,36 @@ 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