diff options
Diffstat (limited to 'src/mongo/db/repl')
7 files changed, 42 insertions, 69 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index 1d7c3821752..fe7a3251df6 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -356,7 +356,7 @@ void ReplicationCoordinatorImpl::_finishLoadLocalConfig( term = lastVoteTerm; } } - _updateTerm_incallback(term, nullptr); + _updateTerm_incallback(term); stdx::unique_lock<stdx::mutex> lk(_mutex); @@ -1637,7 +1637,7 @@ void ReplicationCoordinatorImpl::_processReplSetMetadata_incallback( return; } _setLastCommittedOpTime(replMetadata.getLastOpCommitted()); - _updateTerm_incallback(replMetadata.getTerm(), nullptr); + _updateTerm_incallback(replMetadata.getTerm()); } bool ReplicationCoordinatorImpl::getMaintenanceMode() { @@ -2894,24 +2894,23 @@ void ReplicationCoordinatorImpl::_getTerm_helper(const ReplicationExecutor::Call } Status ReplicationCoordinatorImpl::updateTerm(long long term) { - if (!isV1ElectionProtocol()) { - // Do not update if not in V1 protocol. - return Status::OK(); - } - // Term is only valid if we are replicating. if (getReplicationMode() != modeReplSet) { return {ErrorCodes::BadValue, "cannot supply 'term' without active replication"}; } + if (!isV1ElectionProtocol()) { + // Do not update if not in V1 protocol. + return Status::OK(); + } + bool updated = false; CBHStatus cbh = _replExecutor.scheduleWork(stdx::bind(&ReplicationCoordinatorImpl::_updateTerm_helper, this, stdx::placeholders::_1, term, - &updated, - nullptr)); + &updated)); if (cbh.getStatus() == ErrorCodes::ShutdownInProgress) { return cbh.getStatus(); } @@ -2925,37 +2924,17 @@ Status ReplicationCoordinatorImpl::updateTerm(long long term) { return Status::OK(); } -bool ReplicationCoordinatorImpl::updateTerm_forTest(long long term) { - bool updated = false; - Handle cbHandle; - CBHStatus cbh = - _replExecutor.scheduleWork(stdx::bind(&ReplicationCoordinatorImpl::_updateTerm_helper, - this, - stdx::placeholders::_1, - term, - &updated, - &cbHandle)); - if (cbh.getStatus() == ErrorCodes::ShutdownInProgress) { - return false; - } - fassert(28673, cbh.getStatus()); - _replExecutor.wait(cbh.getValue()); - _replExecutor.wait(cbHandle); - return updated; -} - void ReplicationCoordinatorImpl::_updateTerm_helper(const ReplicationExecutor::CallbackArgs& cbData, long long term, - bool* updated, - Handle* cbHandle) { + bool* updated) { if (cbData.status == ErrorCodes::CallbackCanceled) { return; } - *updated = _updateTerm_incallback(term, cbHandle); + *updated = _updateTerm_incallback(term); } -bool ReplicationCoordinatorImpl::_updateTerm_incallback(long long term, Handle* cbHandle) { +bool ReplicationCoordinatorImpl::_updateTerm_incallback(long long term) { bool updated = _topCoord->updateTerm(term); { stdx::lock_guard<stdx::mutex> lock(_mutex); @@ -2965,15 +2944,7 @@ bool ReplicationCoordinatorImpl::_updateTerm_incallback(long long term, Handle* if (updated && getMemberState().primary()) { log() << "stepping down from primary, because a new term has begun"; _topCoord->prepareForStepDown(); - CBHStatus cbh = _replExecutor.scheduleWorkWithGlobalExclusiveLock( - stdx::bind(&ReplicationCoordinatorImpl::_stepDownFinish, this, stdx::placeholders::_1)); - if (cbh.getStatus() == ErrorCodes::ShutdownInProgress) { - return true; - } - fassert(28672, cbh.getStatus()); - if (cbHandle) { - *cbHandle = cbh.getValue(); - } + _stepDownStart(); } return updated; } diff --git a/src/mongo/db/repl/replication_coordinator_impl.h b/src/mongo/db/repl/replication_coordinator_impl.h index 40c2fc36570..acde2e277c1 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.h +++ b/src/mongo/db/repl/replication_coordinator_impl.h @@ -306,8 +306,6 @@ public: */ Status setLastOptime_forTest(long long cfgVer, long long memberId, const OpTime& opTime); - bool updateTerm_forTest(long long term); - /** * If called after _startElectSelfV1(), blocks until all asynchronous * activities associated with election complete. @@ -900,7 +898,7 @@ private: */ void _requestRemotePrimaryStepdown(const HostAndPort& target); - void _heartbeatStepDownStart(); + void _stepDownStart(); /** * Completes a step-down of the current node. Must be run with a global @@ -983,12 +981,11 @@ private: */ void _updateTerm_helper(const ReplicationExecutor::CallbackArgs& cbData, long long term, - bool* updated, - Handle* cbHandle); + bool* updated); /** * Returns true if the term increased. */ - bool _updateTerm_incallback(long long term, Handle* cbHandle); + bool _updateTerm_incallback(long long term); /** * Callback that processes the ReplSetMetadata returned from a command run against another 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 2cb9e50e7ea..420179f70ac 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_elect_v1.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_elect_v1.cpp @@ -181,7 +181,7 @@ void ReplicationCoordinatorImpl::_onDryRunComplete(long long originalTerm) { } log() << "dry election run succeeded, running for election"; - _updateTerm_incallback(originalTerm + 1, nullptr); + _updateTerm_incallback(originalTerm + 1); // Secure our vote for ourself first _topCoord->voteForMyselfV1(); @@ -298,8 +298,7 @@ void ReplicationCoordinatorImpl::_onElectionWinnerDeclarerComplete() { if (!endResult.isOK()) { log() << "stepping down from primary, because: " << endResult; _topCoord->prepareForStepDown(); - _replExecutor.scheduleWorkWithGlobalExclusiveLock( - stdx::bind(&ReplicationCoordinatorImpl::_stepDownFinish, this, stdx::placeholders::_1)); + _stepDownStart(); } lossGuard.dismiss(); diff --git a/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp b/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp index 4014f88bf3c..388424b9636 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp @@ -142,7 +142,7 @@ void ReplicationCoordinatorImpl::_handleHeartbeatResponse( if (responseStatus.isOK()) { networkTime = cbData.response.getValue().elapsedMillis; - _updateTerm_incallback(hbStatusResponse.getValue().getTerm(), nullptr); + _updateTerm_incallback(hbStatusResponse.getValue().getTerm()); } else { log() << "Error in heartbeat request to " << target << "; " << responseStatus; if (!resp.isEmpty()) { @@ -215,7 +215,8 @@ void ReplicationCoordinatorImpl::_handleHeartbeatResponseAction( break; case HeartbeatResponseAction::StepDownSelf: invariant(action.getPrimaryConfigIndex() == _selfIndex); - _heartbeatStepDownStart(); + log() << "Stepping down from primary in response to heartbeat"; + _stepDownStart(); break; case HeartbeatResponseAction::StepDownRemotePrimary: { invariant(action.getPrimaryConfigIndex() != _selfIndex); @@ -259,10 +260,15 @@ void ReplicationCoordinatorImpl::_requestRemotePrimaryStepdown(const HostAndPort } } -void ReplicationCoordinatorImpl::_heartbeatStepDownStart() { - log() << "Stepping down from primary in response to heartbeat"; +void ReplicationCoordinatorImpl::_stepDownStart() { const StatusWith<ReplicationExecutor::EventHandle> stepDownFinishEvh = _replExecutor.makeEvent(); + if (!stepDownFinishEvh.isOK()) { + if (stepDownFinishEvh.getStatus() != ErrorCodes::ShutdownInProgress) { + fassert(28672, stepDownFinishEvh.getStatus()); + } + return; + } _stepDownFinishedEvent = stepDownFinishEvh.getValue(); _replExecutor.scheduleWorkWithGlobalExclusiveLock( stdx::bind(&ReplicationCoordinatorImpl::_stepDownFinish, this, stdx::placeholders::_1)); diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp index 89a839ebd59..c1745504358 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp @@ -1186,8 +1186,13 @@ private: } }; +TEST_F(ReplCoordTest, UpdateTermNotReplMode) { + init(ReplSettings()); + ASSERT_TRUE(ReplicationCoordinator::modeNone == getReplCoord()->getReplicationMode()); + ASSERT_EQUALS(ErrorCodes::BadValue, getReplCoord()->updateTerm(0).code()); +} + TEST_F(ReplCoordTest, UpdateTerm) { - ReplCoordTest::setUp(); init("mySet/test1:1234,test2:1234,test3:1234"); assertStartSuccess( @@ -1211,19 +1216,20 @@ TEST_F(ReplCoordTest, UpdateTerm) { ASSERT_TRUE(getReplCoord()->getMemberState().primary()); // lower term, no change - getReplCoord()->updateTerm(0); + ASSERT_OK(getReplCoord()->updateTerm(0)); ASSERT_EQUALS(1, getReplCoord()->getTerm()); ASSERT_TRUE(getReplCoord()->getMemberState().primary()); // same term, no change - getReplCoord()->updateTerm(1); + ASSERT_OK(getReplCoord()->updateTerm(1)); ASSERT_EQUALS(1, getReplCoord()->getTerm()); ASSERT_TRUE(getReplCoord()->getMemberState().primary()); // higher term, step down and change term Handle cbHandle; - getReplCoord()->updateTerm_forTest(2); + ASSERT_EQUALS(ErrorCodes::StaleTerm, getReplCoord()->updateTerm(2).code()); ASSERT_EQUALS(2, getReplCoord()->getTerm()); + getReplCoord()->waitForStepDownFinish_forTest(); ASSERT_TRUE(getReplCoord()->getMemberState().secondary()); } diff --git a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp index 2e8fb1afa81..cbcae25e7c5 100644 --- a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp +++ b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp @@ -67,9 +67,6 @@ ReplicaSetConfig ReplCoordTest::assertMakeRSConfig(const BSONObj& configBson) { return config; } -ReplCoordTest::ReplCoordTest() : _callShutdown(false) {} -ReplCoordTest::~ReplCoordTest() {} - void ReplCoordTest::setUp() { _settings.replSet = "mySet/node1:12345,node2:54321"; } diff --git a/src/mongo/db/repl/replication_coordinator_test_fixture.h b/src/mongo/db/repl/replication_coordinator_test_fixture.h index d38ef060eb7..80601582d15 100644 --- a/src/mongo/db/repl/replication_coordinator_test_fixture.h +++ b/src/mongo/db/repl/replication_coordinator_test_fixture.h @@ -68,9 +68,6 @@ public: */ static ReplicaSetConfig assertMakeRSConfig(const BSONObj& configBSON); - ReplCoordTest(); - virtual ~ReplCoordTest(); - protected: virtual void setUp(); virtual void tearDown(); @@ -191,15 +188,15 @@ protected: private: std::unique_ptr<ReplicationCoordinatorImpl> _repl; // Owned by ReplicationCoordinatorImpl - TopologyCoordinatorImpl* _topo; + TopologyCoordinatorImpl* _topo = nullptr; // Owned by ReplicationCoordinatorImpl - executor::NetworkInterfaceMock* _net; + executor::NetworkInterfaceMock* _net = nullptr; // Owned by ReplicationCoordinatorImpl - StorageInterfaceMock* _storage; + StorageInterfaceMock* _storage = nullptr; // Owned by ReplicationCoordinatorImpl - ReplicationCoordinatorExternalStateMock* _externalState; + ReplicationCoordinatorExternalStateMock* _externalState = nullptr; ReplSettings _settings; - bool _callShutdown; + bool _callShutdown = false; }; } // namespace repl |