config option to select if when replication link with master a slave should or not serve stale data

This commit is contained in:
antirez 2010-11-04 19:59:21 +01:00
parent 12ebe2ac17
commit 4ebfc45528
4 changed files with 42 additions and 1 deletions

View File

@ -110,6 +110,19 @@ dir ./
#
# masterauth <master-password>
# When a slave lost the connection with the master, or when the replication
# is still in progress, the slave can act in two different ways:
#
# 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will
# still reply to client requests, possibly with out of data data, or the
# data set may just be empty if this is the first synchronization.
#
# 2) if slave-serve-stale data is set to 'no' the slave will reply with
# an error "SYNC with master in progress" to all the kind of commands
# but to INFO and SLAVEOF.
#
slave-serve-stale-data yes
################################## SECURITY ###################################
# Require clients to issue AUTH <PASSWORD> before processing any other

View File

@ -152,6 +152,10 @@ void loadServerConfig(char *filename) {
server.replstate = REDIS_REPL_CONNECT;
} else if (!strcasecmp(argv[0],"masterauth") && argc == 2) {
server.masterauth = zstrdup(argv[1]);
} else if (!strcasecmp(argv[0],"slave-serve-stale-data") && argc == 2) {
if ((server.repl_serve_stale_data = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
}
} else if (!strcasecmp(argv[0],"glueoutputbuf") && argc == 2) {
if ((server.glueoutputbuf = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
@ -379,6 +383,11 @@ void configSetCommand(redisClient *c) {
appendServerSaveParams(seconds, changes);
}
sdsfreesplitres(v,vlen);
} else if (!strcasecmp(c->argv[2]->ptr,"slave-serve-stale-data")) {
int yn = yesnotoi(o->ptr);
if (yn == -1) goto badfmt;
server.repl_serve_stale_data = yn;
} else {
addReplyErrorFormat(c,"Unsupported CONFIG parameter: %s",
(char*)c->argv[2]->ptr);
@ -488,6 +497,11 @@ void configGetCommand(redisClient *c) {
sdsfree(buf);
matches++;
}
if (stringmatch(pattern,"slave-serve-stale-data",0)) {
addReplyBulkCString(c,"slave-serve-stale-data");
addReplyBulkCString(c,server.repl_serve_stale_data ? "yes" : "no");
matches++;
}
setDeferredMultiBulkLength(c,replylen,matches*2);
}

View File

@ -786,6 +786,7 @@ void initServerConfig() {
server.masterport = 6379;
server.master = NULL;
server.replstate = REDIS_REPL_NONE;
server.repl_serve_stale_data = 1;
/* Double constants initialization */
R_Zero = 0.0;
@ -994,6 +995,17 @@ int processCommand(redisClient *c) {
return REDIS_OK;
}
/* Only allow INFO and SLAVEOF when slave-serve-stale-data is no and
* we are a slave with a broken link with master. */
if (server.masterhost && server.replstate != REDIS_REPL_CONNECTED &&
server.repl_serve_stale_data == 0 &&
cmd->proc != infoCommand && cmd->proc != slaveofCommand)
{
addReplyError(c,
"link with MASTER is down and slave-serve-stale-data is set to no");
return REDIS_OK;
}
/* Exec the command */
if (c->flags & REDIS_MULTI &&
cmd->proc != execCommand && cmd->proc != discardCommand &&

View File

@ -361,7 +361,8 @@ struct redisServer {
long long dirty_before_bgsave; /* used to restore dirty on failed BGSAVE */
list *clients;
dict *commands; /* Command table hahs table */
struct redisCommand *delCommand, *multiCommand; /* often lookedup cmds */
/* Fast pointers to often looked up command */
struct redisCommand *delCommand, *multiCommand;
list *slaves, *monitors;
char neterr[ANET_ERR_LEN];
aeEventLoop *el;
@ -413,6 +414,7 @@ struct redisServer {
int repl_transfer_fd; /* slave -> master SYNC temp file descriptor */
char *repl_transfer_tmpfile; /* slave-> master SYNC temp file name */
time_t repl_transfer_lastio; /* unix time of the latest read, for timeout */
int repl_serve_stale_data; /* Serve stale data when link is down? */
/* Limits */
unsigned int maxclients;
unsigned long long maxmemory;