diff --git a/HISTORY b/HISTORY
index 77ace6b0..fc4299e9 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,4 +1,5 @@
5.1 2019-??-??
+ repmgr: remove BDR 2.x support
repmgr: don't query upstream's data directory (Ian)
repmgr: rename --recovery-conf-only to --replication-conf-only (Ian)
repmgr: ensure postgresql.auto.conf is created with corretc permissions (Ian)
diff --git a/Makefile.in b/Makefile.in
index 3dbd068d..625f1a53 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -55,9 +55,9 @@ $(info Building against PostgreSQL $(MAJORVERSION))
REPMGR_CLIENT_OBJS = repmgr-client.o \
repmgr-action-primary.o repmgr-action-standby.o repmgr-action-witness.o \
- repmgr-action-bdr.o repmgr-action-cluster.o repmgr-action-node.o repmgr-action-service.o repmgr-action-daemon.o \
+ repmgr-action-cluster.o repmgr-action-node.o repmgr-action-service.o repmgr-action-daemon.o \
configfile.o configfile-scan.o log.o strutil.o controldata.o dirutil.o compat.o dbutils.o sysutils.o
-REPMGRD_OBJS = repmgrd.o repmgrd-physical.o repmgrd-bdr.o configfile.o configfile-scan.o log.o dbutils.o strutil.o controldata.o compat.o sysutils.o
+REPMGRD_OBJS = repmgrd.o repmgrd-physical.o configfile.o configfile-scan.o log.o dbutils.o strutil.o controldata.o compat.o sysutils.o
DATE=$(shell date "+%Y-%m-%d")
repmgr_version.h: repmgr_version.h.in
diff --git a/configfile.c b/configfile.c
index 6eed0cfe..a3d23b24 100644
--- a/configfile.c
+++ b/configfile.c
@@ -378,13 +378,6 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
*/
options->witness_sync_interval = DEFAULT_WITNESS_SYNC_INTERVAL;
- /*-------------
- * BDR settings
- *-------------
- */
- options->bdr_local_monitoring_only = false;
- options->bdr_recovery_timeout = DEFAULT_BDR_RECOVERY_TIMEOUT;
-
/*-------------------------
* service command settings
*-------------------------
@@ -616,10 +609,8 @@ parse_configuration_item(t_configuration_options *options, ItemList *error_list,
{
if (strcmp(value, "physical") == 0)
options->replication_type = REPLICATION_TYPE_PHYSICAL;
- else if (strcmp(value, "bdr") == 0)
- options->replication_type = REPLICATION_TYPE_BDR;
else
- item_list_append(error_list, _("value for \"replication_type\" must be \"physical\" or \"bdr\""));
+ item_list_append(error_list, _("value for \"replication_type\" must be \"physical\""));
}
/* log settings */
@@ -778,12 +769,6 @@ parse_configuration_item(t_configuration_options *options, ItemList *error_list,
else if (strcmp(name, "witness_sync_interval") == 0)
options->witness_sync_interval = repmgr_atoi(value, name, error_list, 1);
- /* BDR settings */
- else if (strcmp(name, "bdr_local_monitoring_only") == 0)
- options->bdr_local_monitoring_only = parse_bool(value, name, error_list);
- else if (strcmp(name, "bdr_recovery_timeout") == 0)
- options->bdr_recovery_timeout = repmgr_atoi(value, name, error_list, 0);
-
/* service settings */
else if (strcmp(name, "pg_ctl_options") == 0)
strncpy(options->pg_ctl_options, value, sizeof(options->pg_ctl_options));
@@ -1112,8 +1097,6 @@ parse_time_unit_parameter(const char *name, const char *value, char *dest, ItemL
* with these):
*
* - async_query_timeout
- * - bdr_local_monitoring_only
- * - bdr_recovery_timeout
* - child_nodes_check_interval
* - child_nodes_connected_min_count
* - child_nodes_connected_include_witness
@@ -1250,24 +1233,6 @@ reload_config(t_configuration_options *orig_options, t_server_type server_type)
config_changed = true;
}
- /* bdr_local_monitoring_only */
- if (orig_options->bdr_local_monitoring_only != new_options.bdr_local_monitoring_only)
- {
- orig_options->bdr_local_monitoring_only = new_options.bdr_local_monitoring_only;
- log_info(_("\"bdr_local_monitoring_only\" is now \"%s\""), new_options.bdr_local_monitoring_only == true ? "TRUE" : "FALSE");
-
- config_changed = true;
- }
-
- /* bdr_recovery_timeout */
- if (orig_options->bdr_recovery_timeout != new_options.bdr_recovery_timeout)
- {
- orig_options->bdr_recovery_timeout = new_options.bdr_recovery_timeout;
- log_info(_("\"bdr_recovery_timeout\" is now \"%i\""), new_options.bdr_recovery_timeout);
-
- config_changed = true;
- }
-
/* child_nodes_check_interval */
if (orig_options->child_nodes_check_interval != new_options.child_nodes_check_interval)
{
diff --git a/configfile.h b/configfile.h
index 66eb7366..647209cd 100644
--- a/configfile.h
+++ b/configfile.h
@@ -161,10 +161,6 @@ typedef struct
int child_nodes_disconnect_timeout;
char child_nodes_disconnect_command[MAXPGPATH];
- /* BDR settings */
- bool bdr_local_monitoring_only;
- bool bdr_recovery_timeout;
-
/* service settings */
char pg_ctl_options[MAXLEN];
char service_start_command[MAXPGPATH];
@@ -238,8 +234,6 @@ typedef struct
DEFAULT_CHILD_NODES_CONNECTED_MIN_COUNT, \
DEFAULT_CHILD_NODES_CONNECTED_INCLUDE_WITNESS, \
DEFAULT_CHILD_NODES_DISCONNECT_TIMEOUT, "", \
- /* BDR settings */ \
- false, DEFAULT_BDR_RECOVERY_TIMEOUT, \
/* service settings */ \
"", "", "", "", "", "", \
/* repmgrd service settings */ \
diff --git a/dbutils.c b/dbutils.c
index 7ac6d6f9..e6614551 100644
--- a/dbutils.c
+++ b/dbutils.c
@@ -33,13 +33,6 @@
#define NODE_RECORD_PARAM_COUNT 11
-/*
- * This is set by is_bdr_db(), which is called by every BDR-related
- * action anyway; this is required to be able to generate appropriate
- * queries for versions 2 and 3.
- */
-int bdr_version_num = UNKNOWN_BDR_VERSION_NUM;
-
static void log_db_error(PGconn *conn, const char *query_text, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
@@ -66,10 +59,6 @@ static ReplSlotStatus _verify_replication_slot(PGconn *conn, char *slot_name, PQ
static bool _create_event(PGconn *conn, t_configuration_options *options, int node_id, char *event, bool successful, char *details, t_event_info *event_info, bool send_notification);
-static bool _is_bdr_db(PGconn *conn, PQExpBufferData *output, bool quiet);
-static void _populate_bdr_node_record(PGresult *res, t_bdr_node_info *node_info, int row);
-static void _populate_bdr_node_records(PGresult *res, BdrNodeInfoList *node_list);
-
/*
* This provides a standardized way of logging database errors. Note
* that the provided PGconn can be a normal or a replication connection;
@@ -119,36 +108,6 @@ parse_lsn(const char *str)
}
-/*
- * Wrap query with appropriate DDL function, if required.
- */
-void
-wrap_ddl_query(PQExpBufferData *query_buf, int replication_type, const char *fmt,...)
-{
- va_list arglist;
- char buf[MAXLEN];
-
- if (replication_type == REPLICATION_TYPE_BDR)
- {
- if (bdr_version_num < 3)
- appendPQExpBufferStr(query_buf, "SELECT bdr.bdr_replicate_ddl_command($repmgr$");
- else
- appendPQExpBufferStr(query_buf, "SELECT bdr.replicate_ddl_command($repmgr$");
- }
-
- va_start(arglist, fmt);
- vsnprintf(buf, MAXLEN, fmt, arglist);
- va_end(arglist);
-
- appendPQExpBufferStr(query_buf, buf);
-
- if (replication_type == REPLICATION_TYPE_BDR)
- {
- appendPQExpBufferStr(query_buf, "$repmgr$)");
- }
-}
-
-
/* ==================== */
/* Connection functions */
/* ==================== */
@@ -2517,10 +2476,6 @@ parse_node_type(const char *type)
{
return WITNESS;
}
- else if (strcmp(type, "bdr") == 0)
- {
- return BDR;
- }
return UNKNOWN;
}
@@ -2537,8 +2492,6 @@ get_node_type_string(t_server_type type)
return "standby";
case WITNESS:
return "witness";
- case BDR:
- return "bdr";
/* this should never happen */
case UNKNOWN:
default:
@@ -5777,788 +5730,6 @@ is_wal_replay_paused(PGconn *conn, bool check_pending_wal)
}
-/* ============= */
-/* BDR functions */
-/* ============= */
-
-
-static bool
-_is_bdr_db(PGconn *conn, PQExpBufferData *output, bool quiet)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
- bool is_bdr_db = false;
-
- initPQExpBuffer(&query);
-
- appendPQExpBufferStr(&query,
- " SELECT (pg_catalog.regexp_matches(extversion, '^\\d+'))[1] AS major_version "
- " FROM pg_catalog.pg_extension "
- " WHERE extname = 'bdr' ");
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) == 0)
- {
- is_bdr_db = false;
- bdr_version_num = UNKNOWN_BDR_VERSION_NUM;
- }
- else
- {
- is_bdr_db = true;
- bdr_version_num = atoi(PQgetvalue(res, 0, 0));
- }
-
- PQclear(res);
-
- log_verbose(LOG_DEBUG, "BDR ext version number is %i", bdr_version_num);
-
- if (is_bdr_db == false)
- {
- const char *warning = _("BDR extension is not available for this database");
-
- if (output != NULL)
- appendPQExpBufferStr(output, warning);
- else if (quiet == false)
- log_warning("%s", warning);
-
- return is_bdr_db;
- }
-
- if (bdr_version_num < 3)
- {
- initPQExpBuffer(&query);
-
- appendPQExpBufferStr(&query,
- "SELECT bdr.bdr_is_active_in_db()");
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- is_bdr_db = atobool(PQgetvalue(res, 0, 0));
-
- if (is_bdr_db == false)
- {
- const char *warning = _("BDR extension available for this database, but the database is not configured for BDR");
-
- if (output != NULL)
- appendPQExpBufferStr(output, warning);
- else if (quiet == false)
- log_warning("%s", warning);
- }
-
- PQclear(res);
- }
-
-
- return is_bdr_db;
-}
-
-
-bool
-is_bdr_db(PGconn *conn, PQExpBufferData *output)
-{
- return _is_bdr_db(conn, output, false);
-}
-
-
-bool
-is_bdr_db_quiet(PGconn *conn)
-{
- return _is_bdr_db(conn, NULL, true);
-}
-
-
-int
-get_bdr_version_num(void)
-{
- return bdr_version_num;
-}
-
-bool
-is_active_bdr_node(PGconn *conn, const char *node_name)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
- bool is_active_bdr_node = false;
-
- initPQExpBuffer(&query);
-
- if (bdr_version_num < 3)
- {
- appendPQExpBuffer(&query,
- " SELECT COALESCE(s.active, TRUE) AS active"
- " FROM bdr.bdr_nodes n "
- " LEFT JOIN pg_catalog.pg_replication_slots s "
- " ON s.slot_name=bdr.bdr_format_slot_name(n.node_sysid, n.node_timeline, n.node_dboid, (SELECT oid FROM pg_catalog.pg_database WHERE datname = pg_catalog.current_database())) "
- " WHERE n.node_name='%s' ",
- node_name);
- }
- else
- {
- appendPQExpBuffer(&query,
- " SELECT COALESCE(s.active, FALSE) AS active"
- " FROM bdr.node bn "
- " INNER JOIN pglogical.node pn "
- " ON (pn.node_id = bn.pglogical_node_id) "
- " LEFT JOIN pg_catalog.pg_replication_slots s "
- " ON s.slot_name=bn.local_slot_name "
- " WHERE pn.node_name='%s' ",
- node_name);
- }
-
- log_verbose(LOG_DEBUG, "is_active_bdr_node():\n %s", query.data);
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- /* we don't care if the query fails */
- if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) == 0)
- {
- is_active_bdr_node = false;
- }
- else
- {
- is_active_bdr_node = atobool(PQgetvalue(res, 0, 0));
- }
-
- PQclear(res);
-
- return is_active_bdr_node;
-}
-
-
-bool
-is_bdr_repmgr(PGconn *conn)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
- int non_bdr_nodes = 0;
-
- initPQExpBuffer(&query);
-
- appendPQExpBufferStr(&query,
- "SELECT pg_catalog.count(*)"
- " FROM repmgr.nodes n"
- " WHERE n.type != 'bdr' ");
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) == 0)
- {
- PQclear(res);
- return false;
- }
-
- non_bdr_nodes = atoi(PQgetvalue(res, 0, 0));
-
- PQclear(res);
-
- return (non_bdr_nodes == 0) ? true : false;
-}
-
-
-
-/*
- * Get name of default BDR replication set.
- *
- * Caller must free provided value.
- */
-char *
-get_default_bdr_replication_set(PGconn *conn)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
- char *default_replication_set = NULL;
- int namelen;
-
- if (bdr_version_num < 3)
- {
- /* For BDR2, we use a custom replication set */
- namelen = strlen(BDR2_REPLICATION_SET_NAME);
- default_replication_set = pg_malloc0(namelen + 1);
- snprintf(default_replication_set,
- namelen + 1,
- "%s", BDR2_REPLICATION_SET_NAME);
-
- return default_replication_set;
- }
-
- initPQExpBuffer(&query);
-
- appendPQExpBufferStr(&query,
- " SELECT rs.set_name "
- " FROM pglogical.replication_set rs "
- " INNER JOIN bdr.node_group ng "
- " ON ng.node_group_default_repset = rs.set_id ");
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) == 0)
- {
- log_warning(_("unable to retrieve default BDR replication set name"));
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- log_detail("%s", PQerrorMessage(conn));
-
- PQclear(res);
- return NULL;
- }
-
- namelen = strlen(PQgetvalue(res, 0, 0));
- default_replication_set = pg_malloc0(namelen + 1);
-
- snprintf(default_replication_set,
- namelen,
- "%s", PQgetvalue(res, 0, 0));
-
- PQclear(res);
-
- return default_replication_set;
-}
-
-
-bool
-is_table_in_bdr_replication_set(PGconn *conn, const char *tablename, const char *set)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
- bool in_replication_set = false;
-
- initPQExpBuffer(&query);
-
- if (bdr_version_num < 3)
- {
- appendPQExpBuffer(&query,
- "SELECT pg_catalog.count(*) "
- " FROM pg_catalog.unnest(bdr.table_get_replication_sets('repmgr.%s')) AS repset "
- " WHERE repset='%s' ",
- tablename,
- set);
- }
- else
- {
- appendPQExpBuffer(&query,
- " SELECT pg_catalog.count(*) "
- " FROM pglogical.replication_set s "
- " INNER JOIN pglogical.replication_set_table st "
- " ON s.set_id = st.set_id "
- " WHERE s.set_name = '%s' "
- " AND st.set_reloid = 'repmgr.%s'::REGCLASS ",
- set,
- tablename);
-
- }
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) == 0)
- {
- in_replication_set = false;
- }
- else
- {
- in_replication_set = atoi(PQgetvalue(res, 0, 0)) == 1 ? true : false;
- }
-
- PQclear(res);
-
- return in_replication_set;
-}
-
-
-
-bool
-add_table_to_bdr_replication_set(PGconn *conn, const char *tablename, const char *set)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
- bool success = true;
-
- initPQExpBuffer(&query);
-
- if (bdr_version_num < 3)
- {
- appendPQExpBuffer(&query,
- "SELECT bdr.table_set_replication_sets('repmgr.%s', '{%s}')",
- tablename,
- set);
- }
- else
- {
- appendPQExpBuffer(&query,
- " SELECT bdr.replication_set_add_table( "
- " relation := 'repmgr.%s', "
- " set_name := '%s' "
- " ) ",
- tablename,
- set);
- }
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- log_error(_("unable to add table \"repmgr.%s\" to replication set \"%s\""),
- tablename,
- set);
- log_detail("%s", PQerrorMessage(conn));
-
- success = false;
- }
-
- PQclear(res);
-
- return success;
-}
-
-
-bool
-bdr_node_name_matches(PGconn *conn, const char *node_name, PQExpBufferData *bdr_local_node_name)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
- bool node_exists = false;
-
- initPQExpBuffer(&query);
-
- if (bdr_version_num < 3)
- {
- appendPQExpBufferStr(&query,
- "SELECT bdr.bdr_get_local_node_name() AS node_name");
- }
- else
- {
- appendPQExpBufferStr(&query,
- "SELECT node_name FROM bdr.local_node_info()");
- }
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- node_exists = false;
- }
- else
- {
- node_exists = true;
- appendPQExpBuffer(bdr_local_node_name,
- "%s", PQgetvalue(res, 0, 0));
- }
-
- PQclear(res);
-
- return node_exists;
-}
-
-
-ReplSlotStatus
-get_bdr_node_replication_slot_status(PGconn *conn, const char *node_name)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
- ReplSlotStatus status = SLOT_UNKNOWN;
-
- initPQExpBuffer(&query);
-
- if (bdr_version_num < 3)
- {
- appendPQExpBuffer(&query,
- " SELECT s.active "
- " FROM pg_catalog.pg_replication_slots s "
- " WHERE slot_name = "
- " (SELECT bdr.bdr_format_slot_name(node_sysid, node_timeline, node_dboid, datoid) "
- " FROM bdr.bdr_nodes "
- " WHERE node_name = '%s') ",
- node_name);
- }
- else
- {
- appendPQExpBuffer(&query,
- " SELECT COALESCE(s.active, FALSE) AS active"
- " FROM bdr.node bn "
- " INNER JOIN pglogical.node pn "
- " ON (pn.node_id = bn.pglogical_node_id) "
- " INNER JOIN pg_catalog.pg_replication_slots s "
- " ON s.slot_name=bn.local_slot_name "
- " WHERE pn.node_name='%s' ",
- node_name);
- }
-
- log_verbose(LOG_DEBUG, "get_bdr_node_replication_slot_status():\n %s", query.data);
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) == 0)
- {
- status = SLOT_UNKNOWN;
- }
- else
- {
- status = (atobool(PQgetvalue(res, 0, 0)) == true)
- ? SLOT_ACTIVE
- : SLOT_INACTIVE;
- }
-
- PQclear(res);
-
- return status;
-}
-
-
-void
-get_bdr_other_node_name(PGconn *conn, int node_id, char *node_name)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
-
- initPQExpBuffer(&query);
-
- appendPQExpBuffer(&query,
- " SELECT n.node_name "
- " FROM repmgr.nodes n "
- " WHERE n.node_id != %i",
- node_id);
-
- log_verbose(LOG_DEBUG, "get_bdr_other_node_name():\n %s", query.data);
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) == PGRES_TUPLES_OK)
- {
- snprintf(node_name,
- NAMEDATALEN,
- "%s", PQgetvalue(res, 0, 0));
- }
- else
- {
- log_warning(_("get_bdr_other_node_name(): unable to execute query\n %s"),
- PQerrorMessage(conn));
- }
- PQclear(res);
-
- return;
-}
-
-
-/*
- * For BDR 2.x only
- */
-void
-add_extension_tables_to_bdr_replication_set(PGconn *conn)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
-
- initPQExpBuffer(&query);
-
- appendPQExpBufferStr(&query,
- " SELECT c.relname "
- " FROM pg_class c "
- "INNER JOIN pg_namespace n "
- " ON c.relnamespace = n.oid "
- " WHERE n.nspname = 'repmgr' "
- " AND c.relkind = 'r' ");
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- /* XXX log error */
- }
- else
- {
- int i;
-
- for (i = 0; i < PQntuples(res); i++)
- {
- add_table_to_bdr_replication_set(conn,
- PQgetvalue(res, i, 0),
- "repmgr");
- }
- }
-
- PQclear(res);
-
- return;
-}
-
-void
-get_all_bdr_node_records(PGconn *conn, BdrNodeInfoList *node_list)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
-
- initPQExpBuffer(&query);
-
- if (bdr_version_num < 3)
- {
- appendPQExpBufferStr(&query,
- " SELECT " BDR2_NODES_COLUMNS
- " FROM bdr.bdr_nodes "
- "ORDER BY node_seq_id ");
- }
- else
- {
- appendPQExpBufferStr(&query,
- " SELECT " BDR3_NODES_COLUMNS
- " FROM bdr.node_summary ns "
- " ORDER BY node_name");
- }
-
- log_verbose(LOG_DEBUG, "get_all_bdr_node_records():\n%s", query.data);
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- _populate_bdr_node_records(res, node_list);
-
- PQclear(res);
- return;
-}
-
-RecordStatus
-get_bdr_node_record_by_name(PGconn *conn, const char *node_name, t_bdr_node_info *node_info)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
-
- initPQExpBuffer(&query);
-
- if (bdr_version_num < 3)
- {
- appendPQExpBuffer(&query,
- " SELECT " BDR2_NODES_COLUMNS
- " FROM bdr.bdr_nodes "
- " WHERE node_name = '%s'",
- node_name);
- }
- else
- {
- appendPQExpBuffer(&query,
- " SELECT " BDR3_NODES_COLUMNS
- " FROM bdr.node_summary ns "
- " WHERE ns.node_name = '%s'",
- node_name);
- }
-
- log_verbose(LOG_DEBUG, "get_bdr_node_record_by_name():\n%s", query.data);
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- log_error(_("unable to retrieve BDR node record for \"%s\":\n %s"),
- node_name,
- PQerrorMessage(conn));
-
- PQclear(res);
- return RECORD_ERROR;
- }
-
- if (PQntuples(res) == 0)
- {
- PQclear(res);
- return RECORD_NOT_FOUND;
- }
-
- _populate_bdr_node_record(res, node_info, 0);
-
- PQclear(res);
-
- return RECORD_FOUND;
-}
-
-
-static
-void
-_populate_bdr_node_records(PGresult *res, BdrNodeInfoList *node_list)
-{
- int i;
-
- clear_node_info_list((NodeInfoList *) node_list);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- return;
- }
-
- for (i = 0; i < PQntuples(res); i++)
- {
- BdrNodeInfoListCell *cell;
-
- cell = (BdrNodeInfoListCell *) pg_malloc0(sizeof(BdrNodeInfoListCell));
-
- cell->node_info = pg_malloc0(sizeof(t_bdr_node_info));
-
- _populate_bdr_node_record(res, cell->node_info, i);
-
- if (node_list->tail)
- node_list->tail->next = cell;
- else
- node_list->head = cell;
-
- node_list->tail = cell;
- node_list->node_count++;
- }
-
- return;
-}
-
-
-static void
-_populate_bdr_node_record(PGresult *res, t_bdr_node_info *node_info, int row)
-{
- snprintf(node_info->node_sysid, sizeof(node_info->node_sysid), "%s", PQgetvalue(res, row, 0));
- node_info->node_timeline = atoi(PQgetvalue(res, row, 1));
- node_info->node_dboid = atoi(PQgetvalue(res, row, 2));
- snprintf(node_info->node_name, sizeof(node_info->node_name), "%s", PQgetvalue(res, row, 3));
- snprintf(node_info->node_local_dsn, sizeof(node_info->node_local_dsn), "%s", PQgetvalue(res, row, 4));
- snprintf(node_info->peer_state_name, sizeof(node_info->peer_state_name), "%s", PQgetvalue(res, row, 5));
-}
-
-
-bool
-am_bdr_failover_handler(PGconn *conn, int node_id)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
- bool am_handler = false;
-
- initPQExpBuffer(&query);
-
- appendPQExpBuffer(&query,
- "SELECT repmgr.am_bdr_failover_handler(%i)",
- node_id);
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- log_error(_("unable to execute function repmgr.am_bdr_failover_handler():\n %s"),
- PQerrorMessage(conn));
- PQclear(res);
- return false;
- }
-
-
- am_handler = atobool(PQgetvalue(res, 0, 0));
-
- PQclear(res);
-
- return am_handler;
-}
-
-void
-unset_bdr_failover_handler(PGconn *conn)
-{
- PGresult *res = NULL;
-
- res = PQexec(conn, "SELECT repmgr.unset_bdr_failover_handler()");
-
- PQclear(res);
- return;
-}
-
-
-bool
-bdr_node_has_repmgr_set(PGconn *conn, const char *node_name)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
- bool has_repmgr_set = false;
-
- if (bdr_version_num >= 3)
- return true;
-
- initPQExpBuffer(&query);
-
- appendPQExpBuffer(&query,
- " SELECT pg_catalog.count(*) "
- " FROM pg_catalog.unnest(bdr.connection_get_replication_sets('%s') AS repset "
- " WHERE repset = '%s'",
- node_name,
- BDR2_REPLICATION_SET_NAME);
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) == 0)
- {
- has_repmgr_set = false;
- }
- else
- {
- has_repmgr_set = atoi(PQgetvalue(res, 0, 0)) == 1 ? true : false;
- }
-
- PQclear(res);
-
- return has_repmgr_set;
-}
-
-
-bool
-bdr_node_set_repmgr_set(PGconn *conn, const char *node_name)
-{
- PQExpBufferData query;
- PGresult *res = NULL;
- bool success = true;
-
- if (bdr_version_num >= 3)
- return true;
-
- initPQExpBuffer(&query);
-
- /*
- * Here we extract a list of existing replication sets, add 'repmgr', and
- * set the replication sets to the new list.
- */
- appendPQExpBuffer(&query,
- " SELECT bdr.connection_set_replication_sets( "
- " ARRAY( "
- " SELECT repset::TEXT "
- " FROM pg_catalog.unnest(bdr.connection_get_replication_sets('%s')) AS repset "
- " UNION "
- " SELECT '%s'::TEXT "
- " ), "
- " '%s' "
- " ) ",
- node_name,
- BDR2_REPLICATION_SET_NAME,
- node_name);
-
- log_debug("bdr_node_set_repmgr_set():\n%s", query.data);
-
- res = PQexec(conn, query.data);
- termPQExpBuffer(&query);
-
-
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- log_debug("result status: %s", PQresStatus(PQresultStatus(res)));
- log_error(_("unable to create replication set \"repmgr\""));
- log_detail("%s", PQerrorMessage(conn));
- success = false;
- }
-
- PQclear(res);
-
- return success;
-}
-
-
-
/* miscellaneous debugging functions */
const char *
diff --git a/dbutils.h b/dbutils.h
index e78df15b..06c92fd8 100644
--- a/dbutils.h
+++ b/dbutils.h
@@ -60,11 +60,6 @@
"NULL AS attached "
-
-#define BDR2_NODES_COLUMNS "node_sysid, node_timeline, node_dboid, node_name, node_local_dsn, ''"
-#define BDR3_NODES_COLUMNS "ns.node_id, 0, 0, ns.node_name, ns.interface_connstr, ns.peer_state_name"
-
-
#define ERRBUFF_SIZE 512
typedef enum
@@ -72,8 +67,7 @@ typedef enum
UNKNOWN = 0,
PRIMARY,
STANDBY,
- WITNESS,
- BDR
+ WITNESS
} t_server_type;
typedef enum
@@ -326,45 +320,6 @@ typedef struct s_connection_user
#define T_CONNECTION_USER_INITIALIZER { "", false }
-/* represents an entry in bdr.bdr_nodes */
-typedef struct s_bdr_node_info
-{
- char node_sysid[MAXLEN];
- uint32 node_timeline;
- uint32 node_dboid;
- char node_name[MAXLEN];
- char node_local_dsn[MAXLEN];
- char peer_state_name[MAXLEN];
-} t_bdr_node_info;
-
-#define T_BDR_NODE_INFO_INITIALIZER { \
- "", InvalidOid, InvalidOid, \
- "", "", "" \
-}
-
-
-/* structs to store a list of BDR node records */
-typedef struct BdrNodeInfoListCell
-{
- struct BdrNodeInfoListCell *next;
- t_bdr_node_info *node_info;
-} BdrNodeInfoListCell;
-
-typedef struct BdrNodeInfoList
-{
- BdrNodeInfoListCell *head;
- BdrNodeInfoListCell *tail;
- int node_count;
-} BdrNodeInfoList;
-
-#define T_BDR_NODE_INFO_LIST_INITIALIZER { \
- NULL, \
- NULL, \
- 0 \
-}
-
-
-
typedef struct
{
char filepath[MAXPGPATH];
@@ -374,6 +329,7 @@ typedef struct
#define T_CONFIGFILE_INFO_INITIALIZER { "", "", false }
+
typedef struct
{
int size;
@@ -383,6 +339,7 @@ typedef struct
#define T_CONFIGFILE_LIST_INITIALIZER { 0, 0, NULL }
+
typedef struct
{
uint64 system_identifier;
@@ -422,10 +379,6 @@ typedef struct RepmgrdInfo {
/* utility functions */
XLogRecPtr parse_lsn(const char *str);
-
-extern void
-wrap_ddl_query(PQExpBufferData *query_buf, int replication_type, const char *fmt,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
bool atobool(const char *value);
/* connection functions */
@@ -630,27 +583,6 @@ int get_upstream_last_seen(PGconn *conn, t_server_type node_type);
bool is_wal_replay_paused(PGconn *conn, bool check_pending_wal);
-/* BDR functions */
-int get_bdr_version_num(void);
-void get_all_bdr_node_records(PGconn *conn, BdrNodeInfoList *node_list);
-RecordStatus get_bdr_node_record_by_name(PGconn *conn, const char *node_name, t_bdr_node_info *node_info);
-bool is_bdr_db(PGconn *conn, PQExpBufferData *output);
-bool is_bdr_db_quiet(PGconn *conn);
-bool is_active_bdr_node(PGconn *conn, const char *node_name);
-bool is_bdr_repmgr(PGconn *conn);
-char *get_default_bdr_replication_set(PGconn *conn);
-bool is_table_in_bdr_replication_set(PGconn *conn, const char *tablename, const char *set);
-bool add_table_to_bdr_replication_set(PGconn *conn, const char *tablename, const char *set);
-void add_extension_tables_to_bdr_replication_set(PGconn *conn);
-bool bdr_node_name_matches(PGconn *conn, const char *node_name, PQExpBufferData *bdr_local_node_name);
-ReplSlotStatus get_bdr_node_replication_slot_status(PGconn *conn, const char *node_name);
-void get_bdr_other_node_name(PGconn *conn, int node_id, char *name_buf);
-
-bool am_bdr_failover_handler(PGconn *conn, int node_id);
-void unset_bdr_failover_handler(PGconn *conn);
-bool bdr_node_has_repmgr_set(PGconn *conn, const char *node_name);
-bool bdr_node_set_repmgr_set(PGconn *conn, const char *node_name);
-
/* miscellaneous debugging functions */
const char *print_node_status(NodeStatus node_status);
const char *print_pqping_status(PGPing ping_status);
diff --git a/doc/bdr-failover.md b/doc/bdr-failover.md
deleted file mode 100644
index e1063d48..00000000
--- a/doc/bdr-failover.md
+++ /dev/null
@@ -1,8 +0,0 @@
-BDR failover with repmgrd
-=========================
-
-This document has been integrated into the main `repmgr` documentation
-and is now located here:
-
-> [BDR failover with repmgrd](https://repmgr.org/docs/current/repmgrd-bdr.html)
-
diff --git a/doc/configuration-file-optional-settings.xml b/doc/configuration-file-optional-settings.xml
index 6c915f79..0a2d5689 100644
--- a/doc/configuration-file-optional-settings.xml
+++ b/doc/configuration-file-optional-settings.xml
@@ -66,17 +66,8 @@
- Must be one of physical (for standard streaming replication)
- or bdr.
+ Must be physical (the default).
-
-
- Replication type bdr can only be used with BDR 2.x
-
-
- BDR 3.x users should use physical.
-
-
diff --git a/doc/event-notifications.xml b/doc/event-notifications.xml
index ad39fb99..ce4a06ed 100644
--- a/doc/event-notifications.xml
+++ b/doc/event-notifications.xml
@@ -117,10 +117,6 @@
conninfo string of the primary node
( and )
-
- conninfo string of the next available node
- (bdr_failover and bdr_recovery)
-
@@ -130,9 +126,6 @@
name of the current primary node ( and )
-
- name of the next available node (bdr_failover and bdr_recovery)
-
@@ -273,28 +266,6 @@
-
- Events generated by &repmgrd; (BDR mode):
-
-
- bdr_failover
-
-
- bdr_reconnect
-
-
- bdr_recovery
-
-
- bdr_register
-
-
- bdr_unregister
-
-
-
-
-
Note that under some circumstances (e.g. when no replication cluster primary
could be located), it will not be possible to write an entry into the
diff --git a/doc/filelist.xml b/doc/filelist.xml
index b2bb1578..1226344b 100644
--- a/doc/filelist.xml
+++ b/doc/filelist.xml
@@ -33,7 +33,6 @@
-
diff --git a/doc/repmgr-cluster-show.xml b/doc/repmgr-cluster-show.xml
index 91bc1374..efb07501 100644
--- a/doc/repmgr-cluster-show.xml
+++ b/doc/repmgr-cluster-show.xml
@@ -18,7 +18,7 @@
Displays information about each registered node in the replication cluster. This
command polls each registered server and shows its role (primary /
- standby / bdr) and status. It polls each server
+ standby) and status. It polls each server
directly and can be run on any node in the cluster; this is also useful when analyzing
connectivity from a particular node.
diff --git a/doc/repmgr.xml b/doc/repmgr.xml
index 524f8223..3cc931e5 100644
--- a/doc/repmgr.xml
+++ b/doc/repmgr.xml
@@ -91,7 +91,6 @@
&repmgrd-automatic-failover;
&repmgrd-configuration;
&repmgrd-operation;
- &repmgrd-bdr;
diff --git a/doc/repmgrd-bdr.xml b/doc/repmgrd-bdr.xml
deleted file mode 100644
index 90b813fd..00000000
--- a/doc/repmgrd-bdr.xml
+++ /dev/null
@@ -1,429 +0,0 @@
-
- BDR failover with repmgrd
-
-
- repmgrd
- BDR
-
-
-
- BDR
-
-
-
- &repmgr; 4.x provides support for monitoring a pair of BDR 2.x nodes and taking action in
- case one of the nodes fails.
-
-
-
- Due to the nature of BDR 1.x/2.x, it's only safe to use this solution for
- a two-node scenario. Introducing additional nodes will create an inherent
- risk of node desynchronisation if a node goes down without being cleanly
- removed from the cluster.
-
-
-
- In contrast to streaming replication, there's no concept of "promoting" a new
- primary node with BDR. Instead, "failover" involves monitoring both nodes
- with &repmgrd; and redirecting queries from the failed node to the remaining
- active node. This can be done by using an
- event notification script
- which is called by &repmgrd; to dynamically
- reconfigure a proxy server/connection pooler such as PgBouncer.
-
-
-
-
- This &repmgr; functionality is for BDR 2.x only running on PostgreSQL 9.4/9.6.
- It is not required for later BDR versions.
-
-
-
-
- Prerequisites
-
-
- This &repmgr; functionality is for BDR 2.x only running on PostgreSQL 9.4/9.6.
- It is not required for later BDR versions.
-
-
-
- &repmgr; 4 requires PostgreSQL 9.4 or 9.6 with the BDR 2 extension
- enabled and configured for a two-node BDR network. &repmgr; 4 packages
- must be installed on each node before attempting to configure
- repmgr.
-
-
-
- &repmgr; 4 will refuse to install if it detects more than two BDR nodes.
-
-
-
- Application database connections *must* be passed through a proxy server/
- connection pooler such as PgBouncer, and it must be possible to dynamically
- reconfigure that from &repmgrd;. The example demonstrated in this document
- will use PgBouncer
-
-
- The proxy server / connection poolers must not
- be installed on the database servers.
-
-
- For this example, it's assumed password-less SSH connections are available
- from the PostgreSQL servers to the servers where PgBouncer
- runs, and that the user on those servers has permission to alter the
- PgBouncer configuration files.
-
-
- PostgreSQL connections must be possible between each node, and each node
- must be able to connect to each PgBouncer instance.
-
-
-
-
- Configuration
-
- A sample configuration for repmgr.conf on each
- BDR node would look like this:
-
- # Node information
- node_id=1
- node_name='node1'
- conninfo='host=node1 dbname=bdrtest user=repmgr connect_timeout=2'
- data_directory='/var/lib/postgresql/data'
- replication_type='bdr'
-
- # Event notification configuration
- event_notifications='bdr_failover'
- event_notification_command='/path/to/bdr-pgbouncer.sh %n %e %s "%c" "%a" >> /tmp/bdr-failover.log 2>&1'
-
- # repmgrd options
- monitor_interval_secs=5
- reconnect_attempts=6
- reconnect_interval=5
-
-
- Adjust settings as appropriate; copy and adjust for the second node (particularly
- the values node_id, node_name
- and conninfo).
-
-
- Note that the values provided for the conninfo string
- must be valid for connections from both nodes in the
- replication cluster. The database must be the BDR-enabled database.
-
-
- If defined, the event_notifications parameter will restrict
- execution of the script defined in event_notification_command
- to the specified event(s).
-
-
-
- event_notification_command is the script which does the actual "heavy lifting"
- of reconfiguring the proxy server/ connection pooler. It is fully
- user-definable; see section for a reference
- implementation.
-
-
-
-
-
-
- repmgr setup
-
- Register both nodes; example on node1:
-
- $ repmgr -f /etc/repmgr.conf bdr register
- NOTICE: attempting to install extension "repmgr"
- NOTICE: "repmgr" extension successfully installed
- NOTICE: node record created for node 'node1' (ID: 1)
- NOTICE: BDR node 1 registered (conninfo: host=node1 dbname=bdrtest user=repmgr)
-
-
- and on node1:
-
- $ repmgr -f /etc/repmgr.conf bdr register
- NOTICE: node record created for node 'node2' (ID: 2)
- NOTICE: BDR node 2 registered (conninfo: host=node2 dbname=bdrtest user=repmgr)
-
-
- The repmgr extension will be automatically created
- when the first node is registered, and will be propagated to the second
- node.
-
-
-
- Ensure the &repmgr; package is available on both nodes before
- attempting to register the first node.
-
-
-
- At this point the meta data for both nodes has been created; executing
- (on either node) should produce output like this:
-
- $ repmgr -f /etc/repmgr.conf cluster show
- ID | Name | Role | Status | Upstream | Location | Connection string
- ----+-------+------+-----------+----------+--------------------------------------------------------
- 1 | node1 | bdr | * running | | default | host=node1 dbname=bdrtest user=repmgr connect_timeout=2
- 2 | node2 | bdr | * running | | default | host=node2 dbname=bdrtest user=repmgr connect_timeout=2
-
-
- Additionally it's possible to display log of significant events; executing
- (on either node) should produce output like this:
-
- $ repmgr -f /etc/repmgr.conf cluster event
- Node ID | Event | OK | Timestamp | Details
- ---------+--------------+----+---------------------+----------------------------------------------
- 2 | bdr_register | t | 2017-07-27 17:51:48 | node record created for node 'node2' (ID: 2)
- 1 | bdr_register | t | 2017-07-27 17:51:00 | node record created for node 'node1' (ID: 1)
-
-
-
- At this point there will only be records for the two node registrations (displayed here
- in reverse chronological order).
-
-
-
-
- Defining the BDR failover "event_notification_command"
-
- Key to "failover" execution is the event_notification_command,
- which is a user-definable script specified in repmpgr.conf
- and which can use a &repmgr; event notification
- to reconfigure the proxy server / connection pooler so it points to the other, still-active node.
- Details of the event will be passed as parameters to the script.
-
-
- Following parameter placeholders are available for the script definition in repmpgr.conf;
- these will be replaced with the appropriate value when the script is executed:
-
-
-
-
-
-
-
- node ID
-
-
-
-
-
-
-
-
- event type
-
-
-
-
-
-
-
-
- success (1 or 0)
-
-
-
-
-
-
-
- timestamp
-
-
-
-
-
-
-
-
- details
-
-
-
-
-
-
-
- conninfo string of the next available node (bdr_failover and bdr_recovery)
-
-
-
-
-
-
-
- name of the next available node (bdr_failover and bdr_recovery)
-
-
-
-
-
-
- Note that %c and %a are only provided with
- particular failover events, in this case bdr_failover.
-
-
- The provided sample script
- (scripts/bdr-pgbouncer.sh)
- is configured as follows:
-
- event_notification_command='/path/to/bdr-pgbouncer.sh %n %e %s "%c" "%a"'
-
-
- and parses the placeholder parameters like this:
-
- NODE_ID=$1
- EVENT_TYPE=$2
- SUCCESS=$3
- NEXT_CONNINFO=$4
- NEXT_NODE_NAME=$5
-
-
-
- The sample script also contains some hard-coded values for the PgBouncer
- configuration for both nodes; these will need to be adjusted for your local environment
- (ideally the scripts would be maintained as templates and generated by some
- kind of provisioning system).
-
-
-
-
- The script performs following steps:
-
-
- pauses PgBouncer on all nodes
-
-
- recreates the PgBouncer configuration file on each
- node using the information provided by &repmgrd;
- (primarily the conninfo string) to configure
- PgBouncer
-
-
- reloads the PgBouncer configuration
-
-
- executes the RESUME command (in PgBouncer)
-
-
-
-
- Following successful script execution, any connections to PgBouncer on the failed BDR node
- will be redirected to the active node.
-
-
-
-
- Node monitoring and failover
-
- At the intervals specified by monitor_interval_secs
- in repmgr.conf, &repmgrd;
- will ping each node to check if it's available. If a node isn't available,
- &repmgrd; will enter failover mode and check reconnect_attempts
- times at intervals of reconnect_interval to confirm the node is definitely unreachable.
- This buffer period is necessary to avoid false positives caused by transient
- network outages.
-
-
- If the node is still unavailable, &repmgrd; will enter failover mode and execute
- the script defined in event_notification_command; an entry will be logged
- in the repmgr.events table and &repmgrd; will
- (unless otherwise configured) resume monitoring of the node in "degraded" mode until it reappears.
-
-
- &repmgrd; logfile output during a failover event will look something like this
- on one node (usually the node which has failed, here node2):
-
- ...
- [2017-07-27 21:08:39] [INFO] starting continuous BDR node monitoring
- [2017-07-27 21:08:39] [INFO] monitoring BDR replication status on node "node2" (ID: 2)
- [2017-07-27 21:08:55] [INFO] monitoring BDR replication status on node "node2" (ID: 2)
- [2017-07-27 21:09:11] [INFO] monitoring BDR replication status on node "node2" (ID: 2)
- [2017-07-27 21:09:23] [WARNING] unable to connect to node node2 (ID 2)
- [2017-07-27 21:09:23] [INFO] checking state of node 2, 0 of 5 attempts
- [2017-07-27 21:09:23] [INFO] sleeping 1 seconds until next reconnection attempt
- [2017-07-27 21:09:24] [INFO] checking state of node 2, 1 of 5 attempts
- [2017-07-27 21:09:24] [INFO] sleeping 1 seconds until next reconnection attempt
- [2017-07-27 21:09:25] [INFO] checking state of node 2, 2 of 5 attempts
- [2017-07-27 21:09:25] [INFO] sleeping 1 seconds until next reconnection attempt
- [2017-07-27 21:09:26] [INFO] checking state of node 2, 3 of 5 attempts
- [2017-07-27 21:09:26] [INFO] sleeping 1 seconds until next reconnection attempt
- [2017-07-27 21:09:27] [INFO] checking state of node 2, 4 of 5 attempts
- [2017-07-27 21:09:27] [INFO] sleeping 1 seconds until next reconnection attempt
- [2017-07-27 21:09:28] [WARNING] unable to reconnect to node 2 after 5 attempts
- [2017-07-27 21:09:28] [NOTICE] setting node record for node 2 to inactive
- [2017-07-27 21:09:28] [INFO] executing notification command for event "bdr_failover"
- [2017-07-27 21:09:28] [DETAIL] command is:
- /path/to/bdr-pgbouncer.sh 2 bdr_failover 1 "host=host=node1 dbname=bdrtest user=repmgr connect_timeout=2" "node1"
- [2017-07-27 21:09:28] [INFO] node 'node2' (ID: 2) detected as failed; next available node is 'node1' (ID: 1)
- [2017-07-27 21:09:28] [INFO] monitoring BDR replication status on node "node2" (ID: 2)
- [2017-07-27 21:09:28] [DETAIL] monitoring node "node2" (ID: 2) in degraded mode
- ...
-
-
- Output on the other node (node1) during the same event will look like this:
-
- ...
- [2017-07-27 21:08:35] [INFO] starting continuous BDR node monitoring
- [2017-07-27 21:08:35] [INFO] monitoring BDR replication status on node "node1" (ID: 1)
- [2017-07-27 21:08:51] [INFO] monitoring BDR replication status on node "node1" (ID: 1)
- [2017-07-27 21:09:07] [INFO] monitoring BDR replication status on node "node1" (ID: 1)
- [2017-07-27 21:09:23] [WARNING] unable to connect to node node2 (ID 2)
- [2017-07-27 21:09:23] [INFO] checking state of node 2, 0 of 5 attempts
- [2017-07-27 21:09:23] [INFO] sleeping 1 seconds until next reconnection attempt
- [2017-07-27 21:09:24] [INFO] checking state of node 2, 1 of 5 attempts
- [2017-07-27 21:09:24] [INFO] sleeping 1 seconds until next reconnection attempt
- [2017-07-27 21:09:25] [INFO] checking state of node 2, 2 of 5 attempts
- [2017-07-27 21:09:25] [INFO] sleeping 1 seconds until next reconnection attempt
- [2017-07-27 21:09:26] [INFO] checking state of node 2, 3 of 5 attempts
- [2017-07-27 21:09:26] [INFO] sleeping 1 seconds until next reconnection attempt
- [2017-07-27 21:09:27] [INFO] checking state of node 2, 4 of 5 attempts
- [2017-07-27 21:09:27] [INFO] sleeping 1 seconds until next reconnection attempt
- [2017-07-27 21:09:28] [WARNING] unable to reconnect to node 2 after 5 attempts
- [2017-07-27 21:09:28] [NOTICE] other node's repmgrd is handling failover
- [2017-07-27 21:09:28] [INFO] monitoring BDR replication status on node "node1" (ID: 1)
- [2017-07-27 21:09:28] [DETAIL] monitoring node "node2" (ID: 2) in degraded mode
- ...
-
-
- This assumes only the PostgreSQL instance on node2 has failed. In this case the
- &repmgrd; instance running on node2 has performed the failover. However if
- the entire server becomes unavailable, &repmgrd; on node1 will perform
- the failover.
-
-
-
- Node recovery
-
- Following failure of a BDR node, if the node subsequently becomes available again,
- a bdr_recovery event will be generated. This could potentially be used to
- reconfigure PgBouncer automatically to bring the node back into the available pool,
- however it would be prudent to manually verify the node's status before
- exposing it to the application.
-
-
- If the failed node comes back up and connects correctly, output similar to this
- will be visible in the &repmgrd; log:
-
- [2017-07-27 21:25:30] [DETAIL] monitoring node "node2" (ID: 2) in degraded mode
- [2017-07-27 21:25:46] [INFO] monitoring BDR replication status on node "node2" (ID: 2)
- [2017-07-27 21:25:46] [DETAIL] monitoring node "node2" (ID: 2) in degraded mode
- [2017-07-27 21:25:55] [INFO] active replication slot for node "node1" found after 1 seconds
- [2017-07-27 21:25:55] [NOTICE] node "node2" (ID: 2) has recovered after 986 seconds
-
-
-
-
- Shutdown of both nodes
-
- If both PostgreSQL instances are shut down, &repmgrd; will try and handle the
- situation as gracefully as possible, though with no failover candidates available
- there's not much it can do. Should this case ever occur, we recommend shutting
- down &repmgrd; on both nodes and restarting it once the PostgreSQL instances
- are running properly.
-
-
-
-
diff --git a/doc/repmgrd-configuration.xml b/doc/repmgrd-configuration.xml
index 03193759..cf45f494 100644
--- a/doc/repmgrd-configuration.xml
+++ b/doc/repmgrd-configuration.xml
@@ -619,18 +619,6 @@ repmgrd_service_stop_command='sudo systemctl repmgr12 stop'
-
-
- bdr_local_monitoring_only
-
-
-
-
-
- bdr_recovery_timeout
-
-
-
child_nodes_check_interval
diff --git a/expected/repmgr_extension.out b/expected/repmgr_extension.out
index e0dfdcf1..9013b848 100644
--- a/expected/repmgr_extension.out
+++ b/expected/repmgr_extension.out
@@ -32,18 +32,6 @@ SELECT * FROM repmgr.show_nodes;
(0 rows)
-- functions
-SELECT repmgr.am_bdr_failover_handler(-1);
- am_bdr_failover_handler
--------------------------
-
-(1 row)
-
-SELECT repmgr.am_bdr_failover_handler(NULL);
- am_bdr_failover_handler
--------------------------
-
-(1 row)
-
SELECT repmgr.get_new_primary();
get_new_primary
-----------------
@@ -92,9 +80,3 @@ SELECT repmgr.standby_set_last_updated();
(1 row)
-SELECT repmgr.unset_bdr_failover_handler();
- unset_bdr_failover_handler
-----------------------------
-
-(1 row)
-
diff --git a/repmgr--5.0--5.1.sql b/repmgr--5.0--5.1.sql
index 1fea6b16..29d09bd2 100644
--- a/repmgr--5.0--5.1.sql
+++ b/repmgr--5.0--5.1.sql
@@ -1,3 +1,5 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION repmgr" to load this file. \quit
+DROP FUNCTION am_bdr_failover_handler(INT);
+DROP FUNCTION unset_bdr_failover_handler();
diff --git a/repmgr--5.0.sql b/repmgr--5.0.sql
index ba76d7b3..8f04a821 100644
--- a/repmgr--5.0.sql
+++ b/repmgr--5.0.sql
@@ -153,16 +153,6 @@ CREATE FUNCTION reset_voting_status()
AS 'MODULE_PATHNAME', 'reset_voting_status'
LANGUAGE C STRICT;
-CREATE FUNCTION am_bdr_failover_handler(INT)
- RETURNS BOOL
- AS 'MODULE_PATHNAME', 'am_bdr_failover_handler'
- LANGUAGE C STRICT;
-
-CREATE FUNCTION unset_bdr_failover_handler()
- RETURNS VOID
- AS 'MODULE_PATHNAME', 'unset_bdr_failover_handler'
- LANGUAGE C STRICT;
-
CREATE FUNCTION get_repmgrd_pid()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_repmgrd_pid'
diff --git a/repmgr--5.1.sql b/repmgr--5.1.sql
index ba76d7b3..8f04a821 100644
--- a/repmgr--5.1.sql
+++ b/repmgr--5.1.sql
@@ -153,16 +153,6 @@ CREATE FUNCTION reset_voting_status()
AS 'MODULE_PATHNAME', 'reset_voting_status'
LANGUAGE C STRICT;
-CREATE FUNCTION am_bdr_failover_handler(INT)
- RETURNS BOOL
- AS 'MODULE_PATHNAME', 'am_bdr_failover_handler'
- LANGUAGE C STRICT;
-
-CREATE FUNCTION unset_bdr_failover_handler()
- RETURNS VOID
- AS 'MODULE_PATHNAME', 'unset_bdr_failover_handler'
- LANGUAGE C STRICT;
-
CREATE FUNCTION get_repmgrd_pid()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_repmgrd_pid'
diff --git a/repmgr-action-bdr.c b/repmgr-action-bdr.c
deleted file mode 100644
index 1950791f..00000000
--- a/repmgr-action-bdr.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * repmgr-action-bdr.c
- *
- * Implements BDR-related actions for the repmgr command line utility
- *
- * Copyright (c) 2ndQuadrant, 2010-2020
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include "repmgr.h"
-
-#include "repmgr-client-global.h"
-#include "repmgr-action-bdr.h"
-
-
-/*
- * do_bdr_register()
- *
- * As each BDR node is its own primary, registering a BDR node
- * will create the repmgr metadata schema if necessary.
- */
-void
-do_bdr_register(void)
-{
- PGconn *conn = NULL;
- BdrNodeInfoList bdr_nodes = T_BDR_NODE_INFO_LIST_INITIALIZER;
- ExtensionStatus extension_status = REPMGR_UNKNOWN;
- t_node_info node_info = T_NODE_INFO_INITIALIZER;
- RecordStatus record_status = RECORD_NOT_FOUND;
- PQExpBufferData event_details;
- bool success = true;
- char *dbname = NULL;
-
- /* sanity-check configuration for BDR-compatability */
- if (config_file_options.replication_type != REPLICATION_TYPE_BDR)
- {
- log_error(_("cannot run BDR REGISTER on a non-BDR node"));
- exit(ERR_BAD_CONFIG);
- }
-
- dbname = pg_malloc0(MAXLEN);
-
- if (dbname == NULL)
- {
- log_error(_("unable to allocate memory; terminating."));
- exit(ERR_OUT_OF_MEMORY);
- }
-
- /* store the database name for future reference */
- get_conninfo_value(config_file_options.conninfo, "dbname", dbname);
-
- conn = establish_db_connection(config_file_options.conninfo, true);
-
- if (!is_bdr_db(conn, NULL))
- {
- log_error(_("database \"%s\" is not BDR-enabled"), dbname);
- log_hint(_("when using repmgr with BDR, the repmgr schema must be stored in the BDR database"));
- PQfinish(conn);
- pfree(dbname);
- exit(ERR_BAD_CONFIG);
- }
-
- /* Check that there are at most 2 BDR nodes */
- get_all_bdr_node_records(conn, &bdr_nodes);
-
- if (bdr_nodes.node_count == 0)
- {
- log_error(_("database \"%s\" is BDR-enabled but no BDR nodes were found"), dbname);
- PQfinish(conn);
- pfree(dbname);
- exit(ERR_BAD_CONFIG);
- }
-
- /* BDR 2 implementation is for 2 nodes only */
- if (get_bdr_version_num() < 3 && bdr_nodes.node_count > 2)
- {
- log_error(_("repmgr can only support BDR 2.x clusters with 2 nodes"));
- log_detail(_("this BDR cluster has %i nodes"), bdr_nodes.node_count);
- PQfinish(conn);
- pfree(dbname);
- exit(ERR_BAD_CONFIG);
- }
-
- if (get_bdr_version_num() > 2)
- {
- log_error(_("\"repmgr bdr register\" is for BDR 2.x only"));
- PQfinish(conn);
- pfree(dbname);
- exit(ERR_BAD_CONFIG);
- }
-
-
- /* check for a matching BDR node */
- {
- PQExpBufferData bdr_local_node_name;
- bool node_match = false;
-
- initPQExpBuffer(&bdr_local_node_name);
- node_match = bdr_node_name_matches(conn, config_file_options.node_name, &bdr_local_node_name);
-
- if (node_match == false)
- {
- if (strlen(bdr_local_node_name.data))
- {
- log_error(_("local node BDR node name is \"%s\", expected: \"%s\""),
- bdr_local_node_name.data,
- config_file_options.node_name);
- log_hint(_("\"node_name\" in repmgr.conf must match \"node_name\" in bdr.bdr_nodes"));
- }
- else
- {
- log_error(_("local node does not report BDR node name"));
- log_hint(_("ensure this is an active BDR node"));
- }
-
- PQfinish(conn);
- pfree(dbname);
- termPQExpBuffer(&bdr_local_node_name);
- exit(ERR_BAD_CONFIG);
- }
-
- termPQExpBuffer(&bdr_local_node_name);
- }
-
- /* check whether repmgr extension exists, and there are no non-BDR nodes registered */
- extension_status = get_repmgr_extension_status(conn, NULL);
-
- if (extension_status == REPMGR_UNKNOWN)
- {
- log_error(_("unable to determine status of \"repmgr\" extension in database \"%s\""),
- dbname);
- PQfinish(conn);
- pfree(dbname);
- exit(ERR_BAD_CONFIG);
- }
-
- if (extension_status == REPMGR_UNAVAILABLE)
- {
- log_error(_("\"repmgr\" extension is not available"));
- PQfinish(conn);
- pfree(dbname);
- exit(ERR_BAD_CONFIG);
- }
-
- if (extension_status == REPMGR_INSTALLED)
- {
- if (!is_bdr_repmgr(conn))
- {
- log_error(_("repmgr metadatabase contains records for non-BDR nodes"));
- PQfinish(conn);
- pfree(dbname);
- exit(ERR_BAD_CONFIG);
- }
- }
- else
- {
- log_debug("creating repmgr extension in database \"%s\"", dbname);
-
- begin_transaction(conn);
-
- if (!create_repmgr_extension(conn))
- {
- log_error(_("unable to create repmgr extension - see preceding error message(s); aborting"));
- rollback_transaction(conn);
- pfree(dbname);
- PQfinish(conn);
- exit(ERR_BAD_CONFIG);
- }
-
- commit_transaction(conn);
- }
-
- pfree(dbname);
-
- if (bdr_node_has_repmgr_set(conn, config_file_options.node_name) == false)
- {
- log_debug("bdr_node_has_repmgr_set() = false");
- bdr_node_set_repmgr_set(conn, config_file_options.node_name);
- }
-
- /*
- * before adding the extension tables to the replication set, if any other
- * BDR nodes exist, populate repmgr.nodes with a copy of existing entries
- *
- * currently we won't copy the contents of any other tables
- *
- */
- {
- NodeInfoList local_node_records = T_NODE_INFO_LIST_INITIALIZER;
-
- (void) get_all_node_records(conn, &local_node_records);
-
- if (local_node_records.node_count == 0)
- {
- BdrNodeInfoList bdr_nodes = T_BDR_NODE_INFO_LIST_INITIALIZER;
- BdrNodeInfoListCell *bdr_cell = NULL;
-
- get_all_bdr_node_records(conn, &bdr_nodes);
-
- if (bdr_nodes.node_count == 0)
- {
- log_error(_("unable to retrieve any BDR node records"));
- log_detail("%s", PQerrorMessage(conn));
- PQfinish(conn);
- exit(ERR_BAD_CONFIG);
- }
-
- for (bdr_cell = bdr_nodes.head; bdr_cell; bdr_cell = bdr_cell->next)
- {
- PGconn *bdr_node_conn = NULL;
- NodeInfoList existing_nodes = T_NODE_INFO_LIST_INITIALIZER;
- NodeInfoListCell *cell = NULL;
- ExtensionStatus other_node_extension_status = REPMGR_UNKNOWN;
-
- /* skip the local node */
- if (strncmp(node_info.node_name, bdr_cell->node_info->node_name, sizeof(node_info.node_name)) == 0)
- {
- continue;
- }
-
- log_debug("connecting to BDR node \"%s\" (conninfo: \"%s\")",
- bdr_cell->node_info->node_name,
- bdr_cell->node_info->node_local_dsn);
- bdr_node_conn = establish_db_connection_quiet(bdr_cell->node_info->node_local_dsn);
-
- if (PQstatus(bdr_node_conn) != CONNECTION_OK)
- {
- continue;
- }
-
- /* check repmgr schema exists, skip if not */
- other_node_extension_status = get_repmgr_extension_status(bdr_node_conn, NULL);
-
- if (other_node_extension_status != REPMGR_INSTALLED)
- {
- continue;
- }
-
- (void) get_all_node_records(bdr_node_conn, &existing_nodes);
-
- for (cell = existing_nodes.head; cell; cell = cell->next)
- {
- log_debug("creating record for node \"%s\" (ID: %i)",
- cell->node_info->node_name, cell->node_info->node_id);
- create_node_record(conn, "bdr register", cell->node_info);
- }
-
- PQfinish(bdr_node_conn);
- break;
- }
- }
- }
-
- /* Add the repmgr extension tables to a replication set */
-
- if (get_bdr_version_num() < 3)
- {
- add_extension_tables_to_bdr_replication_set(conn);
- }
- else
- {
- /* this is the only table we need to replicate */
- char *replication_set = get_default_bdr_replication_set(conn);
-
- /*
- * this probably won't happen, but we need to be sure we're using
- * the replication set metadata correctly...
- */
- if (conn == NULL)
- {
- log_error(_("unable to retrieve default BDR replication set"));
- log_hint(_("see preceding messages"));
- log_debug("check query in get_default_bdr_replication_set()");
- exit(ERR_BAD_CONFIG);
- }
-
- if (is_table_in_bdr_replication_set(conn, "nodes", replication_set) == false)
- {
- add_table_to_bdr_replication_set(conn, "nodes", replication_set);
- }
-
- pfree(replication_set);
- }
-
- initPQExpBuffer(&event_details);
-
- begin_transaction(conn);
-
- /*
- * we'll check if a record exists (even if the schema was just created),
- * as there's a faint chance of a race condition
- */
-
- record_status = get_node_record(conn, config_file_options.node_id, &node_info);
-
- /* Update internal node record */
-
- node_info.type = BDR;
- node_info.node_id = config_file_options.node_id;
- node_info.upstream_node_id = NO_UPSTREAM_NODE;
- node_info.active = true;
- node_info.priority = config_file_options.priority;
-
- strncpy(node_info.node_name, config_file_options.node_name, sizeof(node_info.node_name));
- strncpy(node_info.location, config_file_options.location, sizeof(node_info.location));
- strncpy(node_info.conninfo, config_file_options.conninfo, sizeof(node_info.conninfo));
-
- if (record_status == RECORD_FOUND)
- {
- bool node_updated = false;
-
- /*
- * At this point we will have established there are no non-BDR
- * records, so no need to verify the node type
- */
- if (!runtime_options.force)
- {
- log_error(_("this node is already registered"));
- log_hint(_("use -F/--force to overwrite the existing node record"));
- rollback_transaction(conn);
- PQfinish(conn);
- exit(ERR_BAD_CONFIG);
- }
-
- /*
- * don't permit changing the node name - this must match the BDR node
- * name set when the node was registered.
- */
-
- if (strncmp(node_info.node_name, config_file_options.node_name, sizeof(node_info.node_name)) != 0)
- {
- log_error(_("a record for node %i is already registered with node_name \"%s\""),
- config_file_options.node_id, node_info.node_name);
- log_hint(_("node_name configured in repmgr.conf is \"%s\""), config_file_options.node_name);
-
- rollback_transaction(conn);
- PQfinish(conn);
- exit(ERR_BAD_CONFIG);
- }
-
- node_updated = update_node_record(conn, "bdr register", &node_info);
-
- if (node_updated == true)
- {
- appendPQExpBuffer(&event_details, _("node record updated for node \"%s\" (%i)"),
- config_file_options.node_name, config_file_options.node_id);
- log_verbose(LOG_NOTICE, "%s", event_details.data);
- }
- else
- {
- success = false;
- }
-
- }
- else
- {
- /* create new node record */
- bool node_created = create_node_record(conn, "bdr register", &node_info);
-
- if (node_created == true)
- {
- appendPQExpBuffer(&event_details,
- _("node record created for node \"%s\" (ID: %i)"),
- config_file_options.node_name, config_file_options.node_id);
- log_notice("%s", event_details.data);
- }
- else
- {
- success = false;
- }
- }
-
- if (success == false)
- {
- rollback_transaction(conn);
- PQfinish(conn);
- exit(ERR_DB_QUERY);
- }
-
- commit_transaction(conn);
- /* Log the event */
- create_event_notification(
- conn,
- &config_file_options,
- config_file_options.node_id,
- "bdr_register",
- true,
- event_details.data);
-
- termPQExpBuffer(&event_details);
-
- PQfinish(conn);
-
- log_notice(_("BDR node %i registered (conninfo: %s)"),
- config_file_options.node_id, config_file_options.conninfo);
-
- return;
-}
-
-
-void
-do_bdr_unregister(void)
-{
- PGconn *conn = NULL;
- ExtensionStatus extension_status = REPMGR_UNKNOWN;
- int target_node_id = UNKNOWN_NODE_ID;
- t_node_info node_info = T_NODE_INFO_INITIALIZER;
- RecordStatus record_status = RECORD_NOT_FOUND;
- bool node_record_deleted = false;
- PQExpBufferData event_details;
- char *dbname;
-
- /* sanity-check configuration for BDR-compatability */
-
- if (config_file_options.replication_type != REPLICATION_TYPE_BDR)
- {
- log_error(_("cannot run BDR UNREGISTER on a non-BDR node"));
- exit(ERR_BAD_CONFIG);
- }
-
- dbname = pg_malloc0(MAXLEN);
-
- if (dbname == NULL)
- {
- log_error(_("unable to allocate memory; terminating."));
- exit(ERR_OUT_OF_MEMORY);
- }
-
- /* store the database name for future reference */
- get_conninfo_value(config_file_options.conninfo, "dbname", dbname);
-
- conn = establish_db_connection(config_file_options.conninfo, true);
-
- if (!is_bdr_db(conn, NULL))
- {
- log_error(_("database \"%s\" is not BDR-enabled"), dbname);
- PQfinish(conn);
- pfree(dbname);
- exit(ERR_BAD_CONFIG);
- }
-
- extension_status = get_repmgr_extension_status(conn, NULL);
- if (extension_status != REPMGR_INSTALLED)
- {
- log_error(_("repmgr is not installed on database \"%s\""), dbname);
- PQfinish(conn);
- pfree(dbname);
- exit(ERR_BAD_CONFIG);
- }
-
- pfree(dbname);
-
- if (!is_bdr_repmgr(conn))
- {
- log_error(_("repmgr metadatabase contains records for non-BDR nodes"));
- PQfinish(conn);
- exit(ERR_BAD_CONFIG);
- }
-
- initPQExpBuffer(&event_details);
- if (runtime_options.node_id != UNKNOWN_NODE_ID)
- target_node_id = runtime_options.node_id;
- else
- target_node_id = config_file_options.node_id;
-
-
- /* Check node exists and is really a BDR node */
- record_status = get_node_record(conn, target_node_id, &node_info);
-
- if (record_status != RECORD_FOUND)
- {
- log_error(_("no record found for node %i"), target_node_id);
- PQfinish(conn);
- exit(ERR_BAD_CONFIG);
- }
-
- begin_transaction(conn);
-
- log_debug("unregistering node %i", target_node_id);
-
- node_record_deleted = delete_node_record(conn, target_node_id);
-
- if (node_record_deleted == false)
- {
- appendPQExpBuffer(&event_details,
- "unable to delete node record for node \"%s\" (ID: %i)",
- node_info.node_name,
- target_node_id);
- rollback_transaction(conn);
- }
- else
- {
- appendPQExpBuffer(&event_details,
- "node record deleted for node \"%s\" (ID: %i)",
- node_info.node_name,
- target_node_id);
- commit_transaction(conn);
- }
-
-
- /* Log the event */
- create_event_notification(
- conn,
- &config_file_options,
- config_file_options.node_id,
- "bdr_unregister",
- true,
- event_details.data);
-
- PQfinish(conn);
-
- log_notice(_("bdr node \"%s\" (ID: %i) successfully unregistered"),
- node_info.node_name, target_node_id);
-
- termPQExpBuffer(&event_details);
-
- return;
-}
-
-
-void
-do_bdr_help(void)
-{
- print_help_header();
-
- printf(_("Usage:\n"));
- printf(_(" %s [OPTIONS] bdr register\n"), progname());
- printf(_(" %s [OPTIONS] bdr unregister\n"), progname());
- puts("");
-
- printf(_("BDR REGISTER\n"));
- puts("");
- printf(_(" \"bdr register\" initialises the repmgr cluster and registers the initial bdr node.\n"));
- puts("");
- printf(_(" -F, --force overwrite an existing node record\n"));
- puts("");
-
- printf(_("BDR UNREGISTER\n"));
- puts("");
- printf(_(" \"bdr unregister\" unregisters an inactive BDR node.\n"));
- puts("");
- printf(_(" --node-id ID node to unregister (optional, used when the node to unregister\n" \
- " is offline)\n"));
- puts("");
-}
diff --git a/repmgr-action-bdr.h b/repmgr-action-bdr.h
deleted file mode 100644
index e065ddc0..00000000
--- a/repmgr-action-bdr.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * repmgr-action-bdr.h
- * Copyright (c) 2ndQuadrant, 2010-2020
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#ifndef _REPMGR_ACTION_BDR_H_
-#define _REPMGR_ACTION_BDR_H_
-
-extern void do_bdr_register(void);
-extern void do_bdr_unregister(void);
-
-extern void do_bdr_help(void);
-
-
-#endif /* _REPMGR_ACTION_BDR_H_ */
diff --git a/repmgr-action-node.c b/repmgr-action-node.c
index e36ac471..ad497d52 100644
--- a/repmgr-action-node.c
+++ b/repmgr-action-node.c
@@ -159,7 +159,6 @@ do_node_status(void)
_("- node is registered as standby but running as primary"));
}
break;
- case BDR:
default:
break;
}
@@ -1552,34 +1551,6 @@ do_node_check_role(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckS
_("node is witness"));
}
break;
- case BDR:
- {
- PQExpBufferData output;
-
- initPQExpBuffer(&output);
- if (is_bdr_db(conn, &output) == false)
- {
- status = CHECK_STATUS_CRITICAL;
- appendPQExpBufferStr(&details,
- output.data);
- }
- termPQExpBuffer(&output);
-
- if (status == CHECK_STATUS_OK)
- {
- if (is_active_bdr_node(conn, node_info->node_name) == false)
- {
- status = CHECK_STATUS_CRITICAL;
- appendPQExpBufferStr(&details,
- _("node is not an active BDR node"));
- }
- else
- {
- appendPQExpBufferStr(&details,
- _("node is an active BDR node"));
- }
- }
- }
default:
break;
}
diff --git a/repmgr-action-witness.c b/repmgr-action-witness.c
index 780466ec..087081d9 100644
--- a/repmgr-action-witness.c
+++ b/repmgr-action-witness.c
@@ -74,18 +74,6 @@ do_witness_register(void)
exit(ERR_BAD_CONFIG);
}
- /* check that witness node is not a BDR node */
- if (is_bdr_db_quiet(witness_conn) == true)
- {
- log_error(_("witness node is a BDR node"));
- log_hint(_("a witness node cannot be configured for a BDR cluster"));
-
- PQfinish(witness_conn);
-
- exit(ERR_BAD_CONFIG);
- }
-
-
/* connect to primary with provided parameters */
log_info(_("connecting to primary node"));
@@ -194,19 +182,6 @@ do_witness_register(void)
}
}
- /* check that primary node is not a BDR node */
- if (is_bdr_db_quiet(primary_conn) == true)
- {
- log_error(_("primary node is a BDR node"));
- log_hint(_("a witness node cannot be configured for a BDR cluster"));
-
- PQfinish(witness_conn);
- PQfinish(primary_conn);
-
- exit(ERR_BAD_CONFIG);
- }
-
-
/* create repmgr extension, if does not exist */
if (runtime_options.dry_run == false && !create_repmgr_extension(witness_conn))
{
diff --git a/repmgr-client.c b/repmgr-client.c
index 0d0576b5..7cd6ee25 100644
--- a/repmgr-client.c
+++ b/repmgr-client.c
@@ -18,9 +18,6 @@
* STANDBY FOLLOW
* STANDBY SWITCHOVER
*
- * BDR REGISTER
- * BDR UNREGISTER
- *
* CLUSTER SHOW
* CLUSTER EVENT
* CLUSTER CROSSCHECK
@@ -67,7 +64,6 @@
#include "repmgr-action-primary.h"
#include "repmgr-action-standby.h"
#include "repmgr-action-witness.h"
-#include "repmgr-action-bdr.h"
#include "repmgr-action-node.h"
#include "repmgr-action-cluster.h"
#include "repmgr-action-service.h"
@@ -817,7 +813,6 @@ main(int argc, char **argv)
* { PRIMARY | MASTER } REGISTER |
* STANDBY { REGISTER | UNREGISTER | CLONE [node] | PROMOTE | FOLLOW [node] | SWITCHOVER } |
* WITNESS { CREATE | REGISTER | UNREGISTER }
- * BDR { REGISTER | UNREGISTER } |
* NODE { STATUS | CHECK | REJOIN | SERVICE } |
* CLUSTER { CROSSCHECK | MATRIX | SHOW | EVENT | CLEANUP }
* SERVICE { STATUS | PAUSE | UNPAUSE | START | STOP }
@@ -887,6 +882,7 @@ main(int argc, char **argv)
else if (strcasecmp(repmgr_action, "STATUS") == 0)
action = NODE_STATUS;
}
+
else if (strcasecmp(repmgr_command, "WITNESS") == 0)
{
if (help_option == true)
@@ -899,23 +895,6 @@ main(int argc, char **argv)
else if (strcasecmp(repmgr_action, "UNREGISTER") == 0)
action = WITNESS_UNREGISTER;
}
- else if (strcasecmp(repmgr_command, "BDR") == 0)
- {
- if (help_option == true)
- {
- do_bdr_help();
- exit(SUCCESS);
- }
-
- if (strcasecmp(repmgr_action, "REGISTER") == 0)
- action = BDR_REGISTER;
- else if (strcasecmp(repmgr_action, "UNREGISTER") == 0)
- action = BDR_UNREGISTER;
- else if (strcasecmp(repmgr_action, "CHECK") == 0)
- action = NODE_CHECK;
- else if (strcasecmp(repmgr_action, "STATUS") == 0)
- action = NODE_STATUS;
- }
else if (strcasecmp(repmgr_command, "NODE") == 0)
{
@@ -1355,13 +1334,6 @@ main(int argc, char **argv)
case WITNESS_UNREGISTER:
do_witness_unregister();
break;
- /* BDR */
- case BDR_REGISTER:
- do_bdr_register();
- break;
- case BDR_UNREGISTER:
- do_bdr_unregister();
- break;
/* NODE */
case NODE_STATUS:
@@ -1681,7 +1653,6 @@ check_cli_parameters(const int action)
case STANDBY_CLONE:
case STANDBY_REGISTER:
case STANDBY_FOLLOW:
- case BDR_REGISTER:
break;
default:
item_list_append_format(&cli_warnings,
@@ -2220,7 +2191,6 @@ format_node_status(t_node_info *node_info, PQExpBufferData *node_status, PQExpBu
break;
case WITNESS:
- case BDR:
{
/* node is reachable */
if (node_info->node_status == NODE_STATUS_UP)
@@ -2469,11 +2439,6 @@ action_name(const int action)
case WITNESS_UNREGISTER:
return "WITNESS UNREGISTER";
- case BDR_REGISTER:
- return "BDR REGISTER";
- case BDR_UNREGISTER:
- return "BDR UNREGISTER";
-
case NODE_STATUS:
return "NODE STATUS";
case NODE_CHECK:
@@ -2609,7 +2574,6 @@ do_help(void)
printf(_("Usage:\n"));
printf(_(" %s [OPTIONS] primary {register|unregister}\n"), progname());
printf(_(" %s [OPTIONS] standby {register|unregister|clone|promote|follow|switchover}\n"), progname());
- printf(_(" %s [OPTIONS] bdr {register|unregister}\n"), progname());
printf(_(" %s [OPTIONS] node {status|check|rejoin|service}\n"), progname());
printf(_(" %s [OPTIONS] cluster {show|event|matrix|crosscheck|cleanup}\n"), progname());
printf(_(" %s [OPTIONS] witness {register|unregister}\n"), progname());
@@ -2618,7 +2582,7 @@ do_help(void)
puts("");
- printf(_(" Execute \"%s {primary|standby|bdr|node|cluster|witness|service} --help\" to see command-specific options\n"), progname());
+ printf(_(" Execute \"%s {primary|standby|node|cluster|witness|service} --help\" to see command-specific options\n"), progname());
puts("");
@@ -2742,14 +2706,7 @@ create_repmgr_extension(PGconn *conn)
/* 4. Create extension */
- initPQExpBuffer(&query);
-
- wrap_ddl_query(&query, config_file_options.replication_type,
- "CREATE EXTENSION repmgr");
-
- res = PQexec(schema_create_conn, query.data);
-
- termPQExpBuffer(&query);
+ res = PQexec(schema_create_conn, "CREATE EXTENSION repmgr");
if ((PQresultStatus(res) != PGRES_COMMAND_OK && PQresultStatus(res) != PGRES_TUPLES_OK))
{
@@ -2770,13 +2727,13 @@ create_repmgr_extension(PGconn *conn)
{
initPQExpBuffer(&query);
- wrap_ddl_query(&query, config_file_options.replication_type,
- "GRANT USAGE ON SCHEMA repmgr TO %s",
- userinfo.username);
+ appendPQExpBuffer(&query,
+ "GRANT USAGE ON SCHEMA repmgr TO %s",
+ userinfo.username);
res = PQexec(schema_create_conn, query.data);
-
termPQExpBuffer(&query);
+
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
log_error(_("unable to grant usage on \"repmgr\" extension to %s:\n %s"),
@@ -2791,12 +2748,12 @@ create_repmgr_extension(PGconn *conn)
}
initPQExpBuffer(&query);
- wrap_ddl_query(&query, config_file_options.replication_type,
- "GRANT ALL ON ALL TABLES IN SCHEMA repmgr TO %s",
- userinfo.username);
+
+ appendPQExpBuffer(&query,
+ "GRANT ALL ON ALL TABLES IN SCHEMA repmgr TO %s",
+ userinfo.username);
res = PQexec(schema_create_conn, query.data);
-
termPQExpBuffer(&query);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
diff --git a/repmgr-client.h b/repmgr-client.h
index 83132298..95abb55a 100644
--- a/repmgr-client.h
+++ b/repmgr-client.h
@@ -34,23 +34,21 @@
#define STANDBY_SWITCHOVER 8
#define WITNESS_REGISTER 9
#define WITNESS_UNREGISTER 10
-#define BDR_REGISTER 11
-#define BDR_UNREGISTER 12
-#define NODE_STATUS 13
-#define NODE_CHECK 14
-#define NODE_SERVICE 15
-#define NODE_REJOIN 16
-#define NODE_CONTROL 17
-#define CLUSTER_SHOW 18
-#define CLUSTER_CLEANUP 19
-#define CLUSTER_MATRIX 20
-#define CLUSTER_CROSSCHECK 21
-#define CLUSTER_EVENT 22
-#define SERVICE_STATUS 23
-#define SERVICE_PAUSE 24
-#define SERVICE_UNPAUSE 25
-#define DAEMON_START 26
-#define DAEMON_STOP 27
+#define NODE_STATUS 11
+#define NODE_CHECK 12
+#define NODE_SERVICE 13
+#define NODE_REJOIN 14
+#define NODE_CONTROL 15
+#define CLUSTER_SHOW 16
+#define CLUSTER_CLEANUP 17
+#define CLUSTER_MATRIX 18
+#define CLUSTER_CROSSCHECK 19
+#define CLUSTER_EVENT 20
+#define SERVICE_STATUS 21
+#define SERVICE_PAUSE 22
+#define SERVICE_UNPAUSE 23
+#define DAEMON_START 24
+#define DAEMON_STOP 25
/* command line options without short versions */
#define OPT_HELP 1001
diff --git a/repmgr.c b/repmgr.c
index 9a54e588..1303f41b 100644
--- a/repmgr.c
+++ b/repmgr.c
@@ -84,8 +84,6 @@ typedef struct repmgrdSharedState
int current_electoral_term;
int candidate_node_id;
bool follow_new_primary;
- /* BDR failover */
- int bdr_failover_handler;
} repmgrdSharedState;
static repmgrdSharedState *shared_state = NULL;
@@ -131,12 +129,6 @@ PG_FUNCTION_INFO_V1(get_new_primary);
Datum reset_voting_status(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(reset_voting_status);
-Datum am_bdr_failover_handler(PG_FUNCTION_ARGS);
-PG_FUNCTION_INFO_V1(am_bdr_failover_handler);
-
-Datum unset_bdr_failover_handler(PG_FUNCTION_ARGS);
-PG_FUNCTION_INFO_V1(unset_bdr_failover_handler);
-
Datum set_repmgrd_pid(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(set_repmgrd_pid);
@@ -241,7 +233,6 @@ repmgr_shmem_startup(void)
shared_state->voting_status = VS_NO_VOTE;
shared_state->candidate_node_id = UNKNOWN_NODE_ID;
shared_state->follow_new_primary = false;
- shared_state->bdr_failover_handler = UNKNOWN_NODE_ID;
}
LWLockRelease(AddinShmemInitLock);
@@ -571,63 +562,6 @@ reset_voting_status(PG_FUNCTION_ARGS)
}
-Datum
-am_bdr_failover_handler(PG_FUNCTION_ARGS)
-{
- int node_id = UNKNOWN_NODE_ID;
- bool am_handler = false;
-
- if (!shared_state)
- PG_RETURN_NULL();
-
- if (PG_ARGISNULL(0))
- PG_RETURN_NULL();
-
- node_id = PG_GETARG_INT32(0);
-
- LWLockAcquire(shared_state->lock, LW_SHARED);
-
- if (shared_state->bdr_failover_handler == UNKNOWN_NODE_ID)
- {
- LWLockRelease(shared_state->lock);
- LWLockAcquire(shared_state->lock, LW_EXCLUSIVE);
- shared_state->bdr_failover_handler = node_id;
- am_handler = true;
- }
- else if (shared_state->bdr_failover_handler == node_id)
- {
- am_handler = true;
- }
-
- LWLockRelease(shared_state->lock);
-
- PG_RETURN_BOOL(am_handler);
-}
-
-
-Datum
-unset_bdr_failover_handler(PG_FUNCTION_ARGS)
-{
- if (!shared_state)
- PG_RETURN_NULL();
-
- LWLockAcquire(shared_state->lock, LW_SHARED);
-
- /* only do something if local_node_id is initialised */
- if (shared_state->local_node_id != UNKNOWN_NODE_ID)
- {
- LWLockRelease(shared_state->lock);
- LWLockAcquire(shared_state->lock, LW_EXCLUSIVE);
-
- shared_state->bdr_failover_handler = UNKNOWN_NODE_ID;
- }
-
- LWLockRelease(shared_state->lock);
-
- PG_RETURN_VOID();
-}
-
-
/*
* Returns the repmgrd pid; or NULL if none set; or -1 if set but repmgrd
* process not running (TODO!)
diff --git a/repmgr.conf.sample b/repmgr.conf.sample
index 1d7ffb1e..cd874e3c 100644
--- a/repmgr.conf.sample
+++ b/repmgr.conf.sample
@@ -71,8 +71,7 @@
#replication_user='repmgr' # User to make replication connections with, if not set
# defaults to the user defined in "conninfo".
-#replication_type='physical' # Must be one of "physical" or "bdr".
- # NOTE: "bdr" can only be used with BDR 2.x
+#replication_type='physical' # Must "physical" (the default).
#location='default' # An arbitrary string defining the location of the node; this
# is used during failover to check visibility of the
@@ -290,7 +289,6 @@ ssh_options='-q -o ConnectTimeout=10' # Options to append to "ssh"
# node or follow the new upstream node
# 'manual': repmgrd will take no action and the node will require
# manual attention to reattach it to replication
- # (does not apply to BDR mode)
#priority=100 # indicates a preferred priority for promoting nodes;
# a value of zero prevents the node being promoted to primary
@@ -436,12 +434,3 @@ ssh_options='-q -o ConnectTimeout=10' # Options to append to "ssh"
# issues with shutting down the demotion candidate.
-#------------------------------------------------------------------------------
-# BDR monitoring options
-#------------------------------------------------------------------------------
-
-#bdr_local_monitoring_only=false # Only monitor the local node; no checks will be
- # performed on the other node
-#bdr_recovery_timeout # If a BDR node was offline and has become available
- # maximum length of time in seconds to wait for the
- # node to reconnect to the cluster
diff --git a/repmgr.h b/repmgr.h
index 7ca53ae5..9ebb8d3c 100644
--- a/repmgr.h
+++ b/repmgr.h
@@ -78,10 +78,8 @@
#define MIN_SUPPORTED_VERSION_NUM 90300
#define REPLICATION_TYPE_PHYSICAL 1
-#define REPLICATION_TYPE_BDR 2
#define UNKNOWN_SERVER_VERSION_NUM -1
-#define UNKNOWN_BDR_VERSION_NUM -1
#define UNKNOWN_REPMGR_VERSION_NUM -1
#define UNKNOWN_TIMELINE_ID -1
@@ -98,8 +96,6 @@
#define ARCHIVE_STATUS_DIR_ERROR -1
#define NO_DEGRADED_MONITORING_ELAPSED -1
-#define BDR2_REPLICATION_SET_NAME "repmgr"
-
/*
* various default values - ensure repmgr.conf.sample is update
* if any of these are changed
@@ -113,7 +109,6 @@
#define DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT 60 /* seconds */
#define DEFAULT_PRIMARY_FOLLOW_TIMEOUT 60 /* seconds */
#define DEFAULT_STANDBY_FOLLOW_TIMEOUT 30 /* seconds */
-#define DEFAULT_BDR_RECOVERY_TIMEOUT 30 /* seconds */
#define DEFAULT_ARCHIVE_READY_WARNING 16 /* WAL files */
#define DEFAULT_ARCHIVE_READY_CRITICAL 128 /* WAL files */
#define DEFAULT_REPLICATION_LAG_WARNING 300 /* seconds */
diff --git a/repmgrd-bdr.c b/repmgrd-bdr.c
deleted file mode 100644
index 56cd65cd..00000000
--- a/repmgrd-bdr.c
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * repmgrd-bdr.c - BDR functionality for repmgrd
- *
- * Copyright (c) 2ndQuadrant, 2010-2020
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include
-
-#include "repmgr.h"
-#include "repmgrd.h"
-#include "repmgrd-bdr.h"
-#include "configfile.h"
-
-
-static void do_bdr_failover(NodeInfoList *nodes, t_node_info *monitored_node);
-static void do_bdr_recovery(NodeInfoList *nodes, t_node_info *monitored_node);
-
-
-void
-do_bdr_node_check(void)
-{
- /* nothing to do at the moment */
-}
-
-void
-handle_sigint_bdr(SIGNAL_ARGS)
-{
- PQExpBufferData event_details;
-
- initPQExpBuffer(&event_details);
-
- appendPQExpBuffer(&event_details,
- _("%s signal received"),
- postgres_signal_arg == SIGTERM
- ? "TERM" : "INT");
-
- log_notice("%s", event_details.data);
-
- create_event_notification(local_conn,
- &config_file_options,
- config_file_options.node_id,
- "repmgrd_shutdown",
- true,
- event_details.data);
- termPQExpBuffer(&event_details);
-
- terminate(SUCCESS);
-}
-
-
-void
-monitor_bdr(void)
-{
- NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
- t_bdr_node_info bdr_node_info = T_BDR_NODE_INFO_INITIALIZER;
- RecordStatus record_status;
- NodeInfoListCell *cell;
- instr_time log_status_interval_start;
-
- /* sanity check local database */
- log_info(_("connecting to local database \"%s\""),
- config_file_options.conninfo);
-
- local_conn = establish_db_connection(config_file_options.conninfo, true);
-
- /*
- * Local node must be running
- */
- if (PQstatus(local_conn) != CONNECTION_OK)
- {
- log_error(_("unable connect to local node (ID: %i), terminating"),
- local_node_info.node_id);
- log_hint(_("local node must be running before repmgrd can start"));
- PQfinish(local_conn);
- exit(ERR_DB_CONN);
- }
-
- /*
- * Verify that database is a BDR one TODO: check if supported BDR version?
- */
- log_info(_("connected to database, checking for BDR"));
-
- if (!is_bdr_db(local_conn, NULL))
- {
- log_error(_("database is not BDR-enabled"));
- PQfinish(local_conn);
- exit(ERR_BAD_CONFIG);
- }
-
- /*
- * Check this is a supported BDR version (basically BDR 2.x)
- */
- if (get_bdr_version_num() > 2)
- {
- log_error(_("\"bdr\" mode is for BDR 2.x only"));
- log_hint(_("for BDR 3 and later, use \"replication_type=physical\""));
- log_error(_("database is not BDR-enabled"));
- exit(ERR_DB_CONN);
- }
-
- if (is_table_in_bdr_replication_set(local_conn, "nodes", "repmgr") == false)
- {
- log_error(_("repmgr metadata table 'repmgr.%s' is not in the 'repmgr' replication set"),
- "nodes");
-
- /*
- * TODO: add `repmgr bdr sync` or similar for this situation, and hint
- * here
- */
-
- exit(ERR_BAD_CONFIG);
- }
-
- record_status = get_bdr_node_record_by_name(local_conn, local_node_info.node_name, &bdr_node_info);
-
- if (record_status != RECORD_FOUND)
- {
- log_error(_("unable to retrieve BDR record for node \"%s\", terminating"),
- local_node_info.node_name);
- PQfinish(local_conn);
- exit(ERR_BAD_CONFIG);
- }
-
- if (local_node_info.active == false)
- {
- log_error(_("local node (ID: %i) is marked as inactive in repmgr"),
- local_node_info.node_id);
- log_hint(_("if the node has been reactivated, run \"repmgr bdr register --force\" and restart repmgrd"));
- PQfinish(local_conn);
- exit(ERR_BAD_CONFIG);
- }
-
- if (is_active_bdr_node(local_conn, local_node_info.node_name) == false)
- {
- log_error(_("BDR node \"%s\" is not active, terminating"),
- local_node_info.node_name);
- PQfinish(local_conn);
- exit(ERR_BAD_CONFIG);
- }
-
- /* Log startup event */
- create_event_record(local_conn,
- &config_file_options,
- config_file_options.node_id,
- "repmgrd_start",
- true,
- NULL);
-
- /*
- * retrieve list of all nodes - we'll need these if the DB connection goes
- * away
- */
- if (get_all_node_records(local_conn, &nodes) == false)
- {
- /* get_all_node_records() will display the error */
- PQfinish(local_conn);
- exit(ERR_BAD_CONFIG);
- }
-
-
- /* we're expecting all (both) nodes to be up */
- for (cell = nodes.head; cell; cell = cell->next)
- {
- cell->node_info->node_status = NODE_STATUS_UP;
- }
-
- log_info(_("starting continuous BDR node monitoring on node %i"),
- config_file_options.node_id);
-
- INSTR_TIME_SET_CURRENT(log_status_interval_start);
-
- while (true)
- {
-
- /* monitoring loop */
- log_verbose(LOG_DEBUG, "BDR check loop - checking %i nodes", nodes.node_count);
-
- for (cell = nodes.head; cell; cell = cell->next)
- {
- if (config_file_options.bdr_local_monitoring_only == true
- && cell->node_info->node_id != local_node_info.node_id)
- {
- continue;
- }
-
- if (cell->node_info->node_id == local_node_info.node_id)
- {
- log_debug("checking local node %i in %s state",
- local_node_info.node_id,
- print_monitoring_state(cell->node_info->monitoring_state));
- }
- else
- {
- log_debug("checking other node %i in %s state",
- cell->node_info->node_id,
- print_monitoring_state(cell->node_info->monitoring_state));
- }
-
-
- switch (cell->node_info->monitoring_state)
- {
- case MS_NORMAL:
- {
- if (is_server_available(cell->node_info->conninfo) == false)
- {
- /* node is down, we were expecting it to be up */
- if (cell->node_info->node_status == NODE_STATUS_UP)
- {
- instr_time node_unreachable_start;
-
- INSTR_TIME_SET_CURRENT(node_unreachable_start);
-
- cell->node_info->node_status = NODE_STATUS_DOWN;
-
- if (cell->node_info->conn != NULL)
- {
- PQfinish(cell->node_info->conn);
- cell->node_info->conn = NULL;
- }
-
- log_warning(_("unable to connect to node \"%s\" (ID %i)"),
- cell->node_info->node_name, cell->node_info->node_id);
- try_reconnect(&cell->node_info->conn, cell->node_info);
-
- /* node has recovered - log and continue */
- if (cell->node_info->node_status == NODE_STATUS_UP)
- {
- int node_unreachable_elapsed = calculate_elapsed(node_unreachable_start);
- PQExpBufferData event_details;
-
- initPQExpBuffer(&event_details);
-
- appendPQExpBuffer(&event_details,
- _("reconnected to node %i after %i seconds"),
- cell->node_info->node_id,
- node_unreachable_elapsed);
- log_notice("%s", event_details.data);
-
- create_event_notification(cell->node_info->conn,
- &config_file_options,
- config_file_options.node_id,
- "bdr_reconnect",
- true,
- event_details.data);
- termPQExpBuffer(&event_details);
-
- goto loop;
- }
-
- /* still down after reconnect attempt(s) */
- if (cell->node_info->node_status == NODE_STATUS_DOWN)
- {
- do_bdr_failover(&nodes, cell->node_info);
- goto loop;
- }
- }
- }
- }
- break;
- case MS_DEGRADED:
- {
- /* degraded monitoring */
- if (is_server_available(cell->node_info->conninfo) == true)
- {
- do_bdr_recovery(&nodes, cell->node_info);
- }
-
- }
- break;
- }
- }
-
-loop:
-
- /* emit "still alive" log message at regular intervals, if requested */
- if (config_file_options.log_status_interval > 0)
- {
- int log_status_interval_elapsed = calculate_elapsed(log_status_interval_start);
- if (log_status_interval_elapsed >= config_file_options.log_status_interval)
- {
- log_info(_("monitoring BDR replication status on node \"%s\" (ID: %i)"),
- local_node_info.node_name,
- local_node_info.node_id);
-
- for (cell = nodes.head; cell; cell = cell->next)
- {
- if (cell->node_info->monitoring_state == MS_DEGRADED)
- {
- log_detail(_("monitoring node \"%s\" (ID: %i) in degraded mode"),
- cell->node_info->node_name,
- cell->node_info->node_id);
- }
- }
- INSTR_TIME_SET_CURRENT(log_status_interval_start);
- }
- }
-
- if (got_SIGHUP)
- {
- /*
- * if we can reload, then could need to change local_conn
- */
- if (reload_config(&config_file_options, BDR))
- {
- PQfinish(local_conn);
- local_conn = establish_db_connection(config_file_options.conninfo, true);
- update_registration(local_conn);
- }
-
- got_SIGHUP = false;
- }
-
- /* XXX this looks like it will never be called */
- if (got_SIGHUP)
- {
- log_debug("SIGHUP received");
-
- if (reload_config(&config_file_options, BDR))
- {
- PQfinish(local_conn);
- local_conn = establish_db_connection(config_file_options.conninfo, true);
-
- if (*config_file_options.log_file)
- {
- FILE *fd;
-
- fd = freopen(config_file_options.log_file, "a", stderr);
- if (fd == NULL)
- {
- fprintf(stderr, "error reopening stderr to \"%s\": %s",
- config_file_options.log_file, strerror(errno));
- }
- }
- }
- got_SIGHUP = false;
- }
-
- log_verbose(LOG_DEBUG, "sleeping %i seconds (\"monitor_interval_secs\")",
- config_file_options.monitor_interval_secs);
- sleep(config_file_options.monitor_interval_secs);
- }
-
- return;
-}
-
-/*
- * do_bdr_failover()
- *
- * Here we attempt to perform a BDR "failover".
- *
- * As there's no equivalent of a physical replication failover,
- * we'll do the following:
- *
- * - connect to active node
- * - generate an event log record on that node
- * - optionally execute `bdr_failover_command`, passing the conninfo string
- * of that node to the command; this can be used for e.g. reconfiguring
- * pgbouncer.
- *
- */
-
-void
-do_bdr_failover(NodeInfoList *nodes, t_node_info *monitored_node)
-{
- PGconn *next_node_conn = NULL;
- NodeInfoListCell *cell;
- t_event_info event_info = T_EVENT_INFO_INITIALIZER;
- t_node_info target_node = T_NODE_INFO_INITIALIZER;
- t_node_info failed_node = T_NODE_INFO_INITIALIZER;
- RecordStatus record_status;
-
- /* if one of the two nodes is down, cluster will be in a degraded state */
- monitored_node->monitoring_state = MS_DEGRADED;
- INSTR_TIME_SET_CURRENT(degraded_monitoring_start);
-
- /* terminate local connection if this is the failed node */
- if (monitored_node->node_id == local_node_info.node_id)
- {
- PQfinish(local_conn);
- local_conn = NULL;
- }
-
-
- /* get other node */
-
- for (cell = nodes->head; cell; cell = cell->next)
- {
- log_debug("do_bdr_failover() %s", cell->node_info->node_name);
-
- /*
- * don't attempt to connect to the current monitored node, as that's
- * the one which has failed
- */
- if (cell->node_info->node_id == monitored_node->node_id)
- continue;
-
- /* TODO: reuse local conn if local node is up */
- next_node_conn = establish_db_connection(cell->node_info->conninfo, false);
-
- if (PQstatus(next_node_conn) == CONNECTION_OK)
- {
- record_status = get_node_record(next_node_conn,
- cell->node_info->node_id,
- &target_node);
-
- if (record_status == RECORD_FOUND)
- {
- break;
- }
- }
-
- next_node_conn = NULL;
- }
-
- /* shouldn't happen, and if it does, it means everything is down */
- if (next_node_conn == NULL)
- {
- log_error(_("no other available node found"));
-
- /* no other nodes found - continue degraded monitoring */
- return;
- }
-
- /*
- * check if the node record for the failed node is still marked as active,
- * if not it means the other node has done the "failover" already
- */
-
- record_status = get_node_record(next_node_conn,
- monitored_node->node_id,
- &failed_node);
-
- if (record_status == RECORD_FOUND && failed_node.active == false)
- {
- PQfinish(next_node_conn);
- log_notice(_("record for node %i has already been set inactive"),
- failed_node.node_id);
- return;
- }
-
- if (am_bdr_failover_handler(next_node_conn, local_node_info.node_id) == false)
- {
- PQfinish(next_node_conn);
- log_notice(_("other node's repmgrd is handling failover"));
- return;
- }
-
-
- /* check here that the node hasn't come back up */
- if (is_server_available(monitored_node->conninfo) == true)
- {
- log_notice(_("node %i has reappeared, aborting failover"),
- monitored_node->node_id);
- monitored_node->monitoring_state = MS_NORMAL;
- PQfinish(next_node_conn);
- }
-
- log_debug("this node is the failover handler");
-
- {
- PQExpBufferData event_details;
-
- initPQExpBuffer(&event_details);
-
- event_info.conninfo_str = target_node.conninfo;
- event_info.node_name = target_node.node_name;
-
- /* update node record on the active node */
- update_node_record_set_active(next_node_conn, monitored_node->node_id, false);
-
- log_notice(_("setting node record for node %i to inactive"), monitored_node->node_id);
-
- appendPQExpBuffer(&event_details,
- _("node \"%s\" (ID: %i) detected as failed; next available node is \"%s\" (ID: %i)"),
- monitored_node->node_name,
- monitored_node->node_id,
- target_node.node_name,
- target_node.node_id);
-
- /*
- * Create an event record
- *
- * If we were able to connect to another node, we'll update the event log
- * there.
- *
- * In any case the event notification command will be triggered with the
- * event "bdr_failover"
- */
-
-
- create_event_notification_extended(next_node_conn,
- &config_file_options,
- monitored_node->node_id,
- "bdr_failover",
- true,
- event_details.data,
- &event_info);
-
- log_info("%s", event_details.data);
-
- termPQExpBuffer(&event_details);
- }
-
- unset_bdr_failover_handler(next_node_conn);
-
- PQfinish(next_node_conn);
-
-
- return;
-}
-
-static void
-do_bdr_recovery(NodeInfoList *nodes, t_node_info *monitored_node)
-{
- PGconn *recovered_node_conn;
-
- t_event_info event_info = T_EVENT_INFO_INITIALIZER;
- int i;
- bool slot_reactivated = false;
- int node_recovery_elapsed;
-
- char node_name[MAXLEN] = "";
-
- log_debug("handling recovery for monitored node %i", monitored_node->node_id);
-
- recovered_node_conn = establish_db_connection(monitored_node->conninfo, false);
-
- if (PQstatus(recovered_node_conn) != CONNECTION_OK)
- {
- PQfinish(recovered_node_conn);
- return;
- }
-
- if (PQstatus(local_conn) != CONNECTION_OK)
- {
- log_debug("no local connection - attempting to reconnect ");
- local_conn = establish_db_connection(config_file_options.conninfo, false);
- }
-
- /*
- * still unable to connect - the local node is probably down, so we can't
- * check for reconnection
- */
- if (PQstatus(local_conn) != CONNECTION_OK)
- {
- PQExpBufferData event_details;
-
- local_conn = NULL;
- log_warning(_("unable to reconnect to local node"));
-
- initPQExpBuffer(&event_details);
-
- node_recovery_elapsed = calculate_elapsed(degraded_monitoring_start);
- monitored_node->monitoring_state = MS_NORMAL;
- monitored_node->node_status = NODE_STATUS_UP;
-
- appendPQExpBuffer(
- &event_details,
- _("node \"%s\" (ID: %i) has become available after %i seconds"),
- monitored_node->node_name,
- monitored_node->node_id,
- node_recovery_elapsed);
-
- log_notice("%s", event_details.data);
-
- termPQExpBuffer(&event_details);
-
- PQfinish(recovered_node_conn);
-
- return;
- }
-
- get_bdr_other_node_name(local_conn, local_node_info.node_id, node_name);
-
- log_info(_("detected recovery on node \"%s\" (ID: %i), checking status"),
- monitored_node->node_name,
- monitored_node->node_id);
-
- for (i = 0; i < config_file_options.bdr_recovery_timeout; i++)
- {
- ReplSlotStatus slot_status;
-
- log_debug("checking for state of replication slot for node \"%s\"", node_name);
-
- slot_status = get_bdr_node_replication_slot_status(
- local_conn,
- node_name);
-
- if (slot_status == SLOT_ACTIVE)
- {
- slot_reactivated = true;
- break;
- }
-
- sleep(1);
- }
-
- /* mark node as up */
- monitored_node->node_status = NODE_STATUS_UP;
-
- if (slot_reactivated == false)
- {
- log_warning(_("no active replication slot for node \"%s\" found after %i seconds"),
- node_name,
- config_file_options.bdr_recovery_timeout);
- log_detail(_("this probably means inter-node BDR connections have not been re-established"));
- PQfinish(recovered_node_conn);
- return;
- }
-
- log_info(_("active replication slot for node \"%s\" found after %i seconds"),
- node_name,
- i);
-
- node_recovery_elapsed = calculate_elapsed(degraded_monitoring_start);
- monitored_node->monitoring_state = MS_NORMAL;
-
- {
- PQExpBufferData event_details;
-
- initPQExpBuffer(&event_details);
-
- appendPQExpBuffer(&event_details,
- _("node \"%s\" (ID: %i) has recovered after %i seconds"),
- monitored_node->node_name,
- monitored_node->node_id,
- node_recovery_elapsed);
-
- log_notice("%s", event_details.data);
-
-
- /* other node will generate the event */
- if (monitored_node->node_id == local_node_info.node_id)
- {
- termPQExpBuffer(&event_details);
- PQfinish(recovered_node_conn);
-
- return;
- }
-
-
- /* generate the event on the currently active node only */
- if (monitored_node->node_id != local_node_info.node_id)
- {
- event_info.conninfo_str = monitored_node->conninfo;
- event_info.node_name = monitored_node->node_name;
-
- create_event_notification_extended(local_conn,
- &config_file_options,
- config_file_options.node_id,
- "bdr_recovery",
- true,
- event_details.data,
- &event_info);
- }
-
- termPQExpBuffer(&event_details);
- }
-
- update_node_record_set_active(local_conn, monitored_node->node_id, true);
-
- PQfinish(recovered_node_conn);
-
- return;
-}
diff --git a/repmgrd-bdr.h b/repmgrd-bdr.h
deleted file mode 100644
index 208dad81..00000000
--- a/repmgrd-bdr.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * repmgrd-bdr.h
- * Copyright (c) 2ndQuadrant, 2010-2020
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#ifndef _REPMGRD_BDR_H_
-#define _REPMGRD_BDR_H_
-
-extern void do_bdr_node_check(void);
-extern void monitor_bdr(void);
-
-extern void handle_sigint_bdr(SIGNAL_ARGS);
-#endif /* _REPMGRD_BDR_H_ */
diff --git a/repmgrd.c b/repmgrd.c
index ff78b1f5..383a6aa9 100644
--- a/repmgrd.c
+++ b/repmgrd.c
@@ -26,7 +26,6 @@
#include "repmgr.h"
#include "repmgrd.h"
#include "repmgrd-physical.h"
-#include "repmgrd-bdr.h"
#include "configfile.h"
#include "voting.h"
@@ -484,9 +483,6 @@ main(int argc, char **argv)
case REPLICATION_TYPE_PHYSICAL:
log_hint(_("check that 'repmgr (primary|standby) register' was executed for this node"));
break;
- case REPLICATION_TYPE_BDR:
- log_hint(_("check that 'repmgr bdr register' was executed for this node"));
- break;
}
close_connection(&local_conn);
@@ -513,12 +509,7 @@ main(int argc, char **argv)
}
}
- if (config_file_options.replication_type == REPLICATION_TYPE_BDR)
- {
- log_debug("node id is %i", local_node_info.node_id);
- do_bdr_node_check();
- }
- else
+ if (config_file_options.replication_type == REPLICATION_TYPE_PHYSICAL)
{
log_debug("node id is %i, upstream node id is %i",
local_node_info.node_id,
@@ -526,8 +517,6 @@ main(int argc, char **argv)
do_physical_node_check();
}
-
-
if (daemonize == true)
{
daemonize_process();
@@ -576,9 +565,6 @@ start_monitoring(void)
case WITNESS:
monitor_streaming_witness();
break;
- case BDR:
- monitor_bdr();
- return;
case UNKNOWN:
/* should never happen */
break;
@@ -771,10 +757,6 @@ setup_event_handlers(void)
*/
switch (config_file_options.replication_type)
{
- case REPLICATION_TYPE_BDR:
- pqsignal(SIGINT, handle_sigint_bdr);
- pqsignal(SIGTERM, handle_sigint_bdr);
- break;
case REPLICATION_TYPE_PHYSICAL:
pqsignal(SIGINT, handle_sigint_physical);
pqsignal(SIGTERM, handle_sigint_physical);
diff --git a/scripts/bdr-pgbouncer.sh b/scripts/bdr-pgbouncer.sh
deleted file mode 100644
index fa244cc9..00000000
--- a/scripts/bdr-pgbouncer.sh
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env bash
-set -u
-set -e
-
-# Process parameters passed to script
-# -----------------------------------
-#
-# This assumes the repmgr "event_notification_command" is defined like this:
-#
-# event_notification_command='/path/to/bdr-pgbouncer.sh %n %e %s "%c" "%a" >> /tmp/bdr-failover.log 2>&1'
-#
-# Adjust as appropriate.
-
-NODE_ID=$1
-EVENT_TYPE=$2
-SUCCESS=$3
-NEXT_CONNINFO=$4
-NEXT_NODE_NAME=$5
-
-if [ "$EVENT_TYPE" != "bdr_failover" ]; then
- echo "unable to handle event type '$EVENT_TYPE'"
- exit
-fi
-
-# Define database name here
-# -------------------------
-#
-# Note: this assumes the BDR-enabled database has the same name on
-# both hosts
-
-BDR_DBNAME=bdr_db
-
-# Define PgBouncer hosts here
-# ---------------------------
-
-PGBOUNCER_HOSTS="host1 host2"
-PGBOUNCER_PORTS=(6432 6432)
-PGBOUNCER_DATABASE_INI=(/path/to/pgbouncer.database.ini /path/to/pgbouncer.database.ini)
-
-
-# Define local host info here
-# ---------------------------
-
-THIS_HOST="host1"
-THIS_PGBOUNCER_PORT="6432"
-THIS_DB_PORT="5432"
-
-# Pause all pgbouncer nodes to minimize impact on clients
-# -------------------------------------------------------
-
-i=0
-for HOST in $PGBOUNCER_HOSTS
-do
- PORT="${PGBOUNCER_PORTS[$i]}"
-
- psql -tc "pause" -h $HOST -p $PORT -U postgres pgbouncer
-
- i=$((i+1))
-done
-
-# Copy pgbouncer database ini file to all nodes and restart pgbouncer
-# -------------------------------------------------------------------
-
-i=0
-THIS_HOSTPORT="$THIS_HOST$THIS_PGBOUNCER_PORT"
-PGBOUNCER_DATABASE_INI_NEW="/tmp/pgbouncer.database.ini.new"
-
-for HOST in $PGBOUNCER_HOSTS
-do
- PORT="${PGBOUNCER_PORTS[$i]}"
-
- # Recreate the pgbouncer config file
- # ----------------------------------
- echo -e "[databases]\n" > $PGBOUNCER_DATABASE_INI_NEW
-
- echo -e "$BDR_DBNAME= $NEXT_CONNINFO application_name=pgbouncer_$PORT" >> $PGBOUNCER_DATABASE_INI_NEW
-
- # Copy file to host
- # -----------------
- CONFIG="${PGBOUNCER_DATABASE_INI[$i]}"
-
- if [ "$HOST$PORT" != "$THIS_HOSTPORT" ]; then
- rsync $PGBOUNCER_DATABASE_INI_NEW $HOST:$CONFIG
- else
- cp $PGBOUNCER_DATABASE_INI_NEW $CONFIG
- fi
-
- # Reload and resume PgBouncer
- # ---------------------------
-
- psql -tc "reload" -h $HOST -p $PORT -U postgres pgbouncer
- psql -tc "resume" -h $HOST -p $PORT -U postgres pgbouncer
-
- i=$((i+1))
-done
-
-
-# Clean up generated file
-rm $PGBOUNCER_DATABASE_INI_NEW
-
-echo "Reconfiguration of pgbouncer complete"
diff --git a/sql/repmgr_extension.sql b/sql/repmgr_extension.sql
index dbc8cb57..e7997256 100644
--- a/sql/repmgr_extension.sql
+++ b/sql/repmgr_extension.sql
@@ -17,8 +17,6 @@ SELECT * FROM repmgr.replication_status;
SELECT * FROM repmgr.show_nodes;
-- functions
-SELECT repmgr.am_bdr_failover_handler(-1);
-SELECT repmgr.am_bdr_failover_handler(NULL);
SELECT repmgr.get_new_primary();
SELECT repmgr.notify_follow_primary(-1);
SELECT repmgr.notify_follow_primary(NULL);
@@ -27,4 +25,3 @@ SELECT repmgr.set_local_node_id(-1);
SELECT repmgr.set_local_node_id(NULL);
SELECT repmgr.standby_get_last_updated();
SELECT repmgr.standby_set_last_updated();
-SELECT repmgr.unset_bdr_failover_handler();