From 6a16a636bff425a14d641d21a5b058cc7cf72606 Mon Sep 17 00:00:00 2001 From: antirez Date: Thu, 28 May 2020 10:08:16 +0200 Subject: [PATCH] Replication: showLatestBacklog() refactored out. --- src/networking.c | 26 +------------------------- src/replication.c | 34 ++++++++++++++++++++++++++++++++++ src/server.h | 1 + 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/networking.c b/src/networking.c index 7a5f1d7b9..8d3e057b7 100644 --- a/src/networking.c +++ b/src/networking.c @@ -396,31 +396,7 @@ void addReplyErrorLength(client *c, const char *s, size_t len) { if (ctype == CLIENT_TYPE_MASTER && server.repl_backlog && server.repl_backlog_histlen > 0) { - long long dumplen = 256; - if (server.repl_backlog_histlen < dumplen) - dumplen = server.repl_backlog_histlen; - - /* Identify the first byte to dump. */ - long long idx = - (server.repl_backlog_idx + (server.repl_backlog_size - dumplen)) % - server.repl_backlog_size; - - /* Scan the circular buffer to collect 'dumplen' bytes. */ - sds dump = sdsempty(); - while(dumplen) { - long long thislen = - ((server.repl_backlog_size - idx) < dumplen) ? - (server.repl_backlog_size - idx) : dumplen; - - dump = sdscatrepr(dump,server.repl_backlog+idx,thislen); - dumplen -= thislen; - idx = 0; - } - - /* Finally log such bytes: this is vital debugging info to - * understand what happened. */ - serverLog(LL_WARNING,"Latest backlog is: '%s'", dump); - sdsfree(dump); + showLatestBacklog(); } server.stat_unexpected_error_replies++; } diff --git a/src/replication.c b/src/replication.c index 110f0e82d..063a8705e 100644 --- a/src/replication.c +++ b/src/replication.c @@ -307,6 +307,40 @@ void replicationFeedSlaves(list *slaves, int dictid, robj **argv, int argc) { } } +/* This is a debugging function that gets called when we detect something + * wrong with the replication protocol: the goal is to peek into the + * replication backlog and show a few final bytes to make simpler to + * guess what kind of bug it could be. */ +void showLatestBacklog(void) { + if (server.repl_backlog == NULL) return; + + long long dumplen = 256; + if (server.repl_backlog_histlen < dumplen) + dumplen = server.repl_backlog_histlen; + + /* Identify the first byte to dump. */ + long long idx = + (server.repl_backlog_idx + (server.repl_backlog_size - dumplen)) % + server.repl_backlog_size; + + /* Scan the circular buffer to collect 'dumplen' bytes. */ + sds dump = sdsempty(); + while(dumplen) { + long long thislen = + ((server.repl_backlog_size - idx) < dumplen) ? + (server.repl_backlog_size - idx) : dumplen; + + dump = sdscatrepr(dump,server.repl_backlog+idx,thislen); + dumplen -= thislen; + idx = 0; + } + + /* Finally log such bytes: this is vital debugging info to + * understand what happened. */ + serverLog(LL_WARNING,"Latest backlog is: '%s'", dump); + sdsfree(dump); +} + /* This function is used in order to proxy what we receive from our master * to our sub-slaves. */ #include diff --git a/src/server.h b/src/server.h index 0c0b4d052..a08585292 100644 --- a/src/server.h +++ b/src/server.h @@ -1810,6 +1810,7 @@ void clearReplicationId2(void); void chopReplicationBacklog(void); void replicationCacheMasterUsingMyself(void); void feedReplicationBacklog(void *ptr, size_t len); +void showLatestBacklog(void); void rdbPipeReadHandler(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask); void rdbPipeWriteHandlerConnRemoved(struct connection *conn);