From 97d83bd443ad28a1f1e35bd1e94bc744c622bb8a Mon Sep 17 00:00:00 2001 From: Ian Barwick Date: Fri, 17 Apr 2020 11:20:02 +0900 Subject: [PATCH] standby switchover: add hint for diagnosing remote DB connection failure Output a command, which when excuted on the local node (promotion candidate) will attempt to remotely connect to the demotion candidate and display both the connection message encountered and the connection parameters used. This is useful for corner-cases where the connection normally succeeds if a particular environment variable (e.g. PGPORT) is normally set, but is not set in the environment where SSH is executed. --- repmgr-action-standby.c | 21 ++++++++++++++++++++ sysutils.c | 43 ++++++++++++++++++++++++++--------------- sysutils.h | 1 + 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/repmgr-action-standby.c b/repmgr-action-standby.c index eb81edbc..aa99e1cf 100644 --- a/repmgr-action-standby.c +++ b/repmgr-action-standby.c @@ -4064,10 +4064,31 @@ do_standby_switchover(void) if (remote_error == REMOTE_ERROR_DB_CONNECTION) { + PQExpBufferData ssh_command; + /* can happen if the connection configuration is not consistent across nodes */ log_detail(_("an error was encountered when attempting to connect to PostgreSQL on node \"%s\" (ID: %i)"), remote_node_record.node_name, remote_node_record.node_id); + + /* output a helpful hint to help diagnose the issue */ + initPQExpBuffer(&remote_command_str); + make_remote_repmgr_path(&remote_command_str, &remote_node_record); + + appendPQExpBufferStr(&remote_command_str, "node check --db-connection"); + + initPQExpBuffer(&ssh_command); + + make_remote_command(remote_host, + runtime_options.remote_user, + remote_command_str.data, + config_file_options.ssh_options, + &ssh_command); + + log_hint(_("diagnose with:\n %s"), ssh_command.data); + + termPQExpBuffer(&remote_command_str); + termPQExpBuffer(&ssh_command); } else if (remote_error == REMOTE_ERROR_CONNINFO_PARSE) { diff --git a/sysutils.c b/sysutils.c index 65e6a5d0..05df4d97 100644 --- a/sysutils.c +++ b/sysutils.c @@ -118,28 +118,13 @@ remote_command(const char *host, const char *user, const char *command, const ch { FILE *fp; PQExpBufferData ssh_command; - PQExpBufferData ssh_host; char output[MAXLEN] = ""; - initPQExpBuffer(&ssh_host); - - if (*user != '\0') - { - appendPQExpBuffer(&ssh_host, "%s@", user); - } - - appendPQExpBufferStr(&ssh_host, host); initPQExpBuffer(&ssh_command); - appendPQExpBuffer(&ssh_command, - "ssh -o Batchmode=yes %s %s %s", - ssh_options, - ssh_host.data, - command); - - termPQExpBuffer(&ssh_host); + make_remote_command(host, user, command, ssh_options, &ssh_command); log_debug("remote_command():\n %s", ssh_command.data); @@ -187,6 +172,32 @@ remote_command(const char *host, const char *user, const char *command, const ch } +void +make_remote_command(const char *host, const char *user, const char *command, const char *ssh_options, PQExpBufferData *ssh_command) +{ + PQExpBufferData ssh_host; + + initPQExpBuffer(&ssh_host); + + if (*user != '\0') + { + appendPQExpBuffer(&ssh_host, "%s@", user); + } + + appendPQExpBufferStr(&ssh_host, host); + + + appendPQExpBuffer(ssh_command, + "ssh -o Batchmode=yes %s %s %s", + ssh_options, + ssh_host.data, + command); + + termPQExpBuffer(&ssh_host); + +} + + pid_t disable_wal_receiver(PGconn *conn) { diff --git a/sysutils.h b/sysutils.h index 64195584..727f8fad 100644 --- a/sysutils.h +++ b/sysutils.h @@ -24,6 +24,7 @@ extern bool local_command_return_value(const char *command, PQExpBufferData *out extern bool local_command_simple(const char *command, PQExpBufferData *outputbuf); extern bool remote_command(const char *host, const char *user, const char *command, const char *ssh_options, PQExpBufferData *outputbuf); +extern void make_remote_command(const char *host, const char *user, const char *command, const char *ssh_options, PQExpBufferData *ssh_command); extern pid_t disable_wal_receiver(PGconn *conn); extern pid_t enable_wal_receiver(PGconn *conn, bool wait_startup);