summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2015-03-21 11:54:32 +0100
committerantirez <antirez@gmail.com>2015-03-21 18:23:06 +0100
commitb37b2b5c14803a555633b55f50655bcf784bf37d (patch)
treeb3a594e77b689114dc1107e9800f44d1556ebf95
parentc43c970344da846d75a4421dc7936d805765c751 (diff)
downloadredis-b37b2b5c14803a555633b55f50655bcf784bf37d.tar.gz
Cluster: TAKEOVER option for manual failover.
-rw-r--r--src/cluster.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/src/cluster.c b/src/cluster.c
index 4f445f5d7..17270b0f4 100644
--- a/src/cluster.c
+++ b/src/cluster.c
@@ -4174,18 +4174,22 @@ void clusterCommand(redisClient *c) {
} else if (!strcasecmp(c->argv[1]->ptr,"failover") &&
(c->argc == 2 || c->argc == 3))
{
- /* CLUSTER FAILOVER [FORCE] */
- int force = 0;
+ /* CLUSTER FAILOVER [FORCE|TAKEOVER] */
+ int force = 0, takeover = 0;
if (c->argc == 3) {
if (!strcasecmp(c->argv[2]->ptr,"force")) {
force = 1;
+ } else if (!strcasecmp(c->argv[2]->ptr,"takeover")) {
+ takeover = 1;
+ force = 1; /* Takeover also implies force. */
} else {
addReply(c,shared.syntaxerr);
return;
}
}
+ /* Check preconditions. */
if (nodeIsMaster(myself)) {
addReplyError(c,"You should send CLUSTER FAILOVER to a slave");
return;
@@ -4203,15 +4207,24 @@ void clusterCommand(redisClient *c) {
resetManualFailover();
server.cluster->mf_end = mstime() + REDIS_CLUSTER_MF_TIMEOUT;
- /* If this is a forced failover, we don't need to talk with our master
- * to agree about the offset. We just failover taking over it without
- * coordination. */
- if (force) {
+ if (takeover) {
+ /* A takeover does not perform any initial check. It just
+ * generates a new configuration epoch for this node without
+ * consensus, claims the master's slots, and broadcast the new
+ * configuration. */
+ redisLog(REDIS_WARNING,"Taking over the master (user request).");
+ clusterBumpConfigEpochWithoutConsensus();
+ clusterFailoverReplaceYourMaster();
+ } else if (force) {
+ /* If this is a forced failover, we don't need to talk with our
+ * master to agree about the offset. We just failover taking over
+ * it without coordination. */
+ redisLog(REDIS_WARNING,"Forced failover user request accepted.");
server.cluster->mf_can_start = 1;
} else {
+ redisLog(REDIS_WARNING,"Manual failover user request accepted.");
clusterSendMFStart(myself->slaveof);
}
- redisLog(REDIS_WARNING,"Manual failover user request accepted.");
addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"set-config-epoch") && c->argc == 3)
{