Merge 897d36ebf3edef34f429ad2c95c83b377cc26ca7 into 26c6f1af9b29d525831c7fa9840ab3e47ed7b700
This commit is contained in:
commit
c544e43a3d
@ -989,6 +989,7 @@ getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, int argc, int
|
||||
clusterNode *n = NULL;
|
||||
robj *firstkey = NULL;
|
||||
int multiple_keys = 0;
|
||||
int multi_slot = 0;
|
||||
multiState *ms, _ms;
|
||||
multiCmd mc;
|
||||
int i, slot = 0, migrating_slot = 0, importing_slot = 0, missing_keys = 0, existing_keys = 0;
|
||||
@ -1080,12 +1081,26 @@ getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, int argc, int
|
||||
}
|
||||
} else {
|
||||
/* If it is not the first key/channel, make sure it is exactly
|
||||
* the same key/channel as the first we saw. */
|
||||
* the same key/channel as the first we saw or an allowed crossslot situation. */
|
||||
int prevent_crossslot =
|
||||
(cmd_flags & CMD_WRITE) // eliminate issues with client->current_slot
|
||||
|| pubsubshard_included // pubsub does not benefit and too many edge cases
|
||||
|| c->cmd->proc == execCommand // We do not permit crossslot transactions to prevent client code
|
||||
// which will break when cluster topology changes
|
||||
// finally, if any key is migrating we cannot permit the crossslot since we don't check if the
|
||||
// specific keys are affected
|
||||
// this could potentially be relaxed in the future.
|
||||
|| migrating_slot || importing_slot || getMigratingSlotDest(thisslot) != NULL ||
|
||||
getImportingSlotSource(thisslot) != NULL || n != getNodeBySlot(thisslot);
|
||||
if (slot != thisslot) {
|
||||
/* Error: multiple keys from different slots. */
|
||||
getKeysFreeResult(&result);
|
||||
if (error_code) *error_code = CLUSTER_REDIR_CROSS_SLOT;
|
||||
return NULL;
|
||||
if (prevent_crossslot) {
|
||||
/* Error: multiple keys from different slots. */
|
||||
getKeysFreeResult(&result);
|
||||
if (error_code) *error_code = CLUSTER_REDIR_CROSS_SLOT;
|
||||
return NULL;
|
||||
} else {
|
||||
multi_slot = 1;
|
||||
}
|
||||
}
|
||||
if (importing_slot && !multiple_keys && !equalStringObjects(firstkey, thiskey)) {
|
||||
/* Flag this request as one with multiple different
|
||||
@ -1140,7 +1155,11 @@ getNodeByQuery(client *c, struct serverCommand *cmd, robj **argv, int argc, int
|
||||
}
|
||||
|
||||
/* Return the hashslot by reference. */
|
||||
if (hashslot) *hashslot = slot;
|
||||
if (hashslot) {
|
||||
// If we have multiple slots we disable slot caching on the client
|
||||
// In the future perhaps this optimization could be extended to work with multiple keys
|
||||
*hashslot = multi_slot ? -1 : slot;
|
||||
}
|
||||
|
||||
/* MIGRATE always works in the context of the local node if the slot
|
||||
* is open (migrating or importing state). We need to be able to freely
|
||||
|
@ -5645,7 +5645,8 @@ sds genValkeyInfoString(dict *section_dict, int all_sections, int everything) {
|
||||
"executable:%s\r\n", server.executable ? server.executable : "",
|
||||
"config_file:%s\r\n", server.configfile ? server.configfile : "",
|
||||
"io_threads_active:%i\r\n", server.active_io_threads_num > 1,
|
||||
"availability_zone:%s\r\n", server.availability_zone));
|
||||
"availability_zone:%s\r\n", server.availability_zone,
|
||||
"features:%s\r\n", "cluster_mget"));
|
||||
|
||||
/* Conditional properties */
|
||||
if (isShutdownInitiated()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user