From 1824e3a3a37eb9618aa487e6e071395758bdaca8 Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 30 Dec 2011 19:34:40 +0100 Subject: [PATCH] Fixed replication when multiple slaves are attaching at the same time. The output buffer was not copied correctly between slaves. This fixes issue #141. --- src/networking.c | 10 ++++++++++ src/redis.h | 1 + src/replication.c | 3 +-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/networking.c b/src/networking.c index 59512f0f..df059f6b 100644 --- a/src/networking.c +++ b/src/networking.c @@ -401,6 +401,16 @@ void addReplyBulkLongLong(redisClient *c, long long ll) { addReplyBulkCBuffer(c,buf,len); } +/* Copy 'src' client output buffers into 'dst' client output buffers. + * The function takes care of freeing the old output buffers of the + * destination client. */ +void copyClientOutputBuffer(redisClient *dst, redisClient *src) { + listRelease(dst->reply); + dst->reply = listDup(src->reply); + memcpy(dst->buf,src->buf,src->bufpos); + dst->bufpos = src->bufpos; +} + static void acceptCommonHandler(int fd) { redisClient *c; if ((c = createClient(fd)) == NULL) { diff --git a/src/redis.h b/src/redis.h index aa79b4ad..95e1127b 100644 --- a/src/redis.h +++ b/src/redis.h @@ -774,6 +774,7 @@ void addReplyStatus(redisClient *c, char *status); void addReplyDouble(redisClient *c, double d); void addReplyLongLong(redisClient *c, long long ll); void addReplyMultiBulkLen(redisClient *c, long length); +void copyClientOutputBuffer(redisClient *dst, redisClient *src); void *dupClientReplyValue(void *o); void getClientsMaxBuffers(unsigned long *longest_output_list, unsigned long *biggest_input_buffer); diff --git a/src/replication.c b/src/replication.c index e08517e8..479dcf43 100644 --- a/src/replication.c +++ b/src/replication.c @@ -122,8 +122,7 @@ void syncCommand(redisClient *c) { if (ln) { /* Perfect, the server is already registering differences for * another slave. Set the right state, and copy the buffer. */ - listRelease(c->reply); - c->reply = listDup(slave->reply); + copyClientOutputBuffer(c,slave); c->replstate = REDIS_REPL_WAIT_BGSAVE_END; redisLog(REDIS_NOTICE,"Waiting for end of BGSAVE for SYNC"); } else { -- 2.45.2