diff --git a/HISTORY b/HISTORY index 876573df..f74f1b7e 100644 --- a/HISTORY +++ b/HISTORY @@ -14,7 +14,9 @@ it will actually be possible to stream from the target node (Ian) repmgr: "standby switchover": improve handling of connection URIs when executing "node rejoin" on the demotion candidate; GitHub #525 (Ian) - repmgr: fix long node ID display in "cluster show"; (Ian) + repmgr: fix long node ID display in "cluster show" (Ian) + repmgr: check for primary server before executing "witness register"; + GitHub #538 (Ian) repmgrd: check binary and extension major versions match; GitHub #515 (Ian) repmgrd: on a cascaded standby, don't fail over if "failover=manual"; GitHub #531 (Ian) diff --git a/doc/appendix-release-notes.sgml b/doc/appendix-release-notes.sgml index ba5547e5..b185c99e 100644 --- a/doc/appendix-release-notes.sgml +++ b/doc/appendix-release-notes.sgml @@ -137,6 +137,13 @@ REPMGRD_OPTS="--daemonize=false" + + + &repmgr;: when executing repmgr witness register, + chech the node to connected is actually the primary (i.e. not the witness server). (GitHub #528). + + + &repmgr;: when executing repmgr standby switchover, @@ -315,7 +322,6 @@ REPMGRD_OPTS="--daemonize=false" - repmgrd: fix parsing of option. diff --git a/doc/repmgr-witness-register.sgml b/doc/repmgr-witness-register.sgml index 3f5e5b86..de6d1853 100644 --- a/doc/repmgr-witness-register.sgml +++ b/doc/repmgr-witness-register.sgml @@ -34,6 +34,14 @@ witness node's repmgr.conf, unless these are explicitly provided as command line options. + + + + The primary server must be registered with repmgr primary register before the witness + server can be registered. + + + Execute with the option to check what would happen without actually registering the witness server. diff --git a/repmgr-action-witness.c b/repmgr-action-witness.c index fdfb92b9..c313f01f 100644 --- a/repmgr-action-witness.c +++ b/repmgr-action-witness.c @@ -36,10 +36,12 @@ do_witness_register(void) { PGconn *witness_conn = NULL; PGconn *primary_conn = NULL; + int primary_node_id = UNKNOWN_NODE_ID; RecoveryType recovery_type = RECTYPE_UNKNOWN; ExtensionStatus extension_status = REPMGR_UNKNOWN; NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER; t_node_info node_record = T_NODE_INFO_INITIALIZER; + t_node_info primary_node_record = T_NODE_INFO_INITIALIZER; RecordStatus record_status = RECORD_NOT_FOUND; bool record_created = false; @@ -125,6 +127,59 @@ do_witness_register(void) exit(ERR_BAD_CONFIG); } + + /* check we can determine the primary node */ + primary_node_id = get_primary_node_id(primary_conn); + + if (primary_node_id == UNKNOWN_NODE_ID) + { + log_error(_("unable to determine the cluster's primary node")); + log_hint(_("ensure the primary node connection details are correct and that it is registered")); + PQfinish(witness_conn); + PQfinish(primary_conn); + + exit(ERR_BAD_CONFIG); + } + + record_status = get_node_record(primary_conn, primary_node_id, &primary_node_record); + PQfinish(primary_conn); + + if (record_status != RECORD_FOUND) + { + log_error(_("unable to retrieve record for primary node %i"), + primary_node_id); + + PQfinish(witness_conn); + + + exit(ERR_BAD_CONFIG); + } + + /* + * Reconnect to the primary node's conninfo - this will + * protect against the situation where the witness connection + * details were provided, and we're actually connected to the + * witness server. + */ + + primary_conn = establish_db_connection_quiet(primary_node_record.conninfo); + + if (PQstatus(primary_conn) != CONNECTION_OK) + { + log_error(_("unable to reconnect to the primary node (node %i)"), primary_node_id); + log_detail(_("primary node's conninfo is \"%s\""), primary_node_record.conninfo); + + PQfinish(witness_conn); + + exit(ERR_BAD_CONFIG); + } + + /* + * TODO: sanity check witness node is not part of main cluster; we could + * add a random application_name to the respective connections, + * and do a simple check of pg_stat_activity + */ + /* check that primary node is not a BDR node */ if (is_bdr_db_quiet(primary_conn) == true) { @@ -137,11 +192,6 @@ do_witness_register(void) exit(ERR_BAD_CONFIG); } - /* - * TODO: sanity check witness node is not part of main cluster; we could - * add a random application_name to the respective connections, - * and do a simple check of pg_stat_activity - */ /* create repmgr extension, if does not exist */ if (runtime_options.dry_run == false && !create_repmgr_extension(witness_conn)) @@ -275,7 +325,7 @@ do_witness_register(void) /* these values are mandatory, setting them to anything else has no point */ node_record.type = WITNESS; node_record.priority = 0; - node_record.upstream_node_id = get_primary_node_id(primary_conn); + node_record.upstream_node_id = primary_node_id; if (record_status == RECORD_FOUND) {