diff options
author | antirez <antirez@gmail.com> | 2014-01-08 14:25:06 +0100 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2014-01-08 14:27:49 +0100 |
commit | 2a1a31ca9d41032af705c0de673ac984a73cb73a (patch) | |
tree | ac9a97cae018591d10fb67ebbfed7c679554aade | |
parent | 418d3d358a1a09a59eec74bcc92649162585f8ec (diff) | |
download | redis-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.h | 2 | ||||
-rw-r--r-- | src/replication.c | 15 |
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]; |