From 5397f0b03312b8cace07a85333d8f035bdfb8d57 Mon Sep 17 00:00:00 2001 From: John Sully Date: Wed, 4 Mar 2020 17:09:12 -0500 Subject: [PATCH] Add extra logging when reporting errors from masters - especially in rreplay --- src/networking.cpp | 35 +++++++++++++++++++++++++++++++++++ src/replication.cpp | 2 ++ src/server.h | 1 + 3 files changed, 38 insertions(+) diff --git a/src/networking.cpp b/src/networking.cpp index 00322df72..58bd79bcc 100644 --- a/src/networking.cpp +++ b/src/networking.cpp @@ -177,6 +177,7 @@ client *createClient(int fd, int iel) { c->bufposAsync = 0; c->client_tracking_redirection = 0; c->casyncOpsPending = 0; + c->master_error = 0; memset(c->uuid, 0, UUID_BINARY_LEN); listSetFreeMethod(c->pubsub_patterns,decrRefCountVoid); @@ -432,6 +433,34 @@ void addReplyProtoAsync(client *c, const char *s, size_t len) { addReplyProtoCore(c, s, len, true); } +std::string escapeString(sds str) +{ + std::string newstr; + size_t len = sdslen(str); + for (size_t ich = 0; ich < len; ++ich) + { + char ch = str[ich]; + switch (ch) + { + case '\n': + newstr += "\\n"; + break; + + case '\t': + newstr += "\\t"; + break; + + case '\r': + newstr += "\\r"; + break; + + default: + newstr += ch; + } + } + return newstr; +} + /* Low level function called by the addReplyError...() functions. * It emits the protocol for a Redis error, in the form: * @@ -464,6 +493,12 @@ void addReplyErrorLengthCore(client *c, const char *s, size_t len, bool fAsync) serverLog(LL_WARNING,"== CRITICAL == This %s is sending an error " "to its %s: '%s' after processing the command " "'%s'", from, to, s, cmdname); + + if (c->querybuf && sdslen(c->querybuf)) { + std::string str = escapeString(c->querybuf); + serverLog(LL_WARNING, "\tquerybuf: %s", str.c_str()); + } + c->master_error = 1; } } diff --git a/src/replication.cpp b/src/replication.cpp index d7e92d308..2bdc21bf0 100644 --- a/src/replication.cpp +++ b/src/replication.cpp @@ -3482,6 +3482,8 @@ void replicaReplayCommand(client *c) cFake->flags &= ~(CLIENT_MASTER | CLIENT_PREVENT_REPL_PROP); bool fExec = ccmdPrev != serverTL->commandsExecuted; cFake->lock.unlock(); + if (cFake->master_error) + addReplyError(c, "Error in rreplay command, please check logs"); if (fExec || cFake->flags & CLIENT_MULTI) { addReply(c, shared.ok); diff --git a/src/server.h b/src/server.h index 58ea3e620..1e6632576 100644 --- a/src/server.h +++ b/src/server.h @@ -1337,6 +1337,7 @@ typedef struct client { int iel; /* the event loop index we're registered with */ struct fastlock lock; + int master_error; } client; struct saveparam {