mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-24 15:46: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;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
/* %p: former primary id ("repmgr standby switchover") */
|
/* %p: primary id ("standby_switchover": former primary id) */
|
||||||
src_ptr++;
|
src_ptr++;
|
||||||
if (event_info->former_primary_id != UNKNOWN_NODE_ID)
|
if (event_info->node_id != UNKNOWN_NODE_ID)
|
||||||
{
|
{
|
||||||
PQExpBufferData node_id;
|
PQExpBufferData node_id;
|
||||||
initPQExpBuffer(&node_id);
|
initPQExpBuffer(&node_id);
|
||||||
appendPQExpBuffer(&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);
|
strlcpy(dst_ptr, node_id.data, end_ptr - dst_ptr);
|
||||||
dst_ptr += strlen(dst_ptr);
|
dst_ptr += strlen(dst_ptr);
|
||||||
termPQExpBuffer(&node_id);
|
termPQExpBuffer(&node_id);
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ typedef struct s_event_info
|
|||||||
{
|
{
|
||||||
char *node_name;
|
char *node_name;
|
||||||
char *conninfo_str;
|
char *conninfo_str;
|
||||||
int former_primary_id;
|
int node_id;
|
||||||
} t_event_info;
|
} t_event_info;
|
||||||
|
|
||||||
#define T_EVENT_INFO_INITIALIZER { \
|
#define T_EVENT_INFO_INITIALIZER { \
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
<filename>repmgr.conf</filename>.
|
<filename>repmgr.conf</filename>.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
This parameter accepts the following format placeholders:
|
The following format placeholders are provided for all event notifications:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
@@ -84,18 +84,8 @@
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
</variablelist>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The values provided for <literal>%t</literal> and <literal>%d</literal>
|
The values provided for <literal>%t</literal> and <literal>%d</literal>
|
||||||
will probably contain spaces, so should be quoted in the provided command
|
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"'
|
event_notification_command='/path/to/some/script %n %e %s "%t" "%d"'
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Additionally the following format placeholders are available for the event
|
The following parameters are provided for a subset of event notifications:
|
||||||
type <varname>bdr_failover</varname> and optionally <varname>bdr_recovery</varname>:
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<variablelist>
|
<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>
|
<varlistentry>
|
||||||
<term><option>%c</option></term>
|
<term><option>%c</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<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>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>%a</option></term>
|
<term><option>%a</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<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>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
<para>
|
<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>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
By default, all notification types will be passed to the designated script;
|
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">
|
<itemizedlist spacing="compact" mark="bullet">
|
||||||
|
|
||||||
@@ -219,6 +235,7 @@
|
|||||||
|
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Note that under some circumstances (e.g. when no replication cluster primary
|
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
|
could be located), it will not be possible to write an entry into the
|
||||||
|
|||||||
@@ -87,9 +87,14 @@
|
|||||||
<para>
|
<para>
|
||||||
A <literal>standby_follow</literal> <link linkend="event-notifications">event notification</link> will be generated.
|
A <literal>standby_follow</literal> <link linkend="event-notifications">event notification</link> will be generated.
|
||||||
</para>
|
</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>
|
<refsect1>
|
||||||
<title>See also</title>
|
<title>See also</title>
|
||||||
<para>
|
<para>
|
||||||
<xref linkend="repmgr-node-rejoin">
|
<xref linkend="repmgr-node-rejoin">
|
||||||
|
|||||||
@@ -105,6 +105,12 @@
|
|||||||
standby.
|
standby.
|
||||||
</para>
|
</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>
|
</refsect1>
|
||||||
|
|
||||||
</refentry>
|
</refentry>
|
||||||
|
|||||||
@@ -779,6 +779,11 @@ do_standby_register(void)
|
|||||||
|
|
||||||
PQExpBufferData details;
|
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)"),
|
log_info(_("connecting to local node \"%s\" (ID: %i)"),
|
||||||
config_file_options.node_name,
|
config_file_options.node_name,
|
||||||
config_file_options.node_id);
|
config_file_options.node_id);
|
||||||
@@ -863,7 +868,7 @@ do_standby_register(void)
|
|||||||
/* Normal case - we can connect to the local node */
|
/* Normal case - we can connect to the local node */
|
||||||
if (PQstatus(conn) == CONNECTION_OK)
|
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);
|
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
|
* Verify that standby and primary are supported and compatible server
|
||||||
* versions
|
* versions
|
||||||
@@ -1141,12 +1156,14 @@ do_standby_register(void)
|
|||||||
&details,
|
&details,
|
||||||
" (-F/--force option was used)");
|
" (-F/--force option was used)");
|
||||||
|
|
||||||
create_event_notification(primary_conn,
|
create_event_notification_extended(
|
||||||
&config_file_options,
|
primary_conn,
|
||||||
config_file_options.node_id,
|
&config_file_options,
|
||||||
"standby_register",
|
config_file_options.node_id,
|
||||||
false,
|
"standby_register",
|
||||||
details.data);
|
false,
|
||||||
|
details.data,
|
||||||
|
&event_info);
|
||||||
|
|
||||||
termPQExpBuffer(&details);
|
termPQExpBuffer(&details);
|
||||||
PQfinish(primary_conn);
|
PQfinish(primary_conn);
|
||||||
@@ -1166,12 +1183,14 @@ do_standby_register(void)
|
|||||||
|
|
||||||
|
|
||||||
/* Log the event */
|
/* Log the event */
|
||||||
create_event_notification(primary_conn,
|
create_event_notification_extended(
|
||||||
&config_file_options,
|
primary_conn,
|
||||||
config_file_options.node_id,
|
&config_file_options,
|
||||||
"standby_register",
|
config_file_options.node_id,
|
||||||
true,
|
"standby_register",
|
||||||
details.data);
|
true,
|
||||||
|
details.data,
|
||||||
|
&event_info);
|
||||||
|
|
||||||
termPQExpBuffer(&details);
|
termPQExpBuffer(&details);
|
||||||
|
|
||||||
@@ -1266,12 +1285,14 @@ do_standby_register(void)
|
|||||||
timer);
|
timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
create_event_notification(primary_conn,
|
create_event_notification_extended(
|
||||||
&config_file_options,
|
primary_conn,
|
||||||
config_file_options.node_id,
|
&config_file_options,
|
||||||
"standby_register_sync",
|
config_file_options.node_id,
|
||||||
sync_ok,
|
"standby_register_sync",
|
||||||
details.data);
|
sync_ok,
|
||||||
|
details.data,
|
||||||
|
&event_info);
|
||||||
|
|
||||||
if (sync_ok == false)
|
if (sync_ok == false)
|
||||||
{
|
{
|
||||||
@@ -1605,9 +1626,11 @@ do_standby_follow(void)
|
|||||||
PGconn *local_conn = NULL;
|
PGconn *local_conn = NULL;
|
||||||
|
|
||||||
PGconn *primary_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;
|
t_node_info primary_node_record = T_NODE_INFO_INITIALIZER;
|
||||||
RecordStatus record_status = RECORD_NOT_FOUND;
|
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 timer = 0;
|
||||||
int server_version_num = UNKNOWN_SERVER_VERSION_NUM;
|
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++)
|
for (timer = 0; timer < config_file_options.primary_follow_timeout; timer++)
|
||||||
{
|
{
|
||||||
primary_conn = get_primary_connection_quiet(local_conn,
|
primary_conn = get_primary_connection_quiet(local_conn,
|
||||||
&primary_id,
|
&primary_node_id,
|
||||||
NULL);
|
NULL);
|
||||||
if (PQstatus(primary_conn) == CONNECTION_OK || runtime_options.wait == false)
|
if (PQstatus(primary_conn) == CONNECTION_OK || runtime_options.wait == false)
|
||||||
{
|
{
|
||||||
@@ -1673,14 +1696,14 @@ do_standby_follow(void)
|
|||||||
|
|
||||||
if (runtime_options.dry_run == true)
|
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
|
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)
|
if (record_status != RECORD_FOUND)
|
||||||
{
|
{
|
||||||
@@ -1690,17 +1713,25 @@ do_standby_follow(void)
|
|||||||
exit(ERR_BAD_CONFIG);
|
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)
|
if (runtime_options.dry_run == true)
|
||||||
{
|
{
|
||||||
log_info(_("primary node is \"%s\" (ID: %i)"),
|
log_info(_("primary node is \"%s\" (ID: %i)"),
|
||||||
primary_node_record.node_name,
|
primary_node_record.node_name,
|
||||||
primary_id);
|
primary_node_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_verbose(LOG_INFO, ("primary node is \"%s\" (ID: %i)"),
|
log_verbose(LOG_INFO, ("primary node is \"%s\" (ID: %i)"),
|
||||||
primary_node_record.node_name,
|
primary_node_record.node_name,
|
||||||
primary_id);
|
primary_node_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if replication slots in use, check at least one free slot is available */
|
/* if replication slots in use, check at least one free slot is available */
|
||||||
@@ -1791,7 +1822,6 @@ do_standby_follow(void)
|
|||||||
exit(SUCCESS);
|
exit(SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
initPQExpBuffer(&follow_output);
|
initPQExpBuffer(&follow_output);
|
||||||
|
|
||||||
success = do_standby_follow_internal(primary_conn,
|
success = do_standby_follow_internal(primary_conn,
|
||||||
@@ -1799,12 +1829,14 @@ do_standby_follow(void)
|
|||||||
&follow_output,
|
&follow_output,
|
||||||
&follow_error_code);
|
&follow_error_code);
|
||||||
|
|
||||||
create_event_notification(primary_conn,
|
create_event_notification_extended(
|
||||||
&config_file_options,
|
primary_conn,
|
||||||
config_file_options.node_id,
|
&config_file_options,
|
||||||
"standby_follow",
|
config_file_options.node_id,
|
||||||
success,
|
"standby_follow",
|
||||||
follow_output.data);
|
success,
|
||||||
|
follow_output.data,
|
||||||
|
&event_info);
|
||||||
|
|
||||||
PQfinish(primary_conn);
|
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);
|
log_verbose(LOG_DEBUG, "remote node name is \"%s\"", remote_node_record.node_name);
|
||||||
|
|
||||||
/* this will fill the %p event notification parameter */
|
/* 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
|
* If --force-rewind specified, check pg_rewind can be used, and
|
||||||
|
|||||||
Reference in New Issue
Block a user