From 9305953bd2429cc021d15db1c8f72ba1fdc2c6bd Mon Sep 17 00:00:00 2001 From: Ian Barwick Date: Thu, 14 Feb 2019 15:52:40 +0900 Subject: [PATCH] Fix history file parsing Also add additional debugging output. --- dbutils.c | 58 +++++++++++++++++++++++++++++++++++++++---------- repmgr-client.c | 10 +++++++++ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/dbutils.c b/dbutils.c index f70d2b70..c1242e4f 100644 --- a/dbutils.c +++ b/dbutils.c @@ -1521,11 +1521,13 @@ get_timeline_history(PGconn *repl_conn, TimeLineID tli) PQExpBufferData query; PGresult *res = NULL; - int nfields; - TimeLineID file_tli; + PQExpBufferData result; + char *resptr; + + TimeLineHistoryEntry *history; + TimeLineID file_tli = UNKNOWN_TIMELINE_ID; uint32 switchpoint_hi; uint32 switchpoint_lo; - TimeLineHistoryEntry *history; initPQExpBuffer(&query); @@ -1555,19 +1557,51 @@ get_timeline_history(PGconn *repl_conn, TimeLineID tli) return NULL; } - nfields = sscanf(PQgetvalue(res, 0, 1), - "%u\t%X/%X", - &file_tli, &switchpoint_hi, &switchpoint_lo); + initPQExpBuffer(&result); + appendPQExpBufferStr(&result, PQgetvalue(res, 0, 1)); + PQclear(res); - if (nfields != 3) + resptr = result.data; + + while (*resptr) { - log_error(_("unable to parse timeline history file content")); - log_detail(_("content is: \"%s\""), PQgetvalue(res, 0, 1)); - PQclear(res); - return NULL; + char buf[MAXLEN]; + char *bufptr = buf; + + if (*resptr != '\n') + { + int len = 0; + + memset(buf, 0, MAXLEN); + + while (*resptr && *resptr != '\n' && len < MAXLEN) + { + *bufptr++ = *resptr++; + len++; + } + + if (buf[0]) + { + int nfields = sscanf(buf, + "%u\t%X/%X", + &file_tli, &switchpoint_hi, &switchpoint_lo); + if (nfields == 3 && file_tli == tli - 1) + break; + } + } + + if (*resptr) + resptr++; } - PQclear(res); + termPQExpBuffer(&result); + + if (file_tli == UNKNOWN_TIMELINE_ID || file_tli != tli - 1) + { + log_error(_("timeline %i not found in timeline history file content"), tli); + log_detail(_("content is: \"%s\""), result.data); + return NULL; + } history = (TimeLineHistoryEntry *) palloc(sizeof(TimeLineHistoryEntry)); history->tli = file_tli; diff --git a/repmgr-client.c b/repmgr-client.c index 814dcdea..1f895f8a 100644 --- a/repmgr-client.c +++ b/repmgr-client.c @@ -3380,6 +3380,12 @@ check_node_can_attach(TimeLineID local_tli, XLogRecPtr local_xlogpos, PGconn *fo return false; } + log_debug("local tli: %i; local_xlogpos: %X/%X; follow_target_history->tli: %i; follow_target_history->end: %X/%X", + local_tli, + format_lsn(local_xlogpos), + follow_target_history->tli, + format_lsn(follow_target_history->end)); + /* * Local node has proceeded beyond the follow target's fork, so we * definitely can't attach. @@ -3432,6 +3438,10 @@ check_node_can_attach(TimeLineID local_tli, XLogRecPtr local_xlogpos, PGconn *fo } PQfinish(follow_target_repl_conn); + + if (follow_target_history) + pfree(follow_target_history); + return success; }