]> git.saurik.com Git - redis.git/commitdiff
config option to select if when replication link with master a slave should or not...
authorantirez <antirez@gmail.com>
Thu, 4 Nov 2010 18:59:21 +0000 (19:59 +0100)
committerantirez <antirez@gmail.com>
Thu, 4 Nov 2010 18:59:21 +0000 (19:59 +0100)
redis.conf
src/config.c
src/redis.c
src/redis.h

index 36f650ed0e3322ac0e408443758f21842659d530..bb30dcae60fb65a357b9dff1939da05d505337e0 100644 (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
index 2b5063c8fa7919ba2c629588d9ce05f785c540d7..772ac764ed986052ddcc1359b4174b0bb2aa5628 100644 (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);
 }
 
index 971dfecad13a7594ed85253c31b1b2887eb95718..8519f46fffd50134b30013233a2b636d9f2db1ff 100644 (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 &&
index d26e3c7971dfb7781ffb0a462e619eb898e34621..043825af769708981063a726613425d5842a10f4 100644 (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;