MCPcopy Create free account
hub / github.com/F-Stack/f-stack / clusterHandleSlaveFailover

Function clusterHandleSlaveFailover

app/redis-6.2.6/src/cluster.c:3134–3303  ·  view source on GitHub ↗

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. * * The goal of this function is: * 1) To check if we are able to perform a failover, is our data updated? * 2) Try to get elected by masters. * 3) Perform the failover informing all the other nodes. */

Source from the content-addressed store, hash-verified

3132 * 3) Perform the failover informing all the other nodes.
3133 */
3134void clusterHandleSlaveFailover(void) {
3135 mstime_t data_age;
3136 mstime_t auth_age = mstime() - server.cluster->failover_auth_time;
3137 int needed_quorum = (server.cluster->size / 2) + 1;
3138 int manual_failover = server.cluster->mf_end != 0 &&
3139 server.cluster->mf_can_start;
3140 mstime_t auth_timeout, auth_retry_time;
3141
3142 server.cluster->todo_before_sleep &= ~CLUSTER_TODO_HANDLE_FAILOVER;
3143
3144 /* Compute the failover timeout (the max time we have to send votes
3145 * and wait for replies), and the failover retry time (the time to wait
3146 * before trying to get voted again).
3147 *
3148 * Timeout is MAX(NODE_TIMEOUT*2,2000) milliseconds.
3149 * Retry is two times the Timeout.
3150 */
3151 auth_timeout = server.cluster_node_timeout*2;
3152 if (auth_timeout < 2000) auth_timeout = 2000;
3153 auth_retry_time = auth_timeout*2;
3154
3155 /* Pre conditions to run the function, that must be met both in case
3156 * of an automatic or manual failover:
3157 * 1) We are a slave.
3158 * 2) Our master is flagged as FAIL, or this is a manual failover.
3159 * 3) We don't have the no failover configuration set, and this is
3160 * not a manual failover.
3161 * 4) It is serving slots. */
3162 if (nodeIsMaster(myself) ||
3163 myself->slaveof == NULL ||
3164 (!nodeFailed(myself->slaveof) && !manual_failover) ||
3165 (server.cluster_slave_no_failover && !manual_failover) ||
3166 myself->slaveof->numslots == 0)
3167 {
3168 /* There are no reasons to failover, so we set the reason why we
3169 * are returning without failing over to NONE. */
3170 server.cluster->cant_failover_reason = CLUSTER_CANT_FAILOVER_NONE;
3171 return;
3172 }
3173
3174 /* Set data_age to the number of milliseconds we are disconnected from
3175 * the master. */
3176 if (server.repl_state == REPL_STATE_CONNECTED) {
3177 data_age = (mstime_t)(server.unixtime - server.master->lastinteraction)
3178 * 1000;
3179 } else {
3180 data_age = (mstime_t)(server.unixtime - server.repl_down_since) * 1000;
3181 }
3182
3183 /* Remove the node timeout from the data age as it is fine that we are
3184 * disconnected from our master at least for the time it was down to be
3185 * flagged as FAIL, that's the baseline. */
3186 if (data_age > server.cluster_node_timeout)
3187 data_age -= server.cluster_node_timeout;
3188
3189 /* Check if our data is recent enough according to the slave validity
3190 * factor configured by the user.
3191 *

Callers 2

clusterCronFunction · 0.85
clusterBeforeSleepFunction · 0.85

Calls 9

clusterLogCantFailoverFunction · 0.85
clusterGetSlaveRankFunction · 0.85
clusterDoBeforeSleepFunction · 0.85
clusterBroadcastPongFunction · 0.85
mstimeFunction · 0.70
randomFunction · 0.50

Tested by

no test coverage detected