summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2018-09-05 13:20:12 +0200
committerantirez <antirez@gmail.com>2018-09-05 19:55:45 +0200
commitdfbce91a14f24da27e61405ef64d3690184b0ef4 (patch)
tree7745cbf538838c7e6bb8cccf518c84792fdbe523
parent1705e42eb2cc4e7c68a09c77f15c3d99b78b4ec1 (diff)
downloadredis-dfbce91a14f24da27e61405ef64d3690184b0ef4.tar.gz
Propagate read-only scripts as SCRIPT LOAD.
See issue #5250 and the new comments added to the code in this commit for details.
-rw-r--r--src/scripting.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/scripting.c b/src/scripting.c
index 8aa62071c..4b5b0002f 100644
--- a/src/scripting.c
+++ b/src/scripting.c
@@ -1250,6 +1250,7 @@ void evalGenericCommand(client *c, int evalsha) {
lua_State *lua = server.lua;
char funcname[43];
long long numkeys;
+ long long initial_server_dirty = server.dirty;
int delhook = 0, err;
/* When we replicate whole scripts, we want the same PRNG sequence at
@@ -1432,9 +1433,21 @@ void evalGenericCommand(client *c, int evalsha) {
replicationScriptCacheAdd(c->argv[1]->ptr);
serverAssertWithInfo(c,NULL,script != NULL);
- rewriteClientCommandArgument(c,0,
- resetRefCount(createStringObject("EVAL",4)));
- rewriteClientCommandArgument(c,1,script);
+
+ /* If the script did not produce any changes in the dataset we want
+ * just to replicate it as SCRIPT LOAD, otherwise we risk running
+ * an aborted script on slaves (that may then produce results there)
+ * or just running a CPU costly read-only script on the slaves. */
+ if (server.dirty == initial_server_dirty) {
+ rewriteClientCommandVector(c,3,
+ resetRefCount(createStringObject("SCRIPT",6)),
+ resetRefCount(createStringObject("LOAD",4)),
+ script);
+ } else {
+ rewriteClientCommandArgument(c,0,
+ resetRefCount(createStringObject("EVAL",4)));
+ rewriteClientCommandArgument(c,1,script);
+ }
forceCommandPropagation(c,PROPAGATE_REPL|PROPAGATE_AOF);
}
}