mirror of
https://github.com/fluencelabs/redis
synced 2025-03-30 22:31:03 +00:00
Cluster: non-conditional steps of slave failover refactored into a function.
This commit is contained in:
parent
230d141420
commit
a7010ae208
@ -2636,6 +2636,42 @@ void clusterLogCantFailover(int reason) {
|
|||||||
redisLog(REDIS_WARNING,"Currently unable to failover: %s", msg);
|
redisLog(REDIS_WARNING,"Currently unable to failover: %s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function implements the final part of automatic and manual failovers,
|
||||||
|
* where the slave grabs its master's hash slots, and propagates the new
|
||||||
|
* configuration.
|
||||||
|
*
|
||||||
|
* Note that it's up to the caller to be sure that the node got a new
|
||||||
|
* configuration epoch already. */
|
||||||
|
void clusterFailoverReplaceYourMaster(void) {
|
||||||
|
int j;
|
||||||
|
clusterNode *oldmaster = myself->slaveof;
|
||||||
|
|
||||||
|
if (nodeIsMaster(myself) || oldmaster == NULL) return;
|
||||||
|
|
||||||
|
/* 1) Turn this node into a master. */
|
||||||
|
clusterSetNodeAsMaster(myself);
|
||||||
|
replicationUnsetMaster();
|
||||||
|
|
||||||
|
/* 2) Claim all the slots assigned to our master. */
|
||||||
|
for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) {
|
||||||
|
if (clusterNodeGetSlotBit(oldmaster,j)) {
|
||||||
|
clusterDelSlot(j);
|
||||||
|
clusterAddSlot(myself,j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3) Update state and save config. */
|
||||||
|
clusterUpdateState();
|
||||||
|
clusterSaveConfigOrDie(1);
|
||||||
|
|
||||||
|
/* 4) Pong all the other nodes so that they can update the state
|
||||||
|
* accordingly and detect that we switched to master role. */
|
||||||
|
clusterBroadcastPong(CLUSTER_BROADCAST_ALL);
|
||||||
|
|
||||||
|
/* 5) If there was a manual failover in progress, clear the state. */
|
||||||
|
resetManualFailover();
|
||||||
|
}
|
||||||
|
|
||||||
/* This function is called if we are a slave node and our master serving
|
/* This function is called if we are a slave node and our master serving
|
||||||
* a non-zero amount of hash slots is in FAIL state.
|
* a non-zero amount of hash slots is in FAIL state.
|
||||||
*
|
*
|
||||||
@ -2650,7 +2686,6 @@ void clusterHandleSlaveFailover(void) {
|
|||||||
int needed_quorum = (server.cluster->size / 2) + 1;
|
int needed_quorum = (server.cluster->size / 2) + 1;
|
||||||
int manual_failover = server.cluster->mf_end != 0 &&
|
int manual_failover = server.cluster->mf_end != 0 &&
|
||||||
server.cluster->mf_can_start;
|
server.cluster->mf_can_start;
|
||||||
int j;
|
|
||||||
mstime_t auth_timeout, auth_retry_time;
|
mstime_t auth_timeout, auth_retry_time;
|
||||||
|
|
||||||
server.cluster->todo_before_sleep &= ~CLUSTER_TODO_HANDLE_FAILOVER;
|
server.cluster->todo_before_sleep &= ~CLUSTER_TODO_HANDLE_FAILOVER;
|
||||||
@ -2792,26 +2827,12 @@ void clusterHandleSlaveFailover(void) {
|
|||||||
|
|
||||||
/* Check if we reached the quorum. */
|
/* Check if we reached the quorum. */
|
||||||
if (server.cluster->failover_auth_count >= needed_quorum) {
|
if (server.cluster->failover_auth_count >= needed_quorum) {
|
||||||
clusterNode *oldmaster = myself->slaveof;
|
/* We have the quorum, we can finally failover the master. */
|
||||||
|
|
||||||
redisLog(REDIS_WARNING,
|
redisLog(REDIS_WARNING,
|
||||||
"Failover election won: I'm the new master.");
|
"Failover election won: I'm the new master.");
|
||||||
/* We have the quorum, perform all the steps to correctly promote
|
|
||||||
* this slave to a master.
|
|
||||||
*
|
|
||||||
* 1) Turn this node into a master. */
|
|
||||||
clusterSetNodeAsMaster(myself);
|
|
||||||
replicationUnsetMaster();
|
|
||||||
|
|
||||||
/* 2) Claim all the slots assigned to our master. */
|
/* Update my configEpoch to the epoch of the election. */
|
||||||
for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) {
|
|
||||||
if (clusterNodeGetSlotBit(oldmaster,j)) {
|
|
||||||
clusterDelSlot(j);
|
|
||||||
clusterAddSlot(myself,j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 3) Update my configEpoch to the epoch of the election. */
|
|
||||||
if (myself->configEpoch < server.cluster->failover_auth_epoch) {
|
if (myself->configEpoch < server.cluster->failover_auth_epoch) {
|
||||||
myself->configEpoch = server.cluster->failover_auth_epoch;
|
myself->configEpoch = server.cluster->failover_auth_epoch;
|
||||||
redisLog(REDIS_WARNING,
|
redisLog(REDIS_WARNING,
|
||||||
@ -2819,16 +2840,8 @@ void clusterHandleSlaveFailover(void) {
|
|||||||
(unsigned long long) myself->configEpoch);
|
(unsigned long long) myself->configEpoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 4) Update state and save config. */
|
/* Take responsability for the cluster slots. */
|
||||||
clusterUpdateState();
|
clusterFailoverReplaceYourMaster();
|
||||||
clusterSaveConfigOrDie(1);
|
|
||||||
|
|
||||||
/* 5) Pong all the other nodes so that they can update the state
|
|
||||||
* accordingly and detect that we switched to master role. */
|
|
||||||
clusterBroadcastPong(CLUSTER_BROADCAST_ALL);
|
|
||||||
|
|
||||||
/* 6) If there was a manual failover in progress, clear the state. */
|
|
||||||
resetManualFailover();
|
|
||||||
} else {
|
} else {
|
||||||
clusterLogCantFailover(REDIS_CLUSTER_CANT_FAILOVER_WAITING_VOTES);
|
clusterLogCantFailover(REDIS_CLUSTER_CANT_FAILOVER_WAITING_VOTES);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user