Cluster: TAKEOVER option for manual failover.

This commit is contained in:
antirez 2015-03-21 11:54:32 +01:00
parent d544600aa5
commit 2950824ab6

View File

@ -4174,18 +4174,22 @@ void clusterCommand(redisClient *c) {
} else if (!strcasecmp(c->argv[1]->ptr,"failover") && } else if (!strcasecmp(c->argv[1]->ptr,"failover") &&
(c->argc == 2 || c->argc == 3)) (c->argc == 2 || c->argc == 3))
{ {
/* CLUSTER FAILOVER [FORCE] */ /* CLUSTER FAILOVER [FORCE|TAKEOVER] */
int force = 0; int force = 0, takeover = 0;
if (c->argc == 3) { if (c->argc == 3) {
if (!strcasecmp(c->argv[2]->ptr,"force")) { if (!strcasecmp(c->argv[2]->ptr,"force")) {
force = 1; force = 1;
} else if (!strcasecmp(c->argv[2]->ptr,"takeover")) {
takeover = 1;
force = 1; /* Takeover also implies force. */
} else { } else {
addReply(c,shared.syntaxerr); addReply(c,shared.syntaxerr);
return; return;
} }
} }
/* Check preconditions. */
if (nodeIsMaster(myself)) { if (nodeIsMaster(myself)) {
addReplyError(c,"You should send CLUSTER FAILOVER to a slave"); addReplyError(c,"You should send CLUSTER FAILOVER to a slave");
return; return;
@ -4203,15 +4207,24 @@ void clusterCommand(redisClient *c) {
resetManualFailover(); resetManualFailover();
server.cluster->mf_end = mstime() + REDIS_CLUSTER_MF_TIMEOUT; server.cluster->mf_end = mstime() + REDIS_CLUSTER_MF_TIMEOUT;
/* If this is a forced failover, we don't need to talk with our master if (takeover) {
* to agree about the offset. We just failover taking over it without /* A takeover does not perform any initial check. It just
* coordination. */ * generates a new configuration epoch for this node without
if (force) { * 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; server.cluster->mf_can_start = 1;
} else { } else {
redisLog(REDIS_WARNING,"Manual failover user request accepted.");
clusterSendMFStart(myself->slaveof); clusterSendMFStart(myself->slaveof);
} }
redisLog(REDIS_WARNING,"Manual failover user request accepted.");
addReply(c,shared.ok); addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"set-config-epoch") && c->argc == 3) } else if (!strcasecmp(c->argv[1]->ptr,"set-config-epoch") && c->argc == 3)
{ {