diff --git a/src/cluster.c b/src/cluster.c index 1d55ccba..1f19db3e 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5065,7 +5065,10 @@ void readwriteCommand(client *c) { * CLUSTER_REDIR_DOWN_UNBOUND if the request addresses a slot which is * not bound to any node. In this case the cluster global state should be * already "down" but it is fragile to rely on the update of the global state, - * so we also handle it here. */ + * so we also handle it here. + * + * CLUSTER_REDIR_DOWN_STATE if the cluster is down but the user attempts to + * execute a command that addresses one or more keys. */ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *error_code) { clusterNode *n = NULL; robj *firstkey = NULL; @@ -5172,9 +5175,15 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in } /* No key at all in command? then we can serve the request - * without redirections or errors. */ + * without redirections or errors in all the cases. */ if (n == NULL) return myself; + /* Cluster is globally down but we got keys? We can't serve the request. */ + if (server.cluster->state != CLUSTER_OK) { + if (error_code) *error_code = CLUSTER_REDIR_DOWN_STATE; + return NULL; + } + /* Return the hashslot by reference. */ if (hashslot) *hashslot = slot; diff --git a/src/server.c b/src/server.c index bd56ceeb..3e0ed8df 100644 --- a/src/server.c +++ b/src/server.c @@ -2391,23 +2391,17 @@ int processCommand(client *c) { c->cmd->proc != execCommand)) { int hashslot; - - if (server.cluster->state != CLUSTER_OK) { - flagTransaction(c); - clusterRedirectClient(c,NULL,0,CLUSTER_REDIR_DOWN_STATE); - return C_OK; - } else { - int error_code; - clusterNode *n = getNodeByQuery(c,c->cmd,c->argv,c->argc,&hashslot,&error_code); - if (n == NULL || n != server.cluster->myself) { - if (c->cmd->proc == execCommand) { - discardTransaction(c); - } else { - flagTransaction(c); - } - clusterRedirectClient(c,n,hashslot,error_code); - return C_OK; + int error_code; + clusterNode *n = getNodeByQuery(c,c->cmd,c->argv,c->argc, + &hashslot,&error_code); + if (n == NULL || n != server.cluster->myself) { + if (c->cmd->proc == execCommand) { + discardTransaction(c); + } else { + flagTransaction(c); } + clusterRedirectClient(c,n,hashslot,error_code); + return C_OK; } }