mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-22 22:56:29 +00:00
"standby register/follow": provide primary node details for event notifications
For events generated by these commands, it may be useful to know details of the primary node. This makes following additional parameters available to event notification scripts: - %p: node ID of the primary - %a: node name of the primary - %c: conninfo string for the primary Implements GitHub #375
This commit is contained in:
@@ -3265,14 +3265,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);
|
||||
|
||||
@@ -175,7 +175,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 { \
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<filename>repmgr.conf</filename>.
|
||||
</para>
|
||||
<para>
|
||||
This parameter accepts the following format placeholders:
|
||||
The following format placeholders are provided for all event notifications:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
@@ -84,18 +84,8 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry>
|
||||
<term><option>%p</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
node ID of the demoted primary (<xref linkend="repmgr-standby-switchover"> only)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
The values provided for <literal>%t</literal> and <literal>%d</literal>
|
||||
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"'
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Additionally the following format placeholders are available for the event
|
||||
type <varname>bdr_failover</varname> and optionally <varname>bdr_recovery</varname>:
|
||||
The following parameters are provided for a subset of event notifications:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>%p</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
node ID of the current primary (<xref linkend="repmgr-standby-register"> and <xref linkend="repmgr-standby-follow">)
|
||||
</para>
|
||||
<para>
|
||||
node ID of the demoted primary (<xref linkend="repmgr-standby-switchover"> only)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>%c</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
conninfo string of the next available node
|
||||
<literal>conninfo</literal> string of the primary node
|
||||
(<xref linkend="repmgr-standby-register"> and <xref linkend="repmgr-standby-follow">)
|
||||
</para>
|
||||
<para>
|
||||
<literal>conninfo</literal> string of the next available node
|
||||
(<varname>bdr_failover</varname> and <varname>bdr_recovery</varname>)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>%a</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
name of the next available node
|
||||
name of the current primary node (<xref linkend="repmgr-standby-register"> and <xref linkend="repmgr-standby-follow">)
|
||||
</para>
|
||||
<para>
|
||||
name of the next available node (<varname>bdr_failover</varname> and <varname>bdr_recovery</varname>)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
These should always be quoted.
|
||||
The values provided for <literal>%c</literal> and <literal>%a</literal>
|
||||
will probably contain spaces, so should always be quoted.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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
|
||||
<varname>event_notifications</varname> parameter:
|
||||
|
||||
<itemizedlist spacing="compact" mark="bullet">
|
||||
|
||||
@@ -219,6 +235,7 @@
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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
|
||||
|
||||
@@ -87,9 +87,14 @@
|
||||
<para>
|
||||
A <literal>standby_follow</literal> <link linkend="event-notifications">event notification</link> will be generated.
|
||||
</para>
|
||||
<para>
|
||||
If provided, &repmgr; will subsitute the placeholders <literal>%p</literal> with the node ID of the primary
|
||||
being followed, <literal>%c</literal> with its <literal>conninfo</literal> string, and
|
||||
<literal>%a</literal> with its node name.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<refsect1>
|
||||
<title>See also</title>
|
||||
<para>
|
||||
<xref linkend="repmgr-node-rejoin">
|
||||
|
||||
@@ -105,6 +105,12 @@
|
||||
standby.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If provided, &repmgr; will subsitute the placeholders <literal>%p</literal> with the node ID of the
|
||||
primary node, <literal>%c</literal> with its <literal>conninfo</literal> string, and
|
||||
<literal>%a</literal> with its node name.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
|
||||
@@ -779,6 +779,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);
|
||||
@@ -863,7 +868,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -887,6 +892,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
|
||||
@@ -1141,12 +1156,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);
|
||||
@@ -1166,12 +1183,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);
|
||||
|
||||
@@ -1266,12 +1285,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)
|
||||
{
|
||||
@@ -1605,9 +1626,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;
|
||||
@@ -1646,7 +1669,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)
|
||||
{
|
||||
@@ -1673,14 +1696,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)
|
||||
{
|
||||
@@ -1690,17 +1713,25 @@ do_standby_follow(void)
|
||||
exit(ERR_BAD_CONFIG);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
@@ -1791,7 +1822,6 @@ do_standby_follow(void)
|
||||
exit(SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
initPQExpBuffer(&follow_output);
|
||||
|
||||
success = do_standby_follow_internal(primary_conn,
|
||||
@@ -1799,12 +1829,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);
|
||||
|
||||
@@ -2244,7 +2276,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;
|
||||
|
||||
/*
|
||||
* If --force-rewind specified, check pg_rewind can be used, and
|
||||
|
||||
Reference in New Issue
Block a user