summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl
diff options
context:
space:
mode:
authorSiyuan Zhou <siyuan.zhou@mongodb.com>2016-05-17 15:43:35 -0400
committerSiyuan Zhou <siyuan.zhou@mongodb.com>2016-07-05 16:51:04 -0400
commite3ee305be314d8109ec1f1fd558b7011817dbfe7 (patch)
treeb831be96e3a66c52336d2e4a7ca382e5c8a3206f /src/mongo/db/repl
parent71424c1c4b87c5819b1fc5cf114078a6f33c6078 (diff)
downloadmongo-e3ee305be314d8109ec1f1fd558b7011817dbfe7.tar.gz
SERVER-24881 Add StepUp Command.
Diffstat (limited to 'src/mongo/db/repl')
-rw-r--r--src/mongo/db/repl/replication_coordinator.h2
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp21
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.h1
-rw-r--r--src/mongo/db/repl/replication_coordinator_mock.cpp4
-rw-r--r--src/mongo/db/repl/replication_coordinator_mock.h2
-rw-r--r--src/mongo/db/repl/replset_commands.cpp33
6 files changed, 63 insertions, 0 deletions
diff --git a/src/mongo/db/repl/replication_coordinator.h b/src/mongo/db/repl/replication_coordinator.h
index 37c89b5c67f..47ace7b21be 100644
--- a/src/mongo/db/repl/replication_coordinator.h
+++ b/src/mongo/db/repl/replication_coordinator.h
@@ -785,6 +785,8 @@ public:
virtual ReplSettings::IndexPrefetchConfig getIndexPrefetchConfig() const = 0;
virtual void setIndexPrefetchConfig(const ReplSettings::IndexPrefetchConfig cfg) = 0;
+ virtual Status stepUpIfEligible() = 0;
+
protected:
ReplicationCoordinator();
};
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index 5ffd00cef2b..215e9667866 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -3536,6 +3536,27 @@ CallbackFn ReplicationCoordinatorImpl::_wrapAsCallbackFn(const stdx::function<vo
};
}
+Status ReplicationCoordinatorImpl::stepUpIfEligible() {
+ if (!isV1ElectionProtocol()) {
+ return Status(ErrorCodes::CommandNotSupported,
+ "Step-up command is only supported by Protocol Version 1");
+ }
+
+ _startElectSelfIfEligibleV1(false);
+ EventHandle finishEvent;
+ {
+ LockGuard lk(_mutex);
+ finishEvent = _electionFinishedEvent;
+ }
+ if (finishEvent.isValid()) {
+ _replExecutor.waitForEvent(finishEvent);
+ }
+ auto state = getMemberState();
+ if (state.primary()) {
+ return Status::OK();
+ }
+ return Status(ErrorCodes::CommandFailed, "Election failed.");
+}
bool ReplicationCoordinatorImpl::getInitialSyncRequestedFlag() const {
stdx::lock_guard<stdx::mutex> lock(_initialSyncMutex);
diff --git a/src/mongo/db/repl/replication_coordinator_impl.h b/src/mongo/db/repl/replication_coordinator_impl.h
index 1e8b369ff91..cacf60a96b7 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.h
+++ b/src/mongo/db/repl/replication_coordinator_impl.h
@@ -334,6 +334,7 @@ public:
virtual ReplSettings::IndexPrefetchConfig getIndexPrefetchConfig() const override;
virtual void setIndexPrefetchConfig(const ReplSettings::IndexPrefetchConfig cfg) override;
+ virtual Status stepUpIfEligible() override;
// ================== Test support API ===================
diff --git a/src/mongo/db/repl/replication_coordinator_mock.cpp b/src/mongo/db/repl/replication_coordinator_mock.cpp
index 91893d37325..4e1cdff5434 100644
--- a/src/mongo/db/repl/replication_coordinator_mock.cpp
+++ b/src/mongo/db/repl/replication_coordinator_mock.cpp
@@ -449,5 +449,9 @@ ReplSettings::IndexPrefetchConfig ReplicationCoordinatorMock::getIndexPrefetchCo
void ReplicationCoordinatorMock::setIndexPrefetchConfig(
const ReplSettings::IndexPrefetchConfig cfg) {}
+Status ReplicationCoordinatorMock::stepUpIfEligible() {
+ return Status::OK();
+}
+
} // namespace repl
} // namespace mongo
diff --git a/src/mongo/db/repl/replication_coordinator_mock.h b/src/mongo/db/repl/replication_coordinator_mock.h
index ec76a9677ac..67d8fd0ed27 100644
--- a/src/mongo/db/repl/replication_coordinator_mock.h
+++ b/src/mongo/db/repl/replication_coordinator_mock.h
@@ -256,6 +256,8 @@ public:
virtual ReplSettings::IndexPrefetchConfig getIndexPrefetchConfig() const override;
virtual void setIndexPrefetchConfig(const ReplSettings::IndexPrefetchConfig cfg) override;
+ virtual Status stepUpIfEligible() override;
+
private:
AtomicUInt64 _snapshotNameGenerator;
const ReplSettings _settings;
diff --git a/src/mongo/db/repl/replset_commands.cpp b/src/mongo/db/repl/replset_commands.cpp
index 12ace8dc728..9130052de75 100644
--- a/src/mongo/db/repl/replset_commands.cpp
+++ b/src/mongo/db/repl/replset_commands.cpp
@@ -893,5 +893,38 @@ private:
}
} cmdReplSetElect;
+class CmdReplSetStepUp : public ReplSetCommand {
+public:
+ virtual Status checkAuthForCommand(ClientBasic* client,
+ const std::string& dbname,
+ const BSONObj& cmdObj) {
+ ActionSet actions;
+ actions.addAction(ActionType::replSetStateChange);
+ if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource(
+ ResourcePattern::forClusterResource(), actions)) {
+ return Status(ErrorCodes::Unauthorized, "Unauthorized");
+ }
+ return Status::OK();
+ }
+
+ CmdReplSetStepUp() : ReplSetCommand("replSetStepUp") {}
+
+private:
+ virtual bool run(OperationContext* txn,
+ const string&,
+ BSONObj& cmdObj,
+ int,
+ string& errmsg,
+ BSONObjBuilder& result) {
+ Status status = getGlobalReplicationCoordinator()->checkReplEnabledForCommand(&result);
+ if (!status.isOK())
+ return appendCommandStatus(result, status);
+
+ status = getGlobalReplicationCoordinator()->stepUpIfEligible();
+
+ return appendCommandStatus(result, status);
+ }
+} cmdReplSetStepUp;
+
} // namespace repl
} // namespace mongo