Merge 897d36ebf3edef34f429ad2c95c83b377cc26ca7 into 26c6f1af9b29d525831c7fa9840ab3e47ed7b700

This commit is contained in:
John Sully 2025-02-01 07:51:52 -08:00 committed by GitHub
commit c544e43a3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 7 deletions

View File

@ -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

View File

@ -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()) {