]> git.saurik.com Git - redis.git/commitdiff
Fix for slaves chains. Force resync of slaves (simply disconnecting them) when SLAVE...
authorantirez <antirez@gmail.com>
Thu, 29 Mar 2012 07:24:02 +0000 (09:24 +0200)
committerantirez <antirez@gmail.com>
Thu, 29 Mar 2012 07:24:02 +0000 (09:24 +0200)
src/networking.c
src/redis.h
src/replication.c

index 937f8402a5613e30d6d0bc46dab2f4d2e3e7eb1e..406d1cde3bc6891e6bbda6e65605e50cfcec43d3 100644 (file)
@@ -547,6 +547,16 @@ static void freeClientArgv(redisClient *c) {
     c->cmd = NULL;
 }
 
+/* Close all the slaves connections. This is useful in chained replication
+ * when we resync with our own master and want to force all our slaves to
+ * resync with us as well. */
+void disconnectSlaves(void) {
+    while (listLength(server.slaves)) {
+        listNode *ln = listFirst(server.slaves);
+        freeClient((redisClient*)ln->value);
+    }
+}
+
 void freeClient(redisClient *c) {
     listNode *ln;
 
@@ -605,21 +615,12 @@ void freeClient(redisClient *c) {
         server.master = NULL;
         server.repl_state = REDIS_REPL_CONNECT;
         server.repl_down_since = server.unixtime;
-        /* Since we lost the connection with the master, we should also
-         * close the connection with all our slaves if we have any, so
-         * when we'll resync with the master the other slaves will sync again
-         * with us as well. Note that also when the slave is not connected
-         * to the master it will keep refusing connections by other slaves.
+        /* We lost connection with our master, force our slaves to resync
+         * with us as well to load the new data set.
          *
-         * We do this only if server.masterhost != NULL. If it is NULL this
-         * means the user called SLAVEOF NO ONE and we are freeing our
-         * link with the master, so no need to close link with slaves. */
-        if (server.masterhost != NULL) {
-            while (listLength(server.slaves)) {
-                ln = listFirst(server.slaves);
-                freeClient((redisClient*)ln->value);
-            }
-        }
+         * If server.masterhost is NULL te user called SLAVEOF NO ONE so
+         * slave resync is not needed. */
+        if (server.masterhost != NULL) disconnectSlaves();
     }
 
     /* If this client was scheduled for async freeing we need to remove it
index 41e245575cec87efc83691f627244db13dc29025..5a3d1a9c5f42f987f374b5f8bd74fec0ffa0f17f 100644 (file)
@@ -869,6 +869,7 @@ void asyncCloseClientOnOutputBufferLimitReached(redisClient *c);
 int getClientLimitClassByName(char *name);
 char *getClientLimitClassName(int class);
 void flushSlavesOutputBuffers(void);
+void disconnectSlaves(void);
 
 #ifdef __GNUC__
 void addReplyErrorFormat(redisClient *c, const char *fmt, ...)
index 170bee73e1e284ad4052f4de1bd22d4d26d28c9c..c99be32aff6c36be1878a06e5e8d83331a4a263f 100644 (file)
@@ -541,6 +541,7 @@ void slaveofCommand(redisClient *c) {
         server.masterhost = sdsdup(c->argv[1]->ptr);
         server.masterport = port;
         if (server.master) freeClient(server.master);
+        disconnectSlaves(); /* Force our slaves to resync with us as well. */
         if (server.repl_state == REDIS_REPL_TRANSFER)
             replicationAbortSyncTransfer();
         server.repl_state = REDIS_REPL_CONNECT;