]> git.saurik.com Git - redis.git/blobdiff - src/replication.c
Fix: when aof_write_rewrite is true don't append on the AOF buffer but accumulate...
[redis.git] / src / replication.c
index 712af110f41a1e2435491c9899bf27ecfdc09a05..2be03c1b49d08a316d83056b1ebae36cbcca2579 100644 (file)
@@ -358,8 +358,22 @@ void readSyncBulkPayload(aeEventLoop *el, int fd, void *privdata, int mask) {
         server.master->authenticated = 1;
         server.replstate = REDIS_REPL_CONNECTED;
         redisLog(REDIS_NOTICE, "MASTER <-> SLAVE sync: Finished with success");
-        /* Rewrite the AOF file now that the dataset changed. */
-        if (server.appendonly) rewriteAppendOnlyFileBackground();
+        /* Restart the AOF subsystem now that we finished the sync. This
+         * will trigger an AOF rewrite, and when done will start appending
+         * to the new file. */
+        if (server.appendonly) {
+            int retry = 10;
+
+            stopAppendOnly();
+            while (retry-- && startAppendOnly() == REDIS_ERR) {
+                redisLog(REDIS_WARNING,"Failed enabling the AOF after successful master synchrnization! Trying it again in one second.");
+                sleep(1);
+            }
+            if (!retry) {
+                redisLog(REDIS_WARNING,"FATAL: this slave instance finished the synchronization with its master, but the AOF can't be turned on. Exiting now.");
+                exit(1);
+            }
+        }
     }
 
     return;
@@ -471,11 +485,24 @@ int connectWithMaster(void) {
         return REDIS_ERR;
     }
 
+    server.repl_transfer_lastio = time(NULL);
     server.repl_transfer_s = fd;
     server.replstate = REDIS_REPL_CONNECTING;
     return REDIS_OK;
 }
 
+/* This function can be called when a non blocking connection is currently
+ * in progress to undo it. */
+void undoConnectWithMaster(void) {
+    int fd = server.repl_transfer_s;
+
+    redisAssert(server.replstate == REDIS_REPL_CONNECTING);
+    aeDeleteFileEvent(server.el,fd,AE_READABLE|AE_WRITABLE);
+    close(fd);
+    server.repl_transfer_s = -1;
+    server.replstate = REDIS_REPL_CONNECT;
+}
+
 void slaveofCommand(redisClient *c) {
     if (!strcasecmp(c->argv[1]->ptr,"no") &&
         !strcasecmp(c->argv[2]->ptr,"one")) {
@@ -485,6 +512,8 @@ void slaveofCommand(redisClient *c) {
             if (server.master) freeClient(server.master);
             if (server.replstate == REDIS_REPL_TRANSFER)
                 replicationAbortSyncTransfer();
+            else if (server.replstate == REDIS_REPL_CONNECTING)
+                undoConnectWithMaster();
             server.replstate = REDIS_REPL_NONE;
             redisLog(REDIS_NOTICE,"MASTER MODE enabled (user request)");
         }
@@ -505,6 +534,14 @@ void slaveofCommand(redisClient *c) {
 /* --------------------------- REPLICATION CRON  ---------------------------- */
 
 void replicationCron(void) {
+    /* Non blocking connection timeout? */
+    if (server.masterhost && server.replstate == REDIS_REPL_CONNECTING &&
+        (time(NULL)-server.repl_transfer_lastio) > server.repl_timeout)
+    {
+        redisLog(REDIS_WARNING,"Timeout connecting to the MASTER...");
+        undoConnectWithMaster();
+    }
+
     /* Bulk transfer I/O timeout? */
     if (server.masterhost && server.replstate == REDIS_REPL_TRANSFER &&
         (time(NULL)-server.repl_transfer_lastio) > server.repl_timeout)