mirror of https://mirror.osredm.com/root/redis.git
Correctly handle scripts with shebang (not read-only) on a cluster replica (#11223)
EVAL scripts are by default not considered `write` commands, so they were allowed on a replica. But when adding a shebang, they become `write` command (unless the `no-writes` flag is added). With this change we'll handle them as write commands, and reply with MOVED instead of READONLY when executed on a redis cluster replica. Co-authored-by: chendianqiang <chendianqiang@meituan.com>
This commit is contained in:
parent
87e7973c7e
commit
e42d98ed27
|
@ -6797,6 +6797,7 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
|
||||||
* without redirections or errors in all the cases. */
|
* without redirections or errors in all the cases. */
|
||||||
if (n == NULL) return myself;
|
if (n == NULL) return myself;
|
||||||
|
|
||||||
|
uint64_t cmd_flags = getCommandFlags(c);
|
||||||
/* Cluster is globally down but we got keys? We only serve the request
|
/* Cluster is globally down but we got keys? We only serve the request
|
||||||
* if it is a read command and when allow_reads_when_down is enabled. */
|
* if it is a read command and when allow_reads_when_down is enabled. */
|
||||||
if (server.cluster->state != CLUSTER_OK) {
|
if (server.cluster->state != CLUSTER_OK) {
|
||||||
|
@ -6810,7 +6811,7 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
|
||||||
* cluster is down. */
|
* cluster is down. */
|
||||||
if (error_code) *error_code = CLUSTER_REDIR_DOWN_STATE;
|
if (error_code) *error_code = CLUSTER_REDIR_DOWN_STATE;
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (cmd->flags & CMD_WRITE) {
|
} else if (cmd_flags & CMD_WRITE) {
|
||||||
/* The cluster is configured to allow read only commands */
|
/* The cluster is configured to allow read only commands */
|
||||||
if (error_code) *error_code = CLUSTER_REDIR_DOWN_RO_STATE;
|
if (error_code) *error_code = CLUSTER_REDIR_DOWN_RO_STATE;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -6848,7 +6849,7 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
|
||||||
* involves multiple keys and we don't have them all, the only option is
|
* involves multiple keys and we don't have them all, the only option is
|
||||||
* to send a TRYAGAIN error. */
|
* to send a TRYAGAIN error. */
|
||||||
if (importing_slot &&
|
if (importing_slot &&
|
||||||
(c->flags & CLIENT_ASKING || cmd->flags & CMD_ASKING))
|
(c->flags & CLIENT_ASKING || cmd_flags & CMD_ASKING))
|
||||||
{
|
{
|
||||||
if (multiple_keys && missing_keys) {
|
if (multiple_keys && missing_keys) {
|
||||||
if (error_code) *error_code = CLUSTER_REDIR_UNSTABLE;
|
if (error_code) *error_code = CLUSTER_REDIR_UNSTABLE;
|
||||||
|
@ -6861,7 +6862,7 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
|
||||||
/* Handle the read-only client case reading from a slave: if this
|
/* Handle the read-only client case reading from a slave: if this
|
||||||
* node is a slave and the request is about a hash slot our master
|
* node is a slave and the request is about a hash slot our master
|
||||||
* is serving, we can reply without redirection. */
|
* is serving, we can reply without redirection. */
|
||||||
int is_write_command = (c->cmd->flags & CMD_WRITE) ||
|
int is_write_command = (cmd_flags & CMD_WRITE) ||
|
||||||
(c->cmd->proc == execCommand && (c->mstate.cmd_flags & CMD_WRITE));
|
(c->cmd->proc == execCommand && (c->mstate.cmd_flags & CMD_WRITE));
|
||||||
if (((c->flags & CLIENT_READONLY) || is_pubsubshard) &&
|
if (((c->flags & CLIENT_READONLY) || is_pubsubshard) &&
|
||||||
!is_write_command &&
|
!is_write_command &&
|
||||||
|
|
|
@ -69,3 +69,11 @@ test "read-only blocking operations from replica" {
|
||||||
assert {$res eq {foo bar}}
|
assert {$res eq {foo bar}}
|
||||||
$rd close
|
$rd close
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "reply MOVED when eval from replica for update" {
|
||||||
|
catch {[$replica eval {#!lua
|
||||||
|
return redis.call('del','a')
|
||||||
|
} 1 a
|
||||||
|
]} err
|
||||||
|
assert {[string range $err 0 4] eq {MOVED}}
|
||||||
|
}
|
Loading…
Reference in New Issue