summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl/replication_coordinator_impl_elect_v1.cpp
diff options
context:
space:
mode:
authorSamy Lanka <samy.lanka@10gen.com>2017-07-19 14:48:24 -0400
committerSamy Lanka <samy.lanka@10gen.com>2017-08-04 11:17:24 -0400
commitfa70f68f5bfcc2a001d3f9012dff80dd2d41c9f1 (patch)
treec184fd989cb0188231df1496f086286927999051 /src/mongo/db/repl/replication_coordinator_impl_elect_v1.cpp
parent1599ba40e091bcf356bf0231bf32333397f07753 (diff)
downloadmongo-fa70f68f5bfcc2a001d3f9012dff80dd2d41c9f1.tar.gz
SERVER-29502 Require the vote from the current primary in the dry run for catchup takeover
Diffstat (limited to 'src/mongo/db/repl/replication_coordinator_impl_elect_v1.cpp')
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_elect_v1.cpp27
1 files changed, 22 insertions, 5 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl_elect_v1.cpp b/src/mongo/db/repl/replication_coordinator_impl_elect_v1.cpp
index 394878e52ec..1050da2461e 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_elect_v1.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_elect_v1.cpp
@@ -85,12 +85,14 @@ public:
};
-void ReplicationCoordinatorImpl::_startElectSelfV1() {
+void ReplicationCoordinatorImpl::_startElectSelfV1(
+ TopologyCoordinator::StartElectionReason reason) {
stdx::lock_guard<stdx::mutex> lk(_mutex);
- _startElectSelfV1_inlock();
+ _startElectSelfV1_inlock(reason);
}
-void ReplicationCoordinatorImpl::_startElectSelfV1_inlock() {
+void ReplicationCoordinatorImpl::_startElectSelfV1_inlock(
+ TopologyCoordinator::StartElectionReason reason) {
invariant(!_voteRequester);
invariant(!_freshnessChecker);
@@ -138,13 +140,20 @@ void ReplicationCoordinatorImpl::_startElectSelfV1_inlock() {
_voteRequester.reset(new VoteRequester);
long long term = _topCoord->getTerm();
+ int primaryIndex = -1;
+
+ // Only set primaryIndex if the primary's vote is required during the dry run.
+ if (reason == TopologyCoordinator::StartElectionReason::kCatchupTakeover) {
+ primaryIndex = _topCoord->getCurrentPrimaryIndex();
+ }
StatusWith<executor::TaskExecutor::EventHandle> nextPhaseEvh =
_voteRequester->start(_replExecutor.get(),
_rsConfig,
_selfIndex,
_topCoord->getTerm(),
true, // dry run
- lastOpTime);
+ lastOpTime,
+ primaryIndex);
if (nextPhaseEvh.getStatus() == ErrorCodes::ShutdownInProgress) {
return;
}
@@ -175,6 +184,9 @@ void ReplicationCoordinatorImpl::_onDryRunComplete(long long originalTerm) {
} else if (endResult == VoteRequester::Result::kStaleTerm) {
log() << "not running for primary, we have been superceded already";
return;
+ } else if (endResult == VoteRequester::Result::kPrimaryRespondedNo) {
+ log() << "not running for primary, the current primary responded no in the dry run";
+ return;
} else if (endResult != VoteRequester::Result::kSuccessfullyElected) {
log() << "not running for primary, we received an unexpected problem";
return;
@@ -241,7 +253,7 @@ void ReplicationCoordinatorImpl::_startVoteRequester_inlock(long long newTerm) {
_voteRequester.reset(new VoteRequester);
StatusWith<executor::TaskExecutor::EventHandle> nextPhaseEvh = _voteRequester->start(
- _replExecutor.get(), _rsConfig, _selfIndex, _topCoord->getTerm(), false, lastOpTime);
+ _replExecutor.get(), _rsConfig, _selfIndex, _topCoord->getTerm(), false, lastOpTime, -1);
if (nextPhaseEvh.getStatus() == ErrorCodes::ShutdownInProgress) {
return;
}
@@ -264,6 +276,7 @@ void ReplicationCoordinatorImpl::_onVoteRequestComplete(long long originalTerm)
}
const VoteRequester::Result endResult = _voteRequester->getResult();
+ invariant(endResult != VoteRequester::Result::kPrimaryRespondedNo);
switch (endResult) {
case VoteRequester::Result::kInsufficientVotes:
@@ -275,6 +288,10 @@ void ReplicationCoordinatorImpl::_onVoteRequestComplete(long long originalTerm)
case VoteRequester::Result::kSuccessfullyElected:
log() << "election succeeded, assuming primary role in term " << _topCoord->getTerm();
break;
+ case VoteRequester::Result::kPrimaryRespondedNo:
+ // This is impossible because we would only require the primary's
+ // vote during a dry run.
+ invariant(false);
}
// Mark all nodes that responded to our vote request as up to avoid immediately