summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2014-01-08 14:25:06 +0100
committerantirez <antirez@gmail.com>2014-01-08 14:27:49 +0100
commit2a1a31ca9d41032af705c0de673ac984a73cb73a (patch)
treeac9a97cae018591d10fb67ebbfed7c679554aade
parent418d3d358a1a09a59eec74bcc92649162585f8ec (diff)
downloadredis-2a1a31ca9d41032af705c0de673ac984a73cb73a.tar.gz
Don't send REPLCONF ACK to old masters.
Masters not understanding REPLCONF ACK will reply with errors to our requests causing a number of possible issues. This commit detects a global replication offest set to -1 at the end of the replication, and marks the client representing the master with the REDIS_PRE_PSYNC flag. Note that this flag was called REDIS_PRE_PSYNC_SLAVE but now it is just REDIS_PRE_PSYNC as it is used for both slaves and masters starting with this commit. This commit fixes issue #1488.
-rw-r--r--src/redis.h2
-rw-r--r--src/replication.c15
2 files changed, 12 insertions, 5 deletions
diff --git a/src/redis.h b/src/redis.h
index 7cba7ad30..39ee45a0f 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -229,7 +229,7 @@
#define REDIS_MASTER_FORCE_REPLY (1<<13) /* Queue replies even if is master */
#define REDIS_FORCE_AOF (1<<14) /* Force AOF propagation of current cmd. */
#define REDIS_FORCE_REPL (1<<15) /* Force replication of current cmd. */
-#define REDIS_PRE_PSYNC_SLAVE (1<<16) /* Slave don't understand PSYNC. */
+#define REDIS_PRE_PSYNC (1<<16) /* Instance don't understand PSYNC. */
/* Client request types */
#define REDIS_REQ_INLINE 1
diff --git a/src/replication.c b/src/replication.c
index c480c9e82..d585ff1f9 100644
--- a/src/replication.c
+++ b/src/replication.c
@@ -458,7 +458,7 @@ void syncCommand(redisClient *c) {
/* If a slave uses SYNC, we are dealing with an old implementation
* of the replication protocol (like redis-cli --slave). Flag the client
* so that we don't expect to receive REPLCONF ACK feedbacks. */
- c->flags |= REDIS_PRE_PSYNC_SLAVE;
+ c->flags |= REDIS_PRE_PSYNC;
}
/* Full resynchronization. */
@@ -829,6 +829,10 @@ void readSyncBulkPayload(aeEventLoop *el, int fd, void *privdata, int mask) {
server.master->reploff = server.repl_master_initial_offset;
memcpy(server.master->replrunid, server.repl_master_runid,
sizeof(server.repl_master_runid));
+ /* If master offset is set to -1, this master is old and is not
+ * PSYNC capable, so we flag it accordingly. */
+ if (server.master->reploff == -1)
+ server.master->flags |= REDIS_PRE_PSYNC;
redisLog(REDIS_NOTICE, "MASTER <-> SLAVE sync: Finished with success");
/* Restart the AOF subsystem now that we finished the sync. This
* will trigger an AOF rewrite, and when done will start appending
@@ -1554,8 +1558,11 @@ void replicationCron(void) {
}
}
- /* Send ACK to master from time to time. */
- if (server.masterhost && server.master)
+ /* Send ACK to master from time to time.
+ * Note that we do not send periodic acks to masters that don't
+ * support PSYNC and replication offsets. */
+ if (server.masterhost && server.master &&
+ !(server.master->flags & REDIS_PRE_PSYNC))
replicationSendAck();
/* If we have attached slaves, PING them from time to time.
@@ -1599,7 +1606,7 @@ void replicationCron(void) {
redisClient *slave = ln->value;
if (slave->replstate != REDIS_REPL_ONLINE) continue;
- if (slave->flags & REDIS_PRE_PSYNC_SLAVE) continue;
+ if (slave->flags & REDIS_PRE_PSYNC) continue;
if ((server.unixtime - slave->repl_ack_time) > server.repl_timeout)
{
char ip[REDIS_IP_STR_LEN];