Unverified Commit 78960ad5 authored by Huang Zhw's avatar Huang Zhw Committed by GitHub
Browse files

Throw -TRYAGAIN instead of -ASK on migrating nodes for multi-key commands when...

Throw -TRYAGAIN instead of -ASK on migrating nodes for multi-key commands when the node only has some of the keys (#9526)

* In cluster getNodeByQuery when target slot is in migrating state and
the slot lack some keys but have at least one key, should return TRYAGAIN.

Before this commit, when a node is in migrating state and recevies
multiple keys command, if some keys don't exist, the command emits
an `ASK` redirection.

After this commit, if some keys exist and some keys don't exist, the
command emits a TRYAGAIN error. If all keys don't exist, the command
emits an `ASK` redirection.
parent 0a2f7883
...@@ -6583,7 +6583,8 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in ...@@ -6583,7 +6583,8 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
int multiple_keys = 0; int multiple_keys = 0;
multiState *ms, _ms; multiState *ms, _ms;
multiCmd mc; multiCmd mc;
int i, slot = 0, migrating_slot = 0, importing_slot = 0, missing_keys = 0; int i, slot = 0, migrating_slot = 0, importing_slot = 0, missing_keys = 0,
existing_keys = 0;
/* Allow any key to be set if a module disabled cluster redirections. */ /* Allow any key to be set if a module disabled cluster redirections. */
if (server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_REDIRECTION) if (server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_REDIRECTION)
...@@ -6695,10 +6696,10 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in ...@@ -6695,10 +6696,10 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
* node until the migration completes with CLUSTER SETSLOT <slot> * node until the migration completes with CLUSTER SETSLOT <slot>
* NODE <node-id>. */ * NODE <node-id>. */
int flags = LOOKUP_NOTOUCH | LOOKUP_NOSTATS | LOOKUP_NONOTIFY; int flags = LOOKUP_NOTOUCH | LOOKUP_NOSTATS | LOOKUP_NONOTIFY;
if ((migrating_slot || importing_slot) && !is_pubsubshard && if ((migrating_slot || importing_slot) && !is_pubsubshard)
lookupKeyReadWithFlags(&server.db[0], thiskey, flags) == NULL)
{ {
missing_keys++; if (lookupKeyReadWithFlags(&server.db[0], thiskey, flags) == NULL) missing_keys++;
else existing_keys++;
} }
} }
getKeysFreeResult(&result); getKeysFreeResult(&result);
...@@ -6742,10 +6743,16 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in ...@@ -6742,10 +6743,16 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
return myself; return myself;
/* If we don't have all the keys and we are migrating the slot, send /* If we don't have all the keys and we are migrating the slot, send
* an ASK redirection. */ * an ASK redirection or TRYAGAIN. */
if (migrating_slot && missing_keys) { if (migrating_slot && missing_keys) {
if (error_code) *error_code = CLUSTER_REDIR_ASK; /* If we have keys but we don't have all keys, we return TRYAGAIN */
return server.cluster->migrating_slots_to[slot]; if (existing_keys) {
if (error_code) *error_code = CLUSTER_REDIR_UNSTABLE;
return NULL;
} else {
if (error_code) *error_code = CLUSTER_REDIR_ASK;
return server.cluster->migrating_slots_to[slot];
}
} }
/* If we are receiving the slot, and the client correctly flagged the /* If we are receiving the slot, and the client correctly flagged the
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment