diff --git a/dbutils.c b/dbutils.c index b6c9b8eb..d576bed6 100644 --- a/dbutils.c +++ b/dbutils.c @@ -3303,14 +3303,14 @@ _create_event(PGconn *conn, t_configuration_options *options, int node_id, char } break; case 'p': - /* %p: former primary id ("repmgr standby switchover") */ + /* %p: primary id ("standby_switchover": former primary id) */ src_ptr++; - if (event_info->former_primary_id != UNKNOWN_NODE_ID) + if (event_info->node_id != UNKNOWN_NODE_ID) { PQExpBufferData node_id; initPQExpBuffer(&node_id); appendPQExpBuffer(&node_id, - "%i", event_info->former_primary_id); + "%i", event_info->node_id); strlcpy(dst_ptr, node_id.data, end_ptr - dst_ptr); dst_ptr += strlen(dst_ptr); termPQExpBuffer(&node_id); diff --git a/dbutils.h b/dbutils.h index 3e4fa295..93fbf019 100644 --- a/dbutils.h +++ b/dbutils.h @@ -183,7 +183,7 @@ typedef struct s_event_info { char *node_name; char *conninfo_str; - int former_primary_id; + int node_id; } t_event_info; #define T_EVENT_INFO_INITIALIZER { \ diff --git a/doc/event-notifications.sgml b/doc/event-notifications.sgml index 4273944f..9b2c2010 100644 --- a/doc/event-notifications.sgml +++ b/doc/event-notifications.sgml @@ -37,7 +37,7 @@ repmgr.conf. - This parameter accepts the following format placeholders: + The following format placeholders are provided for all event notifications: @@ -84,18 +84,8 @@ - - - - - - - node ID of the demoted primary ( only) - - - - + The values provided for %t and %d will probably contain spaces, so should be quoted in the provided command @@ -104,34 +94,60 @@ event_notification_command='/path/to/some/script %n %e %s "%t" "%d"' + - Additionally the following format placeholders are available for the event - type bdr_failover and optionally bdr_recovery: + The following parameters are provided for a subset of event notifications: + + + + + + node ID of the current primary ( and ) + + + node ID of the demoted primary ( only) + + + - conninfo string of the next available node + conninfo string of the primary node + ( and ) + + + conninfo string of the next available node + (bdr_failover and bdr_recovery) + - name of the next available node + name of the current primary node ( and ) + + + name of the next available node (bdr_failover and bdr_recovery) + + - These should always be quoted. + The values provided for %c and %a + will probably contain spaces, so should always be quoted. + By default, all notification types will be passed to the designated script; - the notification types can be filtered to explicitly named ones: + the notification types can be filtered to explicitly named ones using the + event_notifications parameter: @@ -222,6 +238,7 @@ + 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/repmgr-standby-follow.sgml b/doc/repmgr-standby-follow.sgml index 0079dc37..d464361b 100644 --- a/doc/repmgr-standby-follow.sgml +++ b/doc/repmgr-standby-follow.sgml @@ -87,9 +87,14 @@ A standby_follow event notification will be generated. + + If provided, &repmgr; will subsitute the placeholders %p with the node ID of the primary + being followed, %c with its conninfo string, and + %a with its node name. + - + See also diff --git a/doc/repmgr-standby-register.sgml b/doc/repmgr-standby-register.sgml index b5e69efd..9e5f7b76 100644 --- a/doc/repmgr-standby-register.sgml +++ b/doc/repmgr-standby-register.sgml @@ -172,6 +172,12 @@ standby. + + If provided, &repmgr; will subsitute the placeholders %p with the node ID of the + primary node, %c with its conninfo string, and + %a with its node name. + + diff --git a/repmgr-action-standby.c b/repmgr-action-standby.c index 4a14563f..0d68a297 100644 --- a/repmgr-action-standby.c +++ b/repmgr-action-standby.c @@ -1192,6 +1192,11 @@ do_standby_register(void) PQExpBufferData details; + /* so we can pass info about the primary to event notification scripts */ + t_event_info event_info = T_EVENT_INFO_INITIALIZER; + t_node_info primary_node_record = T_NODE_INFO_INITIALIZER; + int primary_node_id = UNKNOWN_NODE_ID; + log_info(_("connecting to local node \"%s\" (ID: %i)"), config_file_options.node_name, config_file_options.node_id); @@ -1276,7 +1281,7 @@ do_standby_register(void) /* Normal case - we can connect to the local node */ if (PQstatus(conn) == CONNECTION_OK) { - primary_conn = get_primary_connection(conn, NULL, NULL); + primary_conn = get_primary_connection(conn, &primary_node_id, NULL); } /* @@ -1300,6 +1305,16 @@ do_standby_register(void) exit(ERR_BAD_CONFIG); } + /* + * Populate "event_info" with info about the primary for event notifications + */ + record_status = get_node_record(primary_conn, + primary_node_id, + &primary_node_record); + event_info.node_id = primary_node_id; + event_info.node_name = primary_node_record.node_name; + event_info.conninfo_str = primary_node_record.conninfo; + /* * Verify that standby and primary are supported and compatible server * versions @@ -1554,12 +1569,14 @@ do_standby_register(void) &details, " (-F/--force option was used)"); - create_event_notification(primary_conn, - &config_file_options, - config_file_options.node_id, - "standby_register", - false, - details.data); + create_event_notification_extended( + primary_conn, + &config_file_options, + config_file_options.node_id, + "standby_register", + false, + details.data, + &event_info); termPQExpBuffer(&details); PQfinish(primary_conn); @@ -1579,12 +1596,14 @@ do_standby_register(void) /* Log the event */ - create_event_notification(primary_conn, - &config_file_options, - config_file_options.node_id, - "standby_register", - true, - details.data); + create_event_notification_extended( + primary_conn, + &config_file_options, + config_file_options.node_id, + "standby_register", + true, + details.data, + &event_info); termPQExpBuffer(&details); @@ -1679,12 +1698,14 @@ do_standby_register(void) timer); } - create_event_notification(primary_conn, - &config_file_options, - config_file_options.node_id, - "standby_register_sync", - sync_ok, - details.data); + create_event_notification_extended( + primary_conn, + &config_file_options, + config_file_options.node_id, + "standby_register_sync", + sync_ok, + details.data, + &event_info); if (sync_ok == false) { @@ -2016,9 +2037,11 @@ do_standby_follow(void) PGconn *local_conn = NULL; PGconn *primary_conn = NULL; - int primary_id = UNKNOWN_NODE_ID; + int primary_node_id = UNKNOWN_NODE_ID; t_node_info primary_node_record = T_NODE_INFO_INITIALIZER; RecordStatus record_status = RECORD_NOT_FOUND; + /* so we can pass info about the primary to event notification scripts */ + t_event_info event_info = T_EVENT_INFO_INITIALIZER; int timer = 0; int server_version_num = UNKNOWN_SERVER_VERSION_NUM; @@ -2057,7 +2080,7 @@ do_standby_follow(void) for (timer = 0; timer < config_file_options.primary_follow_timeout; timer++) { primary_conn = get_primary_connection_quiet(local_conn, - &primary_id, + &primary_node_id, NULL); if (PQstatus(primary_conn) == CONNECTION_OK || runtime_options.wait == false) { @@ -2084,14 +2107,14 @@ do_standby_follow(void) if (runtime_options.dry_run == true) { - log_info(_("connected to node %i, checking for current primary"), primary_id); + log_info(_("connected to node %i, checking for current primary"), primary_node_id); } else { - log_verbose(LOG_INFO, _("connected to node %i, checking for current primary"), primary_id); + log_verbose(LOG_INFO, _("connected to node %i, checking for current primary"), primary_node_id); } - record_status = get_node_record(primary_conn, primary_id, &primary_node_record); + record_status = get_node_record(primary_conn, primary_node_id, &primary_node_record); if (record_status != RECORD_FOUND) { @@ -2101,17 +2124,25 @@ do_standby_follow(void) exit(ERR_FOLLOW_FAIL); } + /* + * Populate "event_info" with info about the primary for event notifications + */ + event_info.node_id = primary_node_id; + event_info.node_name = primary_node_record.node_name; + event_info.conninfo_str = primary_node_record.conninfo; + + if (runtime_options.dry_run == true) { log_info(_("primary node is \"%s\" (ID: %i)"), primary_node_record.node_name, - primary_id); + primary_node_id); } else { log_verbose(LOG_INFO, ("primary node is \"%s\" (ID: %i)"), primary_node_record.node_name, - primary_id); + primary_node_id); } /* if replication slots in use, check at least one free slot is available */ @@ -2202,7 +2233,6 @@ do_standby_follow(void) exit(SUCCESS); } - initPQExpBuffer(&follow_output); success = do_standby_follow_internal(primary_conn, @@ -2210,12 +2240,14 @@ do_standby_follow(void) &follow_output, &follow_error_code); - create_event_notification(primary_conn, - &config_file_options, - config_file_options.node_id, - "standby_follow", - success, - follow_output.data); + create_event_notification_extended( + primary_conn, + &config_file_options, + config_file_options.node_id, + "standby_follow", + success, + follow_output.data, + &event_info); PQfinish(primary_conn); @@ -2659,7 +2691,7 @@ do_standby_switchover(void) log_verbose(LOG_DEBUG, "remote node name is \"%s\"", remote_node_record.node_name); /* this will fill the %p event notification parameter */ - event_info.former_primary_id = remote_node_record.node_id; + event_info.node_id = remote_node_record.node_id; /* keep a running total of how many nodes will require a replication slot */ if (remote_node_record.slot_name[0] != '\0')