"vscode:/vscode.git/clone" did not exist on "a31693417dba3b2ddad46386778e191daef85e21"
Commit 2a1a31ca authored by antirez's avatar antirez
Browse files

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.
parent 418d3d35
...@@ -229,7 +229,7 @@ ...@@ -229,7 +229,7 @@
#define REDIS_MASTER_FORCE_REPLY (1<<13) /* Queue replies even if is master */ #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_AOF (1<<14) /* Force AOF propagation of current cmd. */
#define REDIS_FORCE_REPL (1<<15) /* Force replication 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 */ /* Client request types */
#define REDIS_REQ_INLINE 1 #define REDIS_REQ_INLINE 1
......
...@@ -458,7 +458,7 @@ void syncCommand(redisClient *c) { ...@@ -458,7 +458,7 @@ void syncCommand(redisClient *c) {
/* If a slave uses SYNC, we are dealing with an old implementation /* If a slave uses SYNC, we are dealing with an old implementation
* of the replication protocol (like redis-cli --slave). Flag the client * of the replication protocol (like redis-cli --slave). Flag the client
* so that we don't expect to receive REPLCONF ACK feedbacks. */ * so that we don't expect to receive REPLCONF ACK feedbacks. */
c->flags |= REDIS_PRE_PSYNC_SLAVE; c->flags |= REDIS_PRE_PSYNC;
} }
/* Full resynchronization. */ /* Full resynchronization. */
...@@ -829,6 +829,10 @@ void readSyncBulkPayload(aeEventLoop *el, int fd, void *privdata, int mask) { ...@@ -829,6 +829,10 @@ void readSyncBulkPayload(aeEventLoop *el, int fd, void *privdata, int mask) {
server.master->reploff = server.repl_master_initial_offset; server.master->reploff = server.repl_master_initial_offset;
memcpy(server.master->replrunid, server.repl_master_runid, memcpy(server.master->replrunid, server.repl_master_runid,
sizeof(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"); redisLog(REDIS_NOTICE, "MASTER <-> SLAVE sync: Finished with success");
/* Restart the AOF subsystem now that we finished the sync. This /* Restart the AOF subsystem now that we finished the sync. This
* will trigger an AOF rewrite, and when done will start appending * will trigger an AOF rewrite, and when done will start appending
...@@ -1554,8 +1558,11 @@ void replicationCron(void) { ...@@ -1554,8 +1558,11 @@ void replicationCron(void) {
} }
} }
/* Send ACK to master from time to time. */ /* Send ACK to master from time to time.
if (server.masterhost && server.master) * 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(); replicationSendAck();
/* If we have attached slaves, PING them from time to time. /* If we have attached slaves, PING them from time to time.
...@@ -1599,7 +1606,7 @@ void replicationCron(void) { ...@@ -1599,7 +1606,7 @@ void replicationCron(void) {
redisClient *slave = ln->value; redisClient *slave = ln->value;
if (slave->replstate != REDIS_REPL_ONLINE) continue; 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) if ((server.unixtime - slave->repl_ack_time) > server.repl_timeout)
{ {
char ip[REDIS_IP_STR_LEN]; char ip[REDIS_IP_STR_LEN];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment