diff --git a/dbutils.c b/dbutils.c index f06f17cd..115c37d8 100644 --- a/dbutils.c +++ b/dbutils.c @@ -825,14 +825,16 @@ get_server_version(PGconn *conn, char *server_version) return atoi(PQgetvalue(res, 0, 0)); } -int -is_standby(PGconn *conn) + +t_recovery_type +get_recovery_type(PGconn *conn) { PGresult *res; - int result = 0; + t_recovery_type recovery_type = RECTYPE_MASTER; + char *sqlquery = "SELECT pg_catalog.pg_is_in_recovery()"; - log_verbose(LOG_DEBUG, "is_standby(): %s", sqlquery); + log_verbose(LOG_DEBUG, "get_recovery_type(): %s", sqlquery); res = PQexec(conn, sqlquery); @@ -840,15 +842,15 @@ is_standby(PGconn *conn) { log_error(_("unable to determine if server is in recovery:\n %s"), PQerrorMessage(conn)); - result = -1; + recovery_type = RECTYPE_UNKNOWN; } else if (PQntuples(res) == 1 && strcmp(PQgetvalue(res, 0, 0), "t") == 0) { - result = 1; + recovery_type = RECTYPE_STANDBY; } PQclear(res); - return result; + return recovery_type; } /* @@ -916,7 +918,7 @@ get_master_connection(PGconn *conn, for (i = 0; i < PQntuples(res); i++) { - int is_node_standby; + t_recovery_type recovery_type; /* initialize with the values of the current node being processed */ node_id = atoi(PQgetvalue(res, i, 0)); @@ -929,9 +931,9 @@ get_master_connection(PGconn *conn, if (PQstatus(remote_conn) != CONNECTION_OK) continue; - is_node_standby = is_standby(remote_conn); + recovery_type = get_recovery_type(remote_conn); - if (is_node_standby == -1) + if (recovery_type == RECTYPE_UNKNOWN) { log_error(_("unable to retrieve recovery state from node %i:\n %s"), node_id, @@ -940,8 +942,7 @@ get_master_connection(PGconn *conn, continue; } - /* if is_standby() returns 0, queried node is the master */ - if (is_node_standby == 0) + if (recovery_type == RECTYPE_MASTER) { PQclear(res); log_debug(_("get_master_connection(): current master node is %i"), node_id); diff --git a/dbutils.h b/dbutils.h index 396b92c6..ad399449 100644 --- a/dbutils.h +++ b/dbutils.h @@ -33,6 +33,12 @@ typedef enum { REPMGR_UNKNOWN } t_extension_status; +typedef enum { + RECTYPE_UNKNOWN = 0, + RECTYPE_MASTER, + RECTYPE_STANDBY +} t_recovery_type; + /* * Struct to store node information */ @@ -165,7 +171,7 @@ bool get_pg_setting(PGconn *conn, const char *setting, char *output); /* server information functions */ bool get_cluster_size(PGconn *conn, char *size); int get_server_version(PGconn *conn, char *server_version); -int is_standby(PGconn *conn); +t_recovery_type get_recovery_type(PGconn *conn); int get_master_node_id(PGconn *conn); /* extension functions */ diff --git a/repmgr-action-master.c b/repmgr-action-master.c index 086df23a..26b90798 100644 --- a/repmgr-action-master.c +++ b/repmgr-action-master.c @@ -18,8 +18,7 @@ do_master_register(void) PGconn *conn = NULL; PGconn *master_conn = NULL; int current_master_id = UNKNOWN_NODE_ID; - int ret; - + t_recovery_type recovery_type; t_node_info node_info = T_NODE_INFO_INITIALIZER; int record_found; bool record_created; @@ -35,14 +34,22 @@ do_master_register(void) check_server_version(conn, "master", true, NULL); /* check that node is actually a master */ - ret = is_standby(conn); - if (ret) - { - log_error(_(ret == 1 ? "server is in standby mode and cannot be registered as a master" : - "connection to node lost!")); + recovery_type = get_recovery_type(conn); - PQfinish(conn); - exit(ERR_BAD_CONFIG); + if (recovery_type != RECTYPE_STANDBY) + { + if (recovery_type == RECTYPE_MASTER) + { + log_error(_("server is in standby mode and cannot be registered as a master")); + PQfinish(conn); + exit(ERR_BAD_CONFIG); + } + else + { + log_error(_("connection to node lost")); + PQfinish(conn); + exit(ERR_DB_CONN); + } } log_verbose(LOG_INFO, _("server is not in recovery")); @@ -204,3 +211,4 @@ do_master_register(void) return; } + diff --git a/repmgr-action-standby.c b/repmgr-action-standby.c index 70aa6324..5e25a31c 100644 --- a/repmgr-action-standby.c +++ b/repmgr-action-standby.c @@ -525,7 +525,6 @@ do_standby_register(void) { PGconn *conn; PGconn *master_conn; - int ret; bool record_created; t_node_info node_record = T_NODE_INFO_INITIALIZER; @@ -560,15 +559,24 @@ do_standby_register(void) if (PQstatus(conn) == CONNECTION_OK) { - ret = is_standby(conn); + t_recovery_type recovery_type = get_recovery_type(conn); - if (ret == 0 || ret == -1) + if (recovery_type != RECTYPE_STANDBY) { - log_error(_(ret == 0 ? "this node should be a standby (%s)" : - "connection to node (%s) lost"), config_file_options.conninfo); - - PQfinish(conn); - exit(ERR_BAD_CONFIG); + if (recovery_type == RECTYPE_MASTER) + { + log_error(_("this node should be a standby (%s)"), + config_file_options.conninfo); + PQfinish(conn); + exit(ERR_BAD_CONFIG); + } + else + { + log_error(_("connection to node (%s) lost"), + config_file_options.conninfo); + PQfinish(conn); + exit(ERR_DB_CONN); + } } } @@ -997,9 +1005,8 @@ do_standby_promote(void) char script[MAXLEN]; - - int r, - retval; + t_recovery_type recovery_type; + int r; char data_dir[MAXLEN]; int i, @@ -1018,18 +1025,22 @@ do_standby_promote(void) check_server_version(conn, "standby", true, NULL); /* Check we are in a standby node */ - retval = is_standby(conn); + recovery_type = get_recovery_type(conn); - switch (retval) + if (recovery_type != RECTYPE_STANDBY) { - case 0: + if (recovery_type == RECTYPE_MASTER) + { log_error(_("STANDBY PROMOTE can only be executed on a standby node")); PQfinish(conn); exit(ERR_BAD_CONFIG); - case -1: + } + else + { log_error(_("connection to node lost")); PQfinish(conn); exit(ERR_DB_CONN); + } } @@ -1094,8 +1105,9 @@ do_standby_promote(void) for (i = 0; i < promote_check_timeout; i += promote_check_interval) { - retval = is_standby(conn); - if (!retval) + + recovery_type = get_recovery_type(conn); + if (recovery_type == RECTYPE_MASTER) { promote_success = true; break; @@ -1105,16 +1117,17 @@ do_standby_promote(void) if (promote_success == false) { - switch (retval) + if (recovery_type == RECTYPE_STANDBY) { - case 1: - log_error(_("STANDBY PROMOTE failed, node is still a standby")); - PQfinish(conn); - exit(ERR_PROMOTION_FAIL); - default: - log_error(_("connection to node lost")); - PQfinish(conn); - exit(ERR_DB_CONN); + log_error(_("STANDBY PROMOTE failed, node is still a standby")); + PQfinish(conn); + exit(ERR_PROMOTION_FAIL); + } + else + { + log_error(_("connection to node lost")); + PQfinish(conn); + exit(ERR_DB_CONN); } } @@ -1258,7 +1271,7 @@ check_source_server() * If the upstream node is a standby, try to connect to the primary too so we * can write an event record */ - if (is_standby(source_conn)) + if (get_recovery_type(source_conn) == RECTYPE_STANDBY) { primary_conn = get_master_connection(source_conn, NULL, NULL);