Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions src/cluster_legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -2211,6 +2211,12 @@ void markNodeAsFailingIfNeeded(clusterNode *node) {
* so here the replica is only helping propagating this status. */
clusterSendFail(node->name);
clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG);

if (nodeIsReplica(myself) && myself->replicaof == node) {
/* Immediately check if the node is our primary node, if so, we can try
* to initiate a failover as soon as possible. */
clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FASTER_FAILOVER);
}
}

/* This function is called only if a node is marked as FAIL, but we are able
Expand Down Expand Up @@ -3543,6 +3549,12 @@ int clusterProcessPacket(clusterLink *link) {
noaddr_node->flags |= CLUSTER_NODE_FAIL;
noaddr_node->fail_time = now;
clusterSendFail(noaddr_node->name);

if (nodeIsReplica(myself) && myself->replicaof == noaddr_node) {
/* Immediately check if the node is our primary node, if so, we can try
* to initiate a failover as soon as possible. */
clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FASTER_FAILOVER);
}
}
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE);
return 0;
Expand Down Expand Up @@ -3777,6 +3789,15 @@ int clusterProcessPacket(clusterLink *link) {
failing->fail_time = now;
failing->flags &= ~CLUSTER_NODE_PFAIL;
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE);

if (nodeIsReplica(myself) && myself->replicaof == failing) {
/* Immediately check if the node is our primary node, if so, we can try
* to initiate a failover as soon as possible. We will also try to send
* the FAIL packet in case we trigger the failover immediately but unable
* to get the votes. */
clusterSendFail(failing->name);
clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FASTER_FAILOVER);
}
}
} else {
serverLog(LL_NOTICE, "Ignoring FAIL message from unknown node %.40s about %.40s", hdr->sender,
Expand Down Expand Up @@ -4963,7 +4984,6 @@ void clusterHandleReplicaFailover(void) {
* elapsed, we can setup a new one. */
if (auth_age > auth_retry_time) {
server.cluster->failover_auth_time = now +
500 + /* Fixed delay of 500 milliseconds, let FAIL msg propagate. */
random() % 500; /* Random delay between 0 and 500 milliseconds. */
server.cluster->failover_auth_count = 0;
server.cluster->failover_auth_sent = 0;
Expand All @@ -4984,6 +5004,11 @@ void clusterHandleReplicaFailover(void) {
/* Reset auth_age since it is outdated now and we can bypass the auth_timeout
* check in the next state and start the election ASAP. */
auth_age = 0;
} else if (server.cluster->failover_auth_time == now) {
/* If we happen to initiate a failover immediately, reset auth_age since it is
* outdated now and we can bypass the auth_timeout check in the next state and
* start the election ASAP. */
auth_age = 0;
}
serverLog(LL_NOTICE,
"Start of election delayed for %lld milliseconds "
Expand Down Expand Up @@ -5573,7 +5598,8 @@ void clusterBeforeSleep(void) {
}
} else if (flags & CLUSTER_TODO_HANDLE_FAILOVER) {
/* Handle failover, this is needed when it is likely that there is already
* the quorum from primaries in order to react fast. */
* the quorum from primaries in order to react fast. Or when we determine
* that we can proceed with the failover. */
clusterHandleReplicaFailover();
}

Expand All @@ -5592,6 +5618,12 @@ void clusterBeforeSleep(void) {
* regular ping. */
clusterBroadcastPong(CLUSTER_BROADCAST_ALL);
}

if (flags & CLUSTER_TODO_HANDLE_FASTER_FAILOVER) {
/* Handle faster failover, this goes after all the todos to check if we
* can initiate a fast failover. */
clusterHandleReplicaFailover();
}
}

void clusterDoBeforeSleep(int flags) {
Expand Down
1 change: 1 addition & 0 deletions src/cluster_legacy.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define CLUSTER_TODO_FSYNC_CONFIG (1 << 3)
#define CLUSTER_TODO_HANDLE_MANUALFAILOVER (1 << 4)
#define CLUSTER_TODO_BROADCAST_ALL (1 << 5)
#define CLUSTER_TODO_HANDLE_FASTER_FAILOVER (1 << 6)

/* clusterLink encapsulates everything needed to talk with a remote node. */
typedef struct clusterLink {
Expand Down
Loading