From 45e96f21a59954820bfd4dacd953fb091c8f6ab7 Mon Sep 17 00:00:00 2001 From: Ian Barwick Date: Wed, 15 Apr 2020 17:36:08 +0900 Subject: [PATCH] node check: add option --db-connection This is intended for diagnostic purposes, primarily when diagnosing the connection parameters used when repmgr is being executed on a remote node. --- repmgr-action-node.c | 86 ++++++++++++++++++++++++++++++++++++++++++ repmgr-client-global.h | 3 +- repmgr-client.c | 4 ++ repmgr-client.h | 2 + 4 files changed, 94 insertions(+), 1 deletion(-) diff --git a/repmgr-action-node.c b/repmgr-action-node.c index 0b5ae0e3..9db1975f 100644 --- a/repmgr-action-node.c +++ b/repmgr-action-node.c @@ -53,6 +53,8 @@ static CheckStatus do_node_check_slots(PGconn *conn, OutputMode mode, t_node_inf static CheckStatus do_node_check_missing_slots(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output); static CheckStatus do_node_check_data_directory(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output); static CheckStatus do_node_check_replication_config_owner(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output); +static CheckStatus do_node_check_db_connection(PGconn *conn, OutputMode mode); + /* * NODE STATUS * @@ -734,12 +736,18 @@ do_node_check(void) exit(return_code); } + /* for use by "standby switchover" */ if (runtime_options.replication_connection == true) { do_node_check_replication_connection(); exit(SUCCESS); } + if (runtime_options.db_connection == true) + { + exit_on_connection_error = false; + } + /* * If --optformat was provided, we'll assume this is a remote invocation * and instead of exiting with an error, we'll return an error string to @@ -750,6 +758,7 @@ do_node_check(void) exit_on_connection_error = false; } + if (config_file_options.conninfo[0] != '\0') { t_conninfo_param_list node_conninfo = T_CONNINFO_PARAM_LIST_INITIALIZER; @@ -799,6 +808,17 @@ do_node_check(void) conn = establish_db_connection_by_params(&source_conninfo, exit_on_connection_error); } + + /* + * --db-connection option provided + */ + if (runtime_options.db_connection == true) + { + return_code = do_node_check_db_connection(conn, runtime_options.output_mode); + PQfinish(conn); + exit(return_code); + } + /* * If we've reached here, and the connection is invalid, then --optformat was provided */ @@ -2152,6 +2172,72 @@ CheckStatus do_node_check_replication_config_owner(PGconn *conn, OutputMode mode } +/* + * This is not included in the general list output + */ +static CheckStatus +do_node_check_db_connection(PGconn *conn, OutputMode mode) +{ + CheckStatus status = CHECK_STATUS_OK; + PQExpBufferData details; + + if (mode == OM_CSV) + { + log_error(_("--csv output not provided with --db-connection option")); + PQfinish(conn); + exit(ERR_BAD_CONFIG); + } + + /* This check is for configuration diagnostics only */ + if (mode == OM_NAGIOS) + { + log_error(_("--nagios output not provided with --db-connection option")); + PQfinish(conn); + exit(ERR_BAD_CONFIG); + } + + initPQExpBuffer(&details); + + if (PQstatus(conn) != CONNECTION_OK) + { + t_conninfo_param_list conninfo = T_CONNINFO_PARAM_LIST_INITIALIZER; + int c; + + status = CHECK_STATUS_CRITICAL; + initialize_conninfo_params(&conninfo, false); + conn_to_param_list(conn, &conninfo); + + appendPQExpBufferStr(&details, + "connection parameters used:"); + for (c = 0; c < conninfo.size && conninfo.keywords[c] != NULL; c++) + { + if (conninfo.values[c] != NULL && conninfo.values[c][0] != '\0') + { + appendPQExpBuffer(&details, + " %s=%s", + conninfo.keywords[c], conninfo.values[c]); + } + } + + } + + if (mode == OM_OPTFORMAT) + { + printf("--db-connection=%s\n", + output_check_status(status)); + } + else if (mode == OM_TEXT) + { + printf("%s (%s)\n", + output_check_status(status), + details.data); + } + termPQExpBuffer(&details); + + return status; +} + + void do_node_service(void) { diff --git a/repmgr-client-global.h b/repmgr-client-global.h index e8277ead..19e2619a 100644 --- a/repmgr-client-global.h +++ b/repmgr-client-global.h @@ -120,6 +120,7 @@ typedef struct bool replication_connection; bool data_directory_config; bool replication_config_owner; + bool db_connection; /* "node rejoin" options */ char config_files[MAXLEN]; @@ -172,7 +173,7 @@ typedef struct /* "node status" options */ \ false, \ /* "node check" options */ \ - false, false, false, false, false, false, false, false, false, false, false, \ + false, false, false, false, false, false, false, false, false, false, false, false, \ /* "node rejoin" options */ \ "", \ /* "node service" options */ \ diff --git a/repmgr-client.c b/repmgr-client.c index 0e39bda4..9556b333 100644 --- a/repmgr-client.c +++ b/repmgr-client.c @@ -541,6 +541,10 @@ main(int argc, char **argv) runtime_options.replication_config_owner = true; break; + case OPT_DB_CONNECTION: + runtime_options.db_connection = true; + break; + /*-------------------- * "node rejoin" options *-------------------- diff --git a/repmgr-client.h b/repmgr-client.h index 55a95461..5bdd1adc 100644 --- a/repmgr-client.h +++ b/repmgr-client.h @@ -100,6 +100,7 @@ #define OPT_DETAIL 1047 #define OPT_REPMGRD_FORCE_UNPAUSE 1048 #define OPT_REPLICATION_CONFIG_OWNER 1049 +#define OPT_DB_CONNECTION 1050 /* deprecated since 4.0 */ #define OPT_CHECK_UPSTREAM_CONFIG 999 @@ -189,6 +190,7 @@ static struct option long_options[] = {"replication-connection", no_argument, NULL, OPT_REPL_CONN}, {"data-directory-config", no_argument, NULL, OPT_DATA_DIRECTORY_CONFIG}, {"replication-config-owner", no_argument, NULL, OPT_REPLICATION_CONFIG_OWNER}, + {"db-connection", no_argument, NULL, OPT_DB_CONNECTION}, /* "node rejoin" options */ {"config-files", required_argument, NULL, OPT_CONFIG_FILES},