Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
593ce5b206 | ||
|
|
f2739ca9c4 | ||
|
|
e8d35809c4 | ||
|
|
4b68dbcbd7 | ||
|
|
17b0d99d9f |
+7
-2
@@ -827,8 +827,7 @@ void freeClient(client *c) {
|
||||
serverLog(LL_WARNING,"Connection with master lost.");
|
||||
if (!(c->flags & (CLIENT_CLOSE_AFTER_REPLY|
|
||||
CLIENT_CLOSE_ASAP|
|
||||
CLIENT_BLOCKED|
|
||||
CLIENT_UNBLOCKED)))
|
||||
CLIENT_BLOCKED)))
|
||||
{
|
||||
replicationCacheMaster(c);
|
||||
return;
|
||||
@@ -1362,6 +1361,12 @@ void processInputBuffer(client *c) {
|
||||
/* Immediately abort if the client is in the middle of something. */
|
||||
if (c->flags & CLIENT_BLOCKED) break;
|
||||
|
||||
/* Don't process input from the master while there is a busy script
|
||||
* condition on the slave. We want just to accumulate the replication
|
||||
* stream (instead of replying -BUSY like we do with other clients) and
|
||||
* later resume the processing. */
|
||||
if (server.lua_timedout && c->flags & CLIENT_MASTER) break;
|
||||
|
||||
/* CLIENT_CLOSE_AFTER_REPLY closes the connection once the reply is
|
||||
* written to the client. Make sure to not let the reply grow after
|
||||
* this flag has been set (i.e. don't process more commands).
|
||||
|
||||
+10
-5
@@ -1222,11 +1222,12 @@ sds luaCreateFunction(client *c, lua_State *lua, robj *body) {
|
||||
|
||||
/* This is the Lua script "count" hook that we use to detect scripts timeout. */
|
||||
void luaMaskCountHook(lua_State *lua, lua_Debug *ar) {
|
||||
long long elapsed;
|
||||
long long elapsed = mstime() - server.lua_time_start;
|
||||
UNUSED(ar);
|
||||
UNUSED(lua);
|
||||
|
||||
elapsed = mstime() - server.lua_time_start;
|
||||
/* Set the timeout condition if not already set and the maximum
|
||||
* execution time was reached. */
|
||||
if (elapsed >= server.lua_time_limit && server.lua_timedout == 0) {
|
||||
serverLog(LL_WARNING,"Lua slow script detected: still in execution after %lld milliseconds. You can try killing the script using the SCRIPT KILL command.",elapsed);
|
||||
server.lua_timedout = 1;
|
||||
@@ -1345,9 +1346,7 @@ void evalGenericCommand(client *c, int evalsha) {
|
||||
server.lua_caller = c;
|
||||
server.lua_time_start = mstime();
|
||||
server.lua_kill = 0;
|
||||
if (server.lua_time_limit > 0 && server.masterhost == NULL &&
|
||||
ldb.active == 0)
|
||||
{
|
||||
if (server.lua_time_limit > 0 && ldb.active == 0) {
|
||||
lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
|
||||
delhook = 1;
|
||||
} else if (ldb.active) {
|
||||
@@ -1368,6 +1367,10 @@ void evalGenericCommand(client *c, int evalsha) {
|
||||
* script timeout was detected. */
|
||||
aeCreateFileEvent(server.el,c->fd,AE_READABLE,
|
||||
readQueryFromClient,c);
|
||||
if (server.masterhost && server.master) {
|
||||
server.master->flags |= CLIENT_UNBLOCKED;
|
||||
listAddNodeTail(server.unblocked_clients,server.master);
|
||||
}
|
||||
}
|
||||
server.lua_caller = NULL;
|
||||
|
||||
@@ -1497,6 +1500,8 @@ NULL
|
||||
} else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"kill")) {
|
||||
if (server.lua_caller == NULL) {
|
||||
addReplySds(c,sdsnew("-NOTBUSY No scripts in execution right now.\r\n"));
|
||||
} else if (server.lua_caller->flags & CLIENT_MASTER) {
|
||||
addReplySds(c,sdsnew("-UNKILLABLE The busy script was sent by a master instance in the context of replication and cannot be killed.\r\n"));
|
||||
} else if (server.lua_write_dirty) {
|
||||
addReplySds(c,sdsnew("-UNKILLABLE Sorry the script already executed write commands against the dataset. You can either wait the script termination or kill the server in a hard way using the SHUTDOWN NOSAVE command.\r\n"));
|
||||
} else {
|
||||
|
||||
@@ -266,3 +266,47 @@ foreach dl {no yes} {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
start_server {tags {"repl"}} {
|
||||
set master [srv 0 client]
|
||||
set master_host [srv 0 host]
|
||||
set master_port [srv 0 port]
|
||||
set load_handle0 [start_write_load $master_host $master_port 3]
|
||||
start_server {} {
|
||||
test "Master stream is correctly processed while the slave has a script in -BUSY state" {
|
||||
set slave [srv 0 client]
|
||||
puts [srv 0 port]
|
||||
$slave config set lua-time-limit 500
|
||||
$slave slaveof $master_host $master_port
|
||||
|
||||
# Wait for the slave to be online
|
||||
wait_for_condition 500 100 {
|
||||
[lindex [$slave role] 3] eq {connected}
|
||||
} else {
|
||||
fail "Slave still not connected after some time"
|
||||
}
|
||||
|
||||
# Wait some time to make sure the master is sending data
|
||||
# to the slave.
|
||||
after 5000
|
||||
|
||||
# Stop the ability of the slave to process data by sendig
|
||||
# a script that will put it in BUSY state.
|
||||
$slave eval {for i=1,3000000000 do end} 0
|
||||
|
||||
# Wait some time again so that more master stream will
|
||||
# be processed.
|
||||
after 2000
|
||||
|
||||
# Stop the write load
|
||||
stop_write_load $load_handle0
|
||||
|
||||
# number of keys
|
||||
wait_for_condition 500 100 {
|
||||
[$master debug digest] eq [$slave debug digest]
|
||||
} else {
|
||||
fail "Different datasets between slave and master"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user