提交 5d73073f 编写于 作者: A antirez

Allow Pub/Sub in contexts where other commands are blocked.

Redis loading data from disk, and a Redis slave disconnected from its
master with serve-stale-data disabled, are two conditions where
commands are normally refused by Redis, returning an error.

However there is no reason to disable Pub/Sub commands as well, given
that this layer does not interact with the dataset. To allow Pub/Sub in
as many contexts as possible is especially interesting now that Redis
Sentinel uses Pub/Sub of a Redis master as a communication channel
between Sentinels.

This commit allows Pub/Sub to be used in the above two contexts where
it was previously denied.
上级 b62bdf1c
......@@ -106,6 +106,10 @@ struct redisCommand *commandTable;
* results. For instance SPOP and RANDOMKEY are two random commands.
* S: Sort command output array if called from script, so that the output
* is deterministic.
* l: Allow command while loading the database.
* t: Allow command while a slave has stale data but is not allowed to
* server this data. Normally no command is accepted in this condition
* but just a few.
*/
struct redisCommand redisCommandTable[] = {
{"get",getCommand,2,"r",0,NULL,1,1,1,0,0},
......@@ -219,19 +223,19 @@ struct redisCommand redisCommandTable[] = {
{"flushdb",flushdbCommand,1,"w",0,NULL,0,0,0,0,0},
{"flushall",flushallCommand,1,"w",0,NULL,0,0,0,0,0},
{"sort",sortCommand,-2,"wmS",0,NULL,1,1,1,0,0},
{"info",infoCommand,-1,"r",0,NULL,0,0,0,0,0},
{"info",infoCommand,-1,"rlt",0,NULL,0,0,0,0,0},
{"monitor",monitorCommand,1,"ars",0,NULL,0,0,0,0,0},
{"ttl",ttlCommand,2,"r",0,NULL,1,1,1,0,0},
{"pttl",pttlCommand,2,"r",0,NULL,1,1,1,0,0},
{"persist",persistCommand,2,"w",0,NULL,1,1,1,0,0},
{"slaveof",slaveofCommand,3,"as",0,NULL,0,0,0,0,0},
{"slaveof",slaveofCommand,3,"ast",0,NULL,0,0,0,0,0},
{"debug",debugCommand,-2,"as",0,NULL,0,0,0,0,0},
{"config",configCommand,-2,"ar",0,NULL,0,0,0,0,0},
{"subscribe",subscribeCommand,-2,"rps",0,NULL,0,0,0,0,0},
{"unsubscribe",unsubscribeCommand,-1,"rps",0,NULL,0,0,0,0,0},
{"psubscribe",psubscribeCommand,-2,"rps",0,NULL,0,0,0,0,0},
{"punsubscribe",punsubscribeCommand,-1,"rps",0,NULL,0,0,0,0,0},
{"publish",publishCommand,3,"pf",0,NULL,0,0,0,0,0},
{"subscribe",subscribeCommand,-2,"rpslt",0,NULL,0,0,0,0,0},
{"unsubscribe",unsubscribeCommand,-1,"rpslt",0,NULL,0,0,0,0,0},
{"psubscribe",psubscribeCommand,-2,"rpslt",0,NULL,0,0,0,0,0},
{"punsubscribe",punsubscribeCommand,-1,"rpslt",0,NULL,0,0,0,0,0},
{"publish",publishCommand,3,"pflt",0,NULL,0,0,0,0,0},
{"watch",watchCommand,-2,"rs",0,noPreloadGetKeys,1,-1,1,0,0},
{"unwatch",unwatchCommand,1,"rs",0,NULL,0,0,0,0,0},
{"cluster",clusterCommand,-2,"ar",0,NULL,0,0,0,0,0},
......@@ -1381,6 +1385,8 @@ void populateCommandTable(void) {
case 's': c->flags |= REDIS_CMD_NOSCRIPT; break;
case 'R': c->flags |= REDIS_CMD_RANDOM; break;
case 'S': c->flags |= REDIS_CMD_SORT_FOR_SCRIPT; break;
case 'l': c->flags |= REDIS_CMD_LOADING; break;
case 't': c->flags |= REDIS_CMD_STALE; break;
default: redisPanic("Unsupported command flag"); break;
}
f++;
......@@ -1622,7 +1628,7 @@ int processCommand(redisClient *c) {
return REDIS_OK;
}
/* Don't accept wirte commands if this is a read only slave. But
/* Don't accept write commands if this is a read only slave. But
* accept write commands if this is our master. */
if (server.masterhost && server.repl_slave_ro &&
!(c->flags & REDIS_MASTER) &&
......@@ -1647,19 +1653,20 @@ int processCommand(redisClient *c) {
* we are a slave with a broken link with master. */
if (server.masterhost && server.repl_state != REDIS_REPL_CONNECTED &&
server.repl_serve_stale_data == 0 &&
c->cmd->proc != infoCommand && c->cmd->proc != slaveofCommand)
!(c->cmd->flags & REDIS_CMD_STALE))
{
addReply(c, shared.masterdownerr);
return REDIS_OK;
}
/* Loading DB? Return an error if the command is not INFO */
if (server.loading && c->cmd->proc != infoCommand) {
/* Loading DB? Return an error if the command has not the
* REDIS_CMD_LOADING flag. */
if (server.loading && !(c->cmd->flags & REDIS_CMD_LOADING)) {
addReply(c, shared.loadingerr);
return REDIS_OK;
}
/* Lua script too slow? Only allow SHUTDOWN NOSAVE and SCRIPT KILL. */
/* Lua script too slow? Only allow commands with REDIS_CMD_STALE flag. */
if (server.lua_timedout &&
!(c->cmd->proc == shutdownCommand &&
c->argc == 2 &&
......
......@@ -85,6 +85,8 @@
#define REDIS_CMD_NOSCRIPT 64 /* "s" flag */
#define REDIS_CMD_RANDOM 128 /* "R" flag */
#define REDIS_CMD_SORT_FOR_SCRIPT 256 /* "S" flag */
#define REDIS_CMD_LOADING 512 /* "l" flag */
#define REDIS_CMD_STALE 1024 /* "t" flag */
/* Object types */
#define REDIS_STRING 0
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册