From ef6b24551ac4dc0476a6cac8cddc638002719feb Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Sun, 9 Aug 2015 00:16:39 +0200 Subject: [PATCH] call update_node_record_set_upstream() for STANDBY FOLLOW repmgrd correctly updates ID of the upstream node after automatic failover, but repmgr was not doing that for manual failvers. This moves the existing function to dbutils and modifies it so that it does not rely on global variables with configuration (available just in repmgrd). This should fix issue #67 (hopefully, haven't done much testing). --- dbutils.c | 33 +++++++++++++++++++++++++++++++++ dbutils.h | 2 +- repmgr.c | 10 +++++++++- repmgrd.c | 40 ++-------------------------------------- 4 files changed, 45 insertions(+), 40 deletions(-) diff --git a/dbutils.c b/dbutils.c index b4a4ea59..7af91dc8 100644 --- a/dbutils.c +++ b/dbutils.c @@ -1283,3 +1283,36 @@ create_event_record(PGconn *conn, t_configuration_options *options, int node_id, return success; } + +bool +update_node_record_set_upstream(PGconn *conn, char *cluster_name, int this_node_id, int new_upstream_node_id) +{ + PGresult *res; + char sqlquery[QUERY_STR_LEN]; + + log_debug(_("update_node_record_set_upstream(): Updating node %i's upstream node to %i\n"), this_node_id, new_upstream_node_id); + + sqlquery_snprintf(sqlquery, + " UPDATE %s.repl_nodes " + " SET upstream_node_id = %i " + " WHERE cluster = '%s' " + " AND id = %i ", + get_repmgr_schema_quoted(conn), + new_upstream_node_id, + cluster_name, + this_node_id); + res = PQexec(conn, sqlquery); + + if (PQresultStatus(res) != PGRES_COMMAND_OK) + { + log_err(_("Unable to set new upstream node id: %s\n"), + PQerrorMessage(conn)); + PQclear(res); + + return false; + } + + PQclear(res); + + return true; +} diff --git a/dbutils.h b/dbutils.h index 233eddca..657c90e1 100644 --- a/dbutils.h +++ b/dbutils.h @@ -63,6 +63,6 @@ bool copy_configuration(PGconn *masterconn, PGconn *witnessconn, char *cluster_ bool create_node_record(PGconn *conn, char *action, int node, char *type, int upstream_node, char *cluster_name, char *node_name, char *conninfo, int priority, char *slot_name); bool delete_node_record(PGconn *conn, int node, char *action); bool create_event_record(PGconn *conn, t_configuration_options *options, int node_id, char *event, bool successful, char *details); - +bool update_node_record_set_upstream(PGconn *conn, char *cluster_name, int this_node_id, int new_upstream_node_id); #endif diff --git a/repmgr.c b/repmgr.c index b11c49e1..284bb58a 100644 --- a/repmgr.c +++ b/repmgr.c @@ -1689,6 +1689,7 @@ do_standby_follow(void) char script[MAXLEN]; char master_conninfo[MAXLEN]; PGconn *master_conn; + int master_id; int r, retval; @@ -1727,7 +1728,7 @@ do_standby_follow(void) } master_conn = get_master_connection(conn, - options.cluster_name, NULL, (char *) &master_conninfo); + options.cluster_name, &master_id, (char *) &master_conninfo); } while (master_conn == NULL && runtime_options.wait_for_master); @@ -1796,6 +1797,13 @@ do_standby_follow(void) exit(ERR_NO_RESTART); } + if(update_node_record_set_upstream(master_conn, options.cluster_name, + options.node, master_id) == false) + { + log_err(_("unable to update upstream node")); + exit(ERR_BAD_CONFIG); + } + return; } diff --git a/repmgrd.c b/repmgrd.c index 80cf20dd..ba5d63ac 100644 --- a/repmgrd.c +++ b/repmgrd.c @@ -91,8 +91,6 @@ static void witness_monitor(void); static bool check_connection(PGconn **conn, const char *type, const char *conninfo); static bool set_local_node_failed(void); -static bool update_node_record_set_upstream(PGconn *conn, int this_node_id, int new_upstream_node_id); - static void update_shared_memory(char *last_wal_standby_applied); static void update_registration(void); static void do_master_failover(void); @@ -1520,7 +1518,7 @@ do_master_failover(void) my_local_conn = establish_db_connection(local_options.conninfo, true); /* update node information to reflect new status */ - if(update_node_record_set_upstream(new_master_conn, node_info.node_id, best_candidate.node_id) == false) + if(update_node_record_set_upstream(new_master_conn, local_options.cluster_name, node_info.node_id, best_candidate.node_id) == false) { appendPQExpBuffer(&event_details, _("Unable to update node record for node %i (following new upstream node %i)"), @@ -1664,7 +1662,7 @@ do_upstream_standby_failover(t_node_info upstream_node) terminate(ERR_BAD_CONFIG); } - if(update_node_record_set_upstream(master_conn, node_info.node_id, upstream_node_id) == false) + if(update_node_record_set_upstream(master_conn, local_options.cluster_name, node_info.node_id, upstream_node_id) == false) { terminate(ERR_BAD_CONFIG); } @@ -2308,37 +2306,3 @@ parse_node_type(const char *type) return UNKNOWN; } - - -static bool -update_node_record_set_upstream(PGconn *conn, int this_node_id, int new_upstream_node_id) -{ - PGresult *res; - char sqlquery[QUERY_STR_LEN]; - - log_debug(_("update_node_record_set_upstream(): Updating node %i's upstream node to %i\n"), this_node_id, new_upstream_node_id); - - sqlquery_snprintf(sqlquery, - " UPDATE %s.repl_nodes " - " SET upstream_node_id = %i " - " WHERE cluster = '%s' " - " AND id = %i ", - get_repmgr_schema_quoted(conn), - new_upstream_node_id, - local_options.cluster_name, - this_node_id); - res = PQexec(conn, sqlquery); - - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - log_err(_("Unable to set new upstream node id: %s\n"), - PQerrorMessage(conn)); - PQclear(res); - - return false; - } - - PQclear(res); - - return true; -}