Compare commits

..

3 Commits

Author SHA1 Message Date
Ian Barwick
fe5904e04e standby clone: improve Barman source server check
Use "remote_command()" to execute the remote psql command, and
provide the -X option to psql to ensure it doesn't read ~/.psqlrc.
2020-10-20 17:21:17 +09:00
Ian Barwick
2cb1f4f728 doc: update release notes 2020-10-20 14:05:25 +09:00
Ian Barwick
5b90842c55 Bump version to 5.2.0
Also update the minimum version check to PostgreSQL 9.4.
2020-10-20 13:34:16 +09:00
87 changed files with 501 additions and 2247 deletions

View File

@@ -2,7 +2,7 @@ License and Contributions
=========================
`repmgr` is licensed under the GPL v3. All of its code and documentation is
Copyright 2010-2021, EnterpriseDB Corporation. See the files COPYRIGHT and LICENSE for
Copyright 2010-2020, 2ndQuadrant Limited. See the files COPYRIGHT and LICENSE for
details.
The development of repmgr has primarily been sponsored by 2ndQuadrant customers.
@@ -12,10 +12,10 @@ which has received funding from the European Union's Seventh Framework Programme
(FP7/2007-2013) under grant agreement 258862.
Contributions to `repmgr` are welcome, and will be listed in the file `CREDITS`.
EnterpriseDB Corporation requires that any contributions provide a copyright
2ndQuadrant Limited requires that any contributions provide a copyright
assignment and a disclaimer of any work-for-hire ownership claims from the
employer of the developer. This lets us make sure that all of the repmgr
distribution remains free code. Please contact info@enterprise.com for a
distribution remains free code. Please contact info@2ndQuadrant.com for a
copy of the relevant Copyright Assignment Form.
Code style

View File

@@ -1,4 +1,4 @@
Copyright (c) 2010-2021, EnterpriseDB Corporation
Copyright (c) 2010-2020, 2ndQuadrant Limited
All rights reserved.
This program is free software: you can redistribute it and/or modify

2
FAQ.md
View File

@@ -5,6 +5,6 @@ The repmgr 4 FAQ is located here: [repmgr FAQ (Frequently Asked Questions)](http
The repmgr 3.x FAQ can be found here:
https://github.com/EnterpriseDB/repmgr/blob/REL3_3_STABLE/FAQ.md
https://github.com/2ndQuadrant/repmgr/blob/REL3_3_STABLE/FAQ.md
Note that repmgr 3.x is no longer supported.

28
HISTORY
View File

@@ -1,28 +1,4 @@
5.3.1 2022-??-??
repmgrd: fixes for potential connection leaks (hslightdb)
5.3.0 2021-10-12
standby switchover: improve handling of node rejoin failure (Ian)
repmgrd: prefix all shared library functions with "repmgr_" to
minimize the risk of clashes with other shared libraries (Ian)
repmgrd: at startup, if node record is marked as "inactive", attempt
to set it to "active" (Ian)
standby clone: set "slot_name" in node record if required (Ian)
node rejoin: emit rejoin target note information as NOTICE (Ian)
repmgrd: ensure short option "-s" is accepted (Ian)
5.2.1 2020-12-07
config: fix parsing of "replication_type"; GitHub #672 (Ian)
standby clone: handle missing "postgresql.auto.conf" (Ian)
standby clone: add option --recovery-min-apply-delay (Ian)
standby clone: fix data directory permissions handling for
PostgreSQL 11 and later (Ian)
repmgrd: prevent termination when local node not available and
standby_disconnect_on_failover; GitHub #675 (Ian)
repmgrd: ensure reconnect_interval" is correctly handled;
GitHub #673 (Ian)
5.2.0 2020-10-22
5.2.0 2020-??-??
general: add support for PostgreSQL 13 (Ian)
general: remove support for PostgreSQL 9.3 (Ian)
config: add support for file inclusion directives (Ian)
@@ -56,7 +32,7 @@
repmgr: ensure postgresql.auto.conf is created with correct permissions (Ian)
repmgr: minimize requirement to check upstream data directory location
during "standby clone" (Ian)
repmgr: warn about missing pg_rewind prerequisites when executing
repmgr: warn about missing pg_rewind prerequisites when excuting
"standby clone" (Ian)
repmgr: add --upstream option to "node check"
repmgr: report error code on follow/rejoin failure due to non-available

View File

@@ -12,8 +12,6 @@ EXTENSION = repmgr
DATA = \
repmgr--unpackaged--4.0.sql \
repmgr--unpackaged--5.1.sql \
repmgr--unpackaged--5.2.sql \
repmgr--unpackaged--5.3.sql \
repmgr--4.0.sql \
repmgr--4.0--4.1.sql \
repmgr--4.1.sql \
@@ -28,9 +26,7 @@ DATA = \
repmgr--5.0--5.1.sql \
repmgr--5.1.sql \
repmgr--5.1--5.2.sql \
repmgr--5.2.sql \
repmgr--5.2--5.3.sql \
repmgr--5.3.sql
repmgr--5.2.sql
REGRESS = repmgr_extension
@@ -79,10 +75,10 @@ configfile-scan.c: configfile-scan.l
$(REPMGR_CLIENT_OBJS): repmgr-client.h repmgr_version.h
repmgr: $(REPMGR_CLIENT_OBJS)
$(CC) $(CFLAGS) $(REPMGR_CLIENT_OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) -o $@$(X)
$(CC) $(CFLAGS) $(REPMGR_CLIENT_OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
repmgrd: $(REPMGRD_OBJS)
$(CC) $(CFLAGS) $(REPMGRD_OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) -o $@$(X)
$(CC) $(CFLAGS) $(REPMGRD_OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
$(REPMGR_CLIENT_OBJS): $(HEADERS)
$(REPMGRD_OBJS): $(HEADERS)

View File

@@ -7,10 +7,10 @@ replication capabilities with utilities to set up standby servers, monitor
replication, and perform administrative tasks such as failover or switchover
operations.
The most recent `repmgr` version (5.2.1) supports all PostgreSQL versions from
9.5 to 13. PostgreSQL 9.4 is also supported, with some restrictions.
PostgreSQL 12, 11, 10, 9.6 and 9.5 are fully supported.
PostgreSQL 9.4 and 9.3 are supported, with some restrictions.
`repmgr` is distributed under the GNU GPL 3 and maintained by EnterpriseDB.
`repmgr` is distributed under the GNU GPL 3 and maintained by 2ndQuadrant.
Documentation
-------------
@@ -21,11 +21,10 @@ The full `repmgr` documentation is available here:
The old `README` file for `repmgr` 3.x is available here:
> https://github.com/EnterpriseDB/repmgr/blob/REL3_3_STABLE/README.md
> https://github.com/2ndQuadrant/repmgr/blob/REL3_3_STABLE/README.md
Note that the `repmgr` 3.x series is no longer supported and contains known bugs;
please upgrade to the [current repmgr version](https://repmgr.org/docs/current/appendix-release-notes.html)
as soon as possible.
please upgrade to the current `repmgr` version as soon as possible.
Versions
--------
@@ -55,11 +54,11 @@ Directories
Support and Assistance
----------------------
EnterpriseDB provides 24x7 production support for `repmgr`, including
2ndQuadrant provides 24x7 production support for `repmgr`, including
configuration assistance, installation verification and training for
running a robust replication cluster. For further details see:
* [EDB Support Services](https://www.enterprisedb.com/support/postgresql-support-overview-get-the-most-out-of-postgresql)
* https://2ndquadrant.com/en/support/
There is a mailing list/forum to discuss contributions or issues:
@@ -69,12 +68,23 @@ The IRC channel #repmgr is registered with freenode.
Please report bugs and other issues to:
* https://github.com/EnterpriseDB/repmgr
* https://github.com/2ndQuadrant/repmgr
See
Further information is available at https://repmgr.org/
We'd love to hear from you about how you use repmgr. Case studies and
news are always welcome.
news are always welcome. Send us an email at info@2ndQuadrant.com, or
send a postcard to
repmgr
c/o 2ndQuadrant
7200 The Quorum
Oxford Business Park North
Oxford
OX4 2JZ
United Kingdom
Thanks from the repmgr core team.
@@ -90,4 +100,7 @@ Further reading
* [repmgr documentation](https://repmgr.org/docs/current/index.html)
* [How to Automate PostgreSQL 12 Replication and Failover with repmgr - Part 1](https://www.2ndquadrant.com/en/blog/how-to-automate-postgresql-12-replication-and-failover-with-repmgr-part-1/)
* [How to Automate PostgreSQL 12 Replication and Failover with repmgr - Part 2](https://www.2ndquadrant.com/en/blog/how-to-automate-postgresql-12-replication-and-failover-with-repmgr-part-2/)
* [How to implement repmgr for PostgreSQL automatic failover](https://www.enterprisedb.com/postgres-tutorials/how-implement-repmgr-postgresql-automatic-failover)
* https://blog.2ndquadrant.com/repmgr-3-2-is-here-barman-support-brand-new-high-availability-features/
* https://blog.2ndquadrant.com/improvements-in-repmgr-3-1-4/
* https://blog.2ndquadrant.com/managing-useful-clusters-repmgr/
* https://blog.2ndquadrant.com/easier_postgresql_90_clusters/

View File

@@ -1,7 +1,7 @@
TODO
====
This file contains a list of improvements which are desirable and/or have
This file contains a list of improvements which are desireable and/or have
been requested, and which we aim to address/implement when time and resources
permit.
@@ -17,4 +17,4 @@ repmgrd nodes to prevent unintended failover; this is obviously inconvenient.
We'll need to implement some way of notifying each repmgrd to suspend automatic
failover until further notice.
Requested in GitHub #410 ( https://github.com/EnterpriseDB/repmgr/issues/410 )
Requested in GitHub #410 ( https://github.com/2ndQuadrant/repmgr/issues/410 )

View File

@@ -6,7 +6,7 @@
* supported PostgreSQL versions. They're unlikely to change but
* it would be worth keeping an eye on them for any fixes/improvements.
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* Copyright (c) 2ndQuadrant, 2010-2020
*
* Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California

View File

@@ -1,6 +1,6 @@
/*
* compat.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* Copyright (c) 2ndQuadrant, 2010-2020
*
* Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California

View File

@@ -1,7 +1,7 @@
/*
* configdata.c - contains structs with parsed configuration data
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -120,10 +120,10 @@ struct ConfigFileSetting config_file_settings[] =
/* replication_type */
{
"replication_type",
CONFIG_REPLICATION_TYPE,
{ .replicationtypeptr = &config_file_options.replication_type },
{ .replicationtypedefault = DEFAULT_REPLICATION_TYPE },
{},
CONFIG_INT,
{ .intptr = &config_file_options.replication_type },
{ .intdefault = REPLICATION_TYPE_PHYSICAL },
{ .intminval = -1 },
{},
{}
},
@@ -581,16 +581,6 @@ struct ConfigFileSetting config_file_settings[] =
{ .strmaxlen = sizeof(config_file_options.repmgrd_pid_file) },
{ .postprocess_func = &repmgr_canonicalize_path }
},
/* repmgrd_exit_on_inactive_node */
{
"repmgrd_exit_on_inactive_node",
CONFIG_BOOL,
{ .boolptr = &config_file_options.repmgrd_exit_on_inactive_node},
{ .booldefault = DEFAULT_REPMGRD_EXIT_ON_INACTIVE_NODE },
{},
{},
{}
},
/* standby_disconnect_on_failover */
{
"standby_disconnect_on_failover",

View File

@@ -107,9 +107,9 @@ ProcessRepmgrConfigFile(const char *config_file, const char *base_dir, ItemList
extern bool
ProcessPostgresConfigFile(const char *config_file, const char *base_dir, bool strict, KeyValueList *contents, ItemList *error_list, ItemList *warning_list)
ProcessPostgresConfigFile(const char *config_file, const char *base_dir, KeyValueList *contents, ItemList *error_list, ItemList *warning_list)
{
return ProcessConfigFile(base_dir, config_file, NULL, strict, 0, contents, error_list, warning_list);
return ProcessConfigFile(base_dir, config_file, NULL, true, 0, contents, error_list, warning_list);
}
static bool

View File

@@ -1,7 +1,7 @@
/*
* configfile.c - parse repmgr.conf and other configuration-related functionality
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -313,9 +313,6 @@ _parse_config(ItemList *error_list, ItemList *warning_list)
case CONFIG_CONNECTION_CHECK_TYPE:
*setting->val.checktypeptr = setting->defval.checktypedefault;
break;
case CONFIG_REPLICATION_TYPE:
*setting->val.replicationtypeptr = setting->defval.replicationtypedefault;
break;
case CONFIG_EVENT_NOTIFICATION_LIST:
case CONFIG_TABLESPACE_MAPPING:
/* no default for these types; lists cleared above */
@@ -569,20 +566,6 @@ parse_configuration_item(ItemList *error_list, ItemList *warning_list, const cha
}
break;
}
case CONFIG_REPLICATION_TYPE:
{
if (strcasecmp(value, "physical") == 0)
{
*(ReplicationType *)setting->val.replicationtypeptr = REPLICATION_TYPE_PHYSICAL;
}
else
{
item_list_append_format(error_list,
_("value for \"%s\" must be \"physical\"\n"),
name);
}
break;
}
case CONFIG_EVENT_NOTIFICATION_LIST:
{
parse_event_notifications_list((EventNotificationList *)setting->val.notificationlistptr,
@@ -1411,9 +1394,6 @@ dump_config(void)
case CONFIG_CONNECTION_CHECK_TYPE:
printf("%s", print_connection_check_type(*setting->val.checktypeptr));
break;
case CONFIG_REPLICATION_TYPE:
printf("%s", print_replication_type(*setting->val.replicationtypeptr));
break;
case CONFIG_EVENT_NOTIFICATION_LIST:
{
char *list = print_event_notification_list(setting->val.notificationlistptr);
@@ -1785,7 +1765,7 @@ modify_auto_conf(const char *data_dir, KeyValueList *items)
FILE *fp;
mode_t um;
struct stat data_dir_st;
struct stat auto_conf_st;
KeyValueList config = {NULL, NULL};
KeyValueListCell *cell = NULL;
@@ -1796,12 +1776,7 @@ modify_auto_conf(const char *data_dir, KeyValueList *items)
appendPQExpBuffer(&auto_conf, "%s/%s",
data_dir, PG_AUTOCONF_FILENAME);
success = ProcessPostgresConfigFile(auto_conf.data,
NULL,
false, /* we don't care if the file does not exist */
&config,
NULL,
NULL);
success = ProcessPostgresConfigFile(auto_conf.data, NULL, &config, NULL, NULL);
if (success == false)
{
@@ -1812,7 +1787,7 @@ modify_auto_conf(const char *data_dir, KeyValueList *items)
}
/*
* Append requested items to any items extracted from the existing file.
* Append requested items to items extracted from the existing file.
*/
for (cell = items->head; cell; cell = cell->next)
{
@@ -1841,46 +1816,27 @@ modify_auto_conf(const char *data_dir, KeyValueList *items)
cell->key, cell->value);
}
/* stat the data directory for the file mode */
if (stat(data_dir, &data_dir_st) != 0)
{
/*
* This is highly unlikely to happen, but if it does (e.g. freak
* race condition with some rogue process which is messing about
* with the data directory), there's not a lot we can do.
*/
log_error(_("error encountered when checking \"%s\""),
data_dir);
log_detail("%s", strerror(errno));
exit(ERR_BAD_CONFIG);
}
stat(auto_conf.data, &auto_conf_st);
/*
* Set umask so the temporary file is created in the same mode as the data
* directory. In PostgreSQL 11 and later this can be 0700 or 0750.
* Set umask so the temporary file is created in the same mode as the original
* postgresql.auto.conf file.
*/
um = umask(~(data_dir_st.st_mode));
um = umask(~(auto_conf_st.st_mode));
fp = fopen(auto_conf_tmp.data, "w");
umask(um);
if (fp == NULL)
{
fprintf(stderr, "unable to open \"%s\" for writing: %s\n",
fprintf(stderr, "unable to open \"%s\": %s\n",
auto_conf_tmp.data,
strerror(errno));
success = false;
}
else
{
if (fwrite(auto_conf_contents.data, strlen(auto_conf_contents.data), 1, fp) != 1)
{
fprintf(stderr, "unable to write to \"%s\": %s\n",
auto_conf_tmp.data,
strerror(errno));
fclose(fp);
success = false;
}
else
{
@@ -1889,7 +1845,7 @@ modify_auto_conf(const char *data_dir, KeyValueList *items)
/*
* Note: durable_rename() is not exposed to frontend code before Pg 10.
* We only really need to be modifying postgresql.auto.conf from Pg 12,
* but provide backwards compatibility for Pg 9.6 and earlier for the
* but provide backwards compatibitilty for Pg 9.6 and earlier for the
* (unlikely) event that a repmgr built against one of those versions
* is being used against Pg 12 and later.
*/
@@ -2211,20 +2167,6 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
}
const char *
print_replication_type(ReplicationType type)
{
switch (type)
{
case REPLICATION_TYPE_PHYSICAL:
return "physical";
}
/* should never reach here */
return "UNKNOWN";
}
const char *
print_connection_check_type(ConnectionCheckType type)
{
@@ -2250,7 +2192,6 @@ print_event_notification_list(EventNotificationList *list)
PQExpBufferData buf;
char *ptr;
EventNotificationListCell *cell;
int ptr_len;
initPQExpBuffer(&buf);
cell = list->head;
@@ -2265,10 +2206,8 @@ print_event_notification_list(EventNotificationList *list)
cell = cell->next;
}
ptr_len = strlen(buf.data);
ptr = palloc0(ptr_len + 1);
strncpy(ptr, buf.data, ptr_len);
ptr = palloc0(strlen(buf.data) + 1);
strncpy(ptr, buf.data, strlen(buf.data));
termPQExpBuffer(&buf);

View File

@@ -1,7 +1,7 @@
/*
* configfile.h
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* Copyright (c) 2ndQuadrant, 2010-2020
*
*
* This program is free software: you can redistribute it and/or modify
@@ -50,11 +50,6 @@ typedef enum
CHECK_CONNECTION
} ConnectionCheckType;
typedef enum
{
REPLICATION_TYPE_PHYSICAL
} ReplicationType;
typedef struct EventNotificationListCell
{
struct EventNotificationListCell *next;
@@ -91,8 +86,7 @@ typedef enum
CONFIG_FAILOVER_MODE,
CONFIG_CONNECTION_CHECK_TYPE,
CONFIG_EVENT_NOTIFICATION_LIST,
CONFIG_TABLESPACE_MAPPING,
CONFIG_REPLICATION_TYPE
CONFIG_TABLESPACE_MAPPING
} ConfigItemType;
@@ -109,7 +103,6 @@ typedef struct ConfigFileSetting
ConnectionCheckType *checktypeptr;
EventNotificationList *notificationlistptr;
TablespaceList *tablespacemappingptr;
ReplicationType *replicationtypeptr;
} val;
union {
int intdefault;
@@ -117,7 +110,6 @@ typedef struct ConfigFileSetting
bool booldefault;
failover_mode_opt failovermodedefault;
ConnectionCheckType checktypedefault;
ReplicationType replicationtypedefault;
} defval;
union {
int intminval;
@@ -146,7 +138,7 @@ typedef struct
char config_directory[MAXPGPATH];
char pg_bindir[MAXPGPATH];
char repmgr_bindir[MAXPGPATH];
ReplicationType replication_type;
int replication_type;
/* log settings */
char log_level[MAXLEN];
@@ -206,7 +198,6 @@ typedef struct
int primary_notification_timeout;
int repmgrd_standby_startup_timeout;
char repmgrd_pid_file[MAXPGPATH];
bool repmgrd_exit_on_inactive_node;
bool standby_disconnect_on_failover;
int sibling_nodes_disconnect_timeout;
ConnectionCheckType connection_check_type;
@@ -250,7 +241,7 @@ typedef struct
/*
* undocumented settings
*
* These settings are for testing or experimental features
* These settings are for testing or experimential features
* and may be changed without notice.
*/
@@ -365,7 +356,6 @@ const char *format_failover_mode(failover_mode_opt failover);
void exit_with_cli_errors(ItemList *error_list, const char *repmgr_command);
void print_item_list(ItemList *item_list);
const char *print_replication_type(ReplicationType type);
const char *print_connection_check_type(ConnectionCheckType type);
char *print_event_notification_list(EventNotificationList *list);
char *print_tablespace_mapping(TablespaceList *tablespacemappingptr);
@@ -374,6 +364,6 @@ extern bool modify_auto_conf(const char *data_dir, KeyValueList *items);
extern bool ProcessRepmgrConfigFile(const char *config_file, const char *base_dir, ItemList *error_list, ItemList *warning_list);
extern bool ProcessPostgresConfigFile(const char *config_file, const char *base_dir, bool strict, KeyValueList *contents, ItemList *error_list, ItemList *warning_list);
extern bool ProcessPostgresConfigFile(const char *config_file, const char *base_dir, KeyValueList *contents, ItemList *error_list, ItemList *warning_list);
#endif /* _REPMGR_CONFIGFILE_H_ */

28
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for repmgr 5.3.0.
# Generated by GNU Autoconf 2.69 for repmgr 5.2.0.
#
# Report bugs to <repmgr@googlegroups.com>.
#
@@ -11,7 +11,7 @@
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
#
# Copyright (c) 2010-2021, EnterpriseDB Corporation
# Copyright (c) 2010-2020, 2ndQuadrant Ltd.
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##
@@ -582,8 +582,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='repmgr'
PACKAGE_TARNAME='repmgr'
PACKAGE_VERSION='5.3.0'
PACKAGE_STRING='repmgr 5.3.0'
PACKAGE_VERSION='5.2.0'
PACKAGE_STRING='repmgr 5.2.0'
PACKAGE_BUGREPORT='repmgr@googlegroups.com'
PACKAGE_URL='https://repmgr.org/'
@@ -1181,7 +1181,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures repmgr 5.3.0 to adapt to many kinds of systems.
\`configure' configures repmgr 5.2.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1242,7 +1242,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of repmgr 5.3.0:";;
short | recursive ) echo "Configuration of repmgr 5.2.0:";;
esac
cat <<\_ACEOF
@@ -1316,14 +1316,14 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
repmgr configure 5.3.0
repmgr configure 5.2.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
Copyright (c) 2010-2021, EnterpriseDB Corporation
Copyright (c) 2010-2020, 2ndQuadrant Ltd.
_ACEOF
exit
fi
@@ -1335,7 +1335,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by repmgr $as_me 5.3.0, which was
It was created by repmgr $as_me 5.2.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -1811,11 +1811,11 @@ fi
pgac_pg_config_version=$($PG_CONFIG --version 2>/dev/null)
major_version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^[^0-9]\+ \([0-9]\{1,2\}\).*$/\1/')
$SED -e 's/^PostgreSQL \([0-9]\{1,2\}\).*$/\1/')
if test "$major_version_num" -lt '10'; then
version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^[^0-9]\+ \([0-9]*\)\.\([0-9]*\)\([a-zA-Z0-9.]*\)$/\1.\2/')
$SED -e 's/^PostgreSQL \([0-9]*\)\.\([0-9]*\)\([a-zA-Z0-9.]*\)$/\1.\2/')
if test -z "$version_num"; then
as_fn_error $? "could not detect the PostgreSQL version, wrong or broken pg_config?" "$LINENO" 5
@@ -1829,7 +1829,7 @@ if test "$major_version_num" -lt '10'; then
fi
else
version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^[^0-9]\+ \(.\+\)$/\1/')
$SED -e 's/^PostgreSQL \(.\+\)$/\1/')
if test -z "$version_num"; then
as_fn_error $? "could not detect the PostgreSQL version, wrong or broken pg_config?" "$LINENO" 5
@@ -2487,7 +2487,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by repmgr $as_me 5.3.0, which was
This file was extended by repmgr $as_me 5.2.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -2550,7 +2550,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
repmgr config.status 5.3.0
repmgr config.status 5.2.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@@ -1,6 +1,6 @@
AC_INIT([repmgr], [5.3.1], [repmgr@googlegroups.com], [repmgr], [https://repmgr.org/])
AC_INIT([repmgr], [5.2.0], [repmgr@googlegroups.com], [repmgr], [https://repmgr.org/])
AC_COPYRIGHT([Copyright (c) 2010-2021, EnterpriseDB Corporation])
AC_COPYRIGHT([Copyright (c) 2010-2020, 2ndQuadrant Ltd.])
AC_CONFIG_HEADER(config.h)
@@ -19,11 +19,11 @@ fi
pgac_pg_config_version=$($PG_CONFIG --version 2>/dev/null)
major_version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^[[^0-9]]\+ \([[0-9]]\{1,2\}\).*$/\1/')
$SED -e 's/^PostgreSQL \([[0-9]]\{1,2\}\).*$/\1/')
if test "$major_version_num" -lt '10'; then
version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^[[^0-9]]\+ \([[0-9]]*\)\.\([[0-9]]*\)\([[a-zA-Z0-9.]]*\)$/\1.\2/')
$SED -e 's/^PostgreSQL \([[0-9]]*\)\.\([[0-9]]*\)\([[a-zA-Z0-9.]]*\)$/\1.\2/')
if test -z "$version_num"; then
AC_MSG_ERROR([could not detect the PostgreSQL version, wrong or broken pg_config?])
@@ -37,7 +37,7 @@ if test "$major_version_num" -lt '10'; then
fi
else
version_num=$(echo "$pgac_pg_config_version"|
$SED -e 's/^[[^0-9]]\+ \(.\+\)$/\1/')
$SED -e 's/^PostgreSQL \(.\+\)$/\1/')
if test -z "$version_num"; then
AC_MSG_ERROR([could not detect the PostgreSQL version, wrong or broken pg_config?])

View File

@@ -2,11 +2,11 @@
* controldata.c - functions for reading the pg_control file
*
* The functions provided here enable repmgr to read a pg_control file
* in a version-independent way, even if the PostgreSQL instance is not
* in a version-indepent way, even if the PostgreSQL instance is not
* running. For that reason we can't use on the pg_control_*() functions
* provided in PostgreSQL 9.6 and later.
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* Copyright (c) 2ndQuadrant, 2010-2020
*
* Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
@@ -333,7 +333,7 @@ get_controlfile(const char *DataDir)
control_file_info->minRecoveryPointTLI = ptr->minRecoveryPointTLI;
control_file_info->minRecoveryPoint = ptr->minRecoveryPoint;
#else
fprintf(stderr, "ERROR: please use a repmgr version built for PostgreSQL 12 or later\n");
fprintf(stderr, "ERROR: please use a repmgr version built for PostgreSQL 12\n");
exit(ERR_BAD_CONFIG);
#endif
}

View File

@@ -1,6 +1,6 @@
/*
* controldata.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* Copyright (c) 2ndQuadrant, 2010-2020
*
* Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California

View File

@@ -1,7 +1,7 @@
/*
* dbutils.c - Database connection/management functions
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* Copyright (c) 2ndQuadrant, 2010-2020
*
*
* This program is free software: you can redistribute it and/or modify
@@ -730,8 +730,6 @@ validate_conninfo_string(const char *conninfo_str, char **errmsg)
if (connOptions == NULL)
return false;
PQconninfoFree(connOptions);
return true;
}
@@ -1257,7 +1255,7 @@ bool
pg_reload_conf(PGconn *conn)
{
PGresult *res = NULL;
bool success = true;
bool success = false;
res = PQexec(conn, "SELECT pg_catalog.pg_reload_conf()");
@@ -4242,7 +4240,7 @@ _create_event(PGconn *conn, t_configuration_options *options, int node_id, char
}
break;
case 'p':
/* %p: primary id ("standby_switchover"/"repmgrd_failover_promote": former primary id) */
/* %p: primary id ("standby_switchover": former primary id) */
src_ptr++;
if (event_info->node_id != UNKNOWN_NODE_ID)
{
@@ -4827,7 +4825,7 @@ cancel_query(PGconn *conn, int timeout)
* Wait until current query finishes, ignoring any results.
* Usually this will be an async query or query cancellation.
*
* Returns 1 for success; 0 if any error occurred; -1 if timeout reached.
* Returns 1 for success; 0 if any error ocurred; -1 if timeout reached.
*/
int
wait_connection_availability(PGconn *conn, int timeout)
@@ -6008,43 +6006,6 @@ is_wal_replay_paused(PGconn *conn, bool check_pending_wal)
return is_paused;
}
/* repmgrd status functions */
CheckStatus
get_repmgrd_status(PGconn *conn)
{
PQExpBufferData query;
PGresult *res = NULL;
CheckStatus repmgrd_status = CHECK_STATUS_CRITICAL;
initPQExpBuffer(&query);
appendPQExpBufferStr(&query,
" SELECT "
" CASE "
" WHEN repmgr.repmgrd_is_running() "
" THEN "
" CASE "
" WHEN repmgr.repmgrd_is_paused() THEN 1 ELSE 0 "
" END "
" ELSE 2 "
" END AS repmgrd_status");
res = PQexec(conn, query.data);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
log_db_error(conn, query.data, _("unable to execute repmgrd status query"));
}
else
{
repmgrd_status = atoi(PQgetvalue(res, 0, 0));
}
termPQExpBuffer(&query);
PQclear(res);
return repmgrd_status;
}
/* miscellaneous debugging functions */

View File

@@ -1,7 +1,7 @@
/*
* dbutils.h
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -602,9 +602,6 @@ int get_upstream_last_seen(PGconn *conn, t_server_type node_type);
bool is_wal_replay_paused(PGconn *conn, bool check_pending_wal);
/* repmgrd status functions */
CheckStatus get_repmgrd_status(PGconn *conn);
/* miscellaneous debugging functions */
const char *print_node_status(NodeStatus node_status);
const char *print_pqping_status(PGPing ping_status);

View File

@@ -3,7 +3,7 @@
* dirmod.c
* directory handling functions
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -109,56 +109,9 @@ create_dir(const char *path)
bool
set_dir_permissions(const char *path, int server_version_num)
set_dir_permissions(const char *path)
{
struct stat stat_buf;
bool no_group_access =
(server_version_num != UNKNOWN_SERVER_VERSION_NUM) &&
(server_version_num < 110000);
/*
* At this point the path should exist, so this check is very
* much just-in-case.
*/
if (stat(path, &stat_buf) != 0)
{
if (errno == ENOENT)
{
log_warning(_("directory \"%s\" does not exist"), path);
}
else
{
log_warning(_("could not read permissions of directory \"%s\""),
path);
log_detail("%s", strerror(errno));
}
return false;
}
/*
* If mode is not 0700 or 0750, attempt to change.
*/
if ((no_group_access == true && (stat_buf.st_mode & (S_IRWXG | S_IRWXO)))
|| (no_group_access == false && (stat_buf.st_mode & (S_IWGRP | S_IRWXO))))
{
/*
* Currently we default to 0700.
* There is no facility to override this directly,
* but the user can manually create the directory with
* the desired permissions.
*/
if (chmod(path, 0700) != 0) {
log_error(_("unable to change permissions of directory \"%s\""), path);
log_detail("%s", strerror(errno));
return false;
}
return true;
}
/* Leave as-is */
return true;
return (chmod(path, 0700) != 0) ? false : true;
}
@@ -205,7 +158,7 @@ mkdir_p(char *path, mode_t omode)
/*
* POSIX 1003.2: For each dir operand that does not name an
* existing directory, effects equivalent to those caused by the
* following command shall occur:
* following command shall occcur:
*
* mkdir -p -m $(umask -S),u+wx $(dirname dir) && mkdir [-m mode]
* dir
@@ -289,7 +242,7 @@ is_pg_running(const char *path)
{
/*
* No PID file - PostgreSQL shouldn't be running. From 9.3 (the
* earliest version we care about) removal of the PID file will
* earliesty version we care about) removal of the PID file will
* cause the postmaster to shut down, so it's highly unlikely
* that PostgreSQL will still be running.
*/
@@ -350,7 +303,7 @@ create_pg_dir(const char *path, bool force)
switch (check_dir(path))
{
case DIR_NOENT:
/* Directory does not exist, attempt to create it. */
/* directory does not exist, attempt to create it */
log_info(_("creating directory \"%s\"..."), path);
if (!create_dir(path))
@@ -361,23 +314,14 @@ create_pg_dir(const char *path, bool force)
}
break;
case DIR_EMPTY:
/*
* Directory exists but empty, fix permissions and use it.
*
* Note that at this point the caller might not know the server
* version number, so in this case "set_dir_permissions()" will
* accept 0750 as a valid setting. As this is invalid in Pg10 and
* earlier, the caller should call "set_dir_permissions()" again
* when it has the number.
*
* We need to do the permissions check here in any case to catch
* fatal permissions early.
*/
/* exists but empty, fix permissions and use it */
log_info(_("checking and correcting permissions on existing directory \"%s\""),
path);
if (!set_dir_permissions(path, UNKNOWN_SERVER_VERSION_NUM))
if (!set_dir_permissions(path))
{
log_error(_("unable to change permissions of directory \"%s\""), path);
log_detail("%s", strerror(errno));
return false;
}
break;

View File

@@ -1,6 +1,6 @@
/*
* dirutil.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -35,7 +35,7 @@ typedef enum
} PgDirState;
extern int mkdir_p(char *path, mode_t omode);
extern bool set_dir_permissions(const char *path, int server_version_num);
extern bool set_dir_permissions(const char *path);
extern DataDirState check_dir(const char *path);
extern bool create_dir(const char *path);

View File

@@ -95,7 +95,6 @@ clean:
rm -f repmgr.html
rm -f repmgr-A4.pdf
rm -f repmgr-US.pdf
rm -f *.fo
rm -f html/*
maintainer-clean:

View File

@@ -62,7 +62,7 @@
<tip>
<para>
Our recommended configuration is to configure
2ndQuadrant's recommended configuration is to configure
<ulink url="https://www.pgbarman.org/">Barman</ulink> as a fallback
source of WAL files, rather than maintain replication slots for
each standby. See also: <link linkend="cloning-from-barman-restore-command">Using Barman as a WAL file source</link>.
@@ -127,7 +127,7 @@
filesystem layouts.
</para>
<para>
Either use PostgreSQL packages provided by the community or EnterpriseDB; if this
Either use PostgreSQL packages provided by the community or 2ndQuadrant; if this
is not possible, contact your vendor for assistance.
</para>
</sect2>
@@ -170,7 +170,7 @@
<para>
If different &quot;minor&quot; &repmgr; versions (e.g. 4.1.1 and 4.1.6) are installed,
&repmgr; will function, but we strongly recommend always running the same version
to ensure there are no unexpected surprises, e.g. a newer version behaving slightly
to ensure there are no unexpected suprises, e.g. a newer version behaving slightly
differently to the older version.
</para>
<para>
@@ -212,11 +212,11 @@
</para>
</sect2>
<sect2 id="faq-third-party-packages" xreflabel="Compatibility with third party vendor packages">
<sect2 id="faq-third-party-packages" xreflabel="Compatability with third party vendor packages">
<title>Are &repmgr; packages compatible with <literal>$third_party_vendor</literal>'s packages?</title>
<para>
&repmgr; packages provided by EnterpriseDB are compatible with the community-provided PostgreSQL
packages and specified software provided by EnterpriseDB.
&repmgr; packages provided by 2ndQuadrant are compatible with the community-provided PostgreSQL
packages and any software provided by 2ndQuadrant.
</para>
<para>
A number of other vendors provide their own versions of PostgreSQL packages, often with different
@@ -311,7 +311,7 @@
</para>
</sect2>
<sect2 id="faq-repmgr-shared-preload-libraries-no-repmgrd" xreflabel="shared_preload_libraries without repmgrd">
<sect2 id="faq-repmgr-shared-preload-libaries-no-repmgrd" xreflabel="shared_preload_libraries without repmgrd">
<title>Do I need to include <literal>shared_preload_libraries = 'repmgr'</literal>
in <filename>postgresql.conf</filename> if I'm not using &repmgrd;?</title>
<para>
@@ -459,7 +459,7 @@
</title>
<para>
<varname>promote_command</varname> or <varname>follow_command</varname> can be user-defined scripts,
so &repmgr; will not apply <option>pg_bindir</option> even if executing &repmgr;. Always provide the full
so &repmgr; will not apply <option>pg_bindir</option> even if excuting &repmgr;. Always provide the full
path; see <xref linkend="repmgrd-automatic-failover-configuration"/> for more details.
</para>
</sect2>
@@ -479,7 +479,7 @@
is out-of-date, which may lead to incorrect failover behaviour.
</para>
<para>
The onus is therefore on the administrator to manually set the cluster to a stable, healthy state before
The onus is therefore on the adminstrator to manually set the cluster to a stable, healthy state before
starting &repmgrd;.
</para>
</sect2>

View File

@@ -52,7 +52,8 @@
<para>
&repmgr; packages are available from the public 2ndQuadrant repository, and also the
PostgreSQL community repository. The 2ndQuadrant repository is updated immediately
after each &repmgr; release.
after each
&repmgr; release.
</para>
<table id="centos-2ndquadrant-repository">
@@ -397,7 +398,7 @@
</indexterm>
<indexterm>
<primary>packages</primary>
<secondary>snapshots</secondary>
<secondary>snaphots</secondary>
</indexterm>
<para>
@@ -438,7 +439,7 @@ curl https://dl.2ndquadrant.com/default/snapshot/get/9.6/rpm | sudo bash</progra
The package name will be formatted like this:
<programlisting>
repmgr96-4.1.1-0.0git320.g5113ab0.1.el7.x86_64.rpm</programlisting>
containing the snapshot build number (here: <literal>320</literal>) and the hash
containg the snapshot build number (here: <literal>320</literal>) and the hash
of the <application>git</application> commit it was built from (here: <literal>g5113ab0</literal>).
</para>

View File

@@ -16,226 +16,10 @@
</para>
<!-- remember to update the release date in ../repmgr_version.h.in -->
<sect1 id="release-5.3.1">
<title id="release-current">Release 5.3.1</title>
<para><emphasis>Tue 15 February, 2022</emphasis></para>
<para>
&repmgr; 5.3.1 is a minor release.
</para>
<sect2>
<title>Bug fixes</title>
<para>
<itemizedlist>
<listitem>
<para>
Fix upgrade path from &repmgr; 4.2 and 4.3 to &repmgr; 5.3.
</para>
</listitem>
<listitem>
<para>
&repmgrd;: ensure potentially open connections are closed.
</para>
<para>
In some cases, when recovering from degraded state in local node monitoring,
new connection was opened to the local node without closing
the old one, which will result in memory leakage.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
<sect1 id="release-5.3.0">
<title>Release 5.3.0</title>
<para><emphasis>Tue 12 October, 2021</emphasis></para>
<para>
&repmgr; 5.3.0 is a major release.
</para>
<para>
This release provides support for <ulink url="https://www.postgresql.org/docs/14/release-14.html">PostgreSQL 14</ulink>,
released in September 2021.
</para>
<sect2>
<title>Improvements</title>
<para>
<itemizedlist>
<listitem>
<para>
<link linkend="repmgr-standby-switchover"><command>repmgr standby switchover</command></link>:
Improve handling of node rejoin failure on the demotion candidate.
</para>
<para>
Previously &repmgr; did not check whether <command>repmgr node rejoin</command> actually
succeeded on the demotion candidate, and would always wait up to <varname>node_rejoin_timeout</varname>
seconds for it to attach to the promotion candidate, even if this would never happen.
</para>
<para>
This makes it easier to identify unexpected events during a switchover operation, such as
the demotion candidate being unexpectedly restarted by an external process.
</para>
<para>
Note that the output of the <link linkend="repmgr-node-rejoin"><command>repmgr node rejoin</command></link>
operation on the demotion candidate will now be logged to a temporary file on that node;
the location of the file will be reported in the error message, if one is emitted.
</para>
</listitem>
<listitem>
<para>
&repmgrd;: at startup, if node record is marked as "inactive", attempt
to set it to "active".
</para>
<para>
This behaviour can be overridden by setting the configuration parameter
<varname>repmgrd_exit_on_inactive_node</varname> to <literal>true</literal>.
</para>
</listitem>
<listitem>
<para>
<command><link linkend="repmgr-node-rejoin">repmgr node rejoin</link></command>:
emit rejoin target note information as <literal>NOTICE</literal>.
</para>
<para>
This makes it clearer what &repmgr; is trying to do.
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-node-check">repmgr node check</link>:
option <option>--repmgrd</option> added to check &repmgrd;
status.
</para>
</listitem>
<listitem>
<para>
Add <literal>%p</literal> <link linkend="event-notifications">event notification parameter</link>
providing the node ID of the former primary for the <literal>repmgrd_failover_promote</literal> event.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2>
<title>Bug fixes</title>
<para>
<itemizedlist>
<listitem>
<para>
<command><link linkend="repmgr-standby-clone">repmgr standby clone</link></command>:
if using <option>--replication-conf-only</option> on a node
which was set up without replication slots, but the &repmgr; configuration
was since changed to <option>use_replication_slots=1</option>,
&repmgr; will now set <varname>slot_name</varname> in the
node record, if it was previously empty.
</para>
</listitem>
<listitem>
<para>
&repmgrd;: rename internal shared library functions to minimize the
risk of clashes with other shared libraries.
</para>
<para>
This does not affect user-facing SQL functions. However an upgrade
of the installed extension version is required.
</para>
</listitem>
<listitem>
<para>
&repmgrd;: ensure short option <option>-s</option> is accepted.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
<sect1 id="release-5.2.1">
<title>Release 5.2.1</title>
<para><emphasis>Mon 7 December, 2020</emphasis></para>
<para>
&repmgr; 5.2.1 is a minor release.
</para>
<sect2>
<title>Improvements</title>
<para>
<itemizedlist>
<listitem>
<para>
<link linkend="repmgr-standby-clone">repmgr standby clone</link>:
option <option>--recovery-min-apply-delay</option> added, overriding any
setting present in <filename>repmgr.conf</filename>.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<sect2>
<title>Bug fixes</title>
<para>
<itemizedlist>
<listitem>
<para>
Configuration: fix parsing of <option>replication_type</option> configuration parameter. GitHub #672.
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-standby-clone">repmgr standby clone</link>:
handle case where <filename>postgresql.auto.conf</filename> is absent on the
source node.
</para>
</listitem>
<listitem>
<para>
<link linkend="repmgr-standby-clone">repmgr standby clone</link>:
in PostgreSQL 11 and later, an existing data directory's permissions
will not be changed to <option>0700</option> if they are already set to
<option>0750</option>.
</para>
</listitem>
<listitem>
<para>
&repmgrd;: prevent termination when local node not available and
<option>standby_disconnect_on_failover</option> is set. GitHub #675.
</para>
</listitem>
<listitem>
<para>
&repmgrd;: ensure <option>reconnect_interval</option> is correctly handled.
GitHub #673.
</para>
</listitem>
<listitem>
<para>
<command>repmgr witness --help</command>: fix <command>witness unregister</command>
description. GitHub #676.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
<sect1 id="release-5.2.0">
<title>Release 5.2.0</title>
<para><emphasis>Thu 22 October, 2020</emphasis></para>
<title id="release-current">Release 5.2.0</title>
<para><emphasis>??? ?? October, 2020</emphasis></para>
<para>
&repmgr; 5.2.0 is a major release.
@@ -1339,7 +1123,7 @@ REPMGRD_OPTS="--daemonize=false"</programlisting>
</para>
<para>
Possible values are <literal>ping</literal> (default; uses <command>PQping()</command> to
determine server availability), <literal>connection</literal> (attempts to make a new connection to
determine server availability), <literal>connection</literal> (attempst to make a new connection to
the upstream node), and <literal>query</literal> (determines server availability
by executing an SQL statement on the node via the existing connection).
</para>

View File

@@ -20,7 +20,7 @@
A mailing list/forum is provided via Google groups to discuss contributions or issues: <ulink url="https://groups.google.com/group/repmgr">https://groups.google.com/group/repmgr</ulink>.
</para>
<para>
Please report bugs and other issues to: <ulink url="https://github.com/EnterpriseDB/repmgr">https://github.com/EnterpriseDB/repmgr</ulink>.
Please report bugs and other issues to: <ulink url="https://github.com/2ndQuadrant/repmgr">https://github.com/2ndQuadrant/repmgr</ulink>.
</para>
<important>
@@ -64,7 +64,7 @@
<listitem>
<simpara>
<filename>repmgr.conf</filename> files (suitably anonymized if necessary)
<filename>repmpgr.conf</filename> files (suitably anonymized if necessary)
</simpara>
</listitem>

View File

@@ -319,7 +319,7 @@ description = "Main cluster"
Cascading replication, introduced with PostgreSQL 9.2, enables a standby server
to replicate from another standby server rather than directly from the primary,
meaning replication changes "cascade" down through a hierarchy of servers. This
can be used to reduce load on the primary and minimize bandwidth usage between
can be used to reduce load on the primary and minimize bandwith usage between
sites. For more details, see the
<ulink url="https://www.postgresql.org/docs/current/warm-standby.html#CASCADING-REPLICATION">
PostgreSQL cascading replication documentation</ulink>.
@@ -391,7 +391,7 @@ description = "Main cluster"
cluster, you may wish to clone a downstream standby whose upstream node
does not yet exist. In this case you can clone from the primary (or
another upstream node); provide the parameter <literal>--upstream-conninfo</literal>
to explicitly set the upstream's <varname>primary_conninfo</varname> string
to explictly set the upstream's <varname>primary_conninfo</varname> string
in <filename>recovery.conf</filename>.
</simpara>
</tip>

View File

@@ -7,14 +7,6 @@
<secondary>optional settings</secondary>
</indexterm>
<note>
<simpara>
This section documents a subset of optional configuration settings; for a full
for a full and annotated view of all configuration options see the
see the <ulink url="https://raw.githubusercontent.com/EnterpriseDB/repmgr/master/repmgr.conf.sample">sample repmgr.conf file</ulink>
</simpara>
</note>
<variablelist>
@@ -140,50 +132,5 @@ ssh_options='-q -o ConnectTimeout=10'</programlisting>
</listitem>
</varlistentry>
<varlistentry id="repmgr-conf-pg-bindir" xreflabel="pg_bindir">
<term><varname>pg_bindir</varname> (<type>string</type>)
<indexterm>
<primary><varname>pg_bindir</varname> configuration file parameter</primary>
</indexterm>
</term>
<listitem>
<para>
Path to the PostgreSQL binary directory (location of <application>pg_ctl</application>,
<application>pg_basebackup</application> etc.). Only required
if these are not in the system <varname>PATH</varname>.
</para>
<tip>
<para>
When &repmgr; is executed via <application>SSH</application> (e.g. when running
<command><link linkend="repmgr-standby-switchover">repmgr standby switchover</link></command>,
<command><link linkend="repmgr-cluster-matrix">repmgr cluster matrix</link></command> or
<command><link linkend="repmgr-cluster-crosscheck">repmgr cluster crosscheck</link></command>,
or if it is executed as cronjob), a login shell will not be used and only the
default system <varname>PATH</varname> will be set. Therefore it's recommended to set
<varname>pg_bindir</varname> so &repmgr; can correctly invoke binaries on a remote
system and avoid potential path issues.
</para>
</tip>
<para>
Debian/Ubuntu users: you will probably need to set this to the directory where
<application>pg_ctl</application> is located, e.g. <filename>/usr/lib/postgresql/9.6/bin/</filename>.
</para>
<para>
<emphasis>NOTE</emphasis>: <varname>pg_bindir</varname> is only used when &repmgr; directly
executes PostgreSQL binaries; any user-defined scripts
<emphasis>must</emphasis> be specified with the full path.
</para>
</listitem>
</varlistentry>
</variablelist>
<tip>
<simpara>
See the <ulink url="https://raw.githubusercontent.com/EnterpriseDB/repmgr/master/repmgr.conf.sample">sample repmgr.conf file</ulink>
for a full and annotated view of all configuration options.
</simpara>
</tip>
</sect1>

View File

@@ -96,9 +96,6 @@
</variablelist>
</para>
<para>
See <xref linkend="configuration-file-optional-settings"/> for further configuration options.
</para>
</sect1>

View File

@@ -27,9 +27,7 @@
<note>
<para>
If using <application>systemd</application>, ensure you have <varname>RemoveIPC</varname> set to <literal>off</literal>.
See the <ulink url="https://www.postgresql.org/docs/current/index.html">PostgreSQL documentation</ulink> section
<ulink url="https://www.postgresql.org/docs/current/kernel-resources.html#SYSTEMD-REMOVEIPC">systemd RemoveIPC</ulink>
and also the <ulink url="https://wiki.postgresql.org/wiki/Systemd">systemd</ulink>
See the <ulink url="https://wiki.postgresql.org/wiki/Systemd">systemd</ulink>
entry in the <ulink url="https://wiki.postgresql.org/wiki/Main_Page">PostgreSQL wiki</ulink> for details.
</para>
</note>

View File

@@ -262,7 +262,7 @@ conninfo='host=node1 user=repmgr dbname=repmgr connect_timeout=2'</programlistin
<indexterm>
<primary>repmgr.conf</primary>
<secondary>PostgreSQL major version upgrades</secondary>
<secondary>ostgreSQL major version upgrades</secondary>
</indexterm>
<para>

View File

@@ -95,8 +95,7 @@
</para>
<para>
The following parameters are provided for a subset of event notifications; their meaning may
change according to context:
The following parameters are provided for a subset of event notifications:
</para>
<variablelist>
@@ -109,9 +108,6 @@
<para>
node ID of the demoted primary (<xref linkend="repmgr-standby-switchover"/> only)
</para>
<para>
node ID of the former primary (<literal>repmgrd_failover_promote</literal> only)
</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -137,7 +133,7 @@
<para>
The values provided for <literal>%c</literal> and <literal>%a</literal>
may contain spaces, so should always be quoted.
will probably contain spaces, so should always be quoted.
</para>
<para>

View File

@@ -93,7 +93,7 @@
<table id="repmgr-compatibility-matrix">
<title>&repmgr; compatibility matrix</title>
<tgroup cols="4">
<tgroup cols="3">
<thead>
<row>
<entry>
@@ -112,30 +112,16 @@
</thead>
<tbody>
<row>
<entry>
&repmgr; 5.3
</entry>
<entry>
YES
</entry>
<entry>
<link linkend="release-current">&repmgrversion;</link> (&releasedate;)
</entry>
<entry>
9.4, 9.5, 9.6, 10, 11, 12, 13, 14
</entry>
</row>
<row>
<entry>
&repmgr; 5.2
</entry>
<entry>
NO
YES
</entry>
<entry>
<link linkend="release-5.2.1">5.2.1</link> (2020-12-07)
<link linkend="release-current">&repmgrversion;</link> (&releasedate;)
</entry>
<entry>
9.4, 9.5, 9.6, 10, 11, 12, 13

View File

@@ -178,18 +178,18 @@ deb-src https://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main</programlist
<para>
The source for &repmgr; is maintained at
<ulink url="https://github.com/EnterpriseDB/repmgr">https://github.com/EnterpriseDB/repmgr</ulink>.
<ulink url="https://github.com/2ndQuadrant/repmgr">https://github.com/2ndQuadrant/repmgr</ulink>.
</para>
<para>
There are also tags for each <ulink url="https://github.com/EnterpriseDB/repmgr/releases">&repmgr; release</ulink>, e.g.
<literal><ulink url="https://github.com/EnterpriseDB/repmgr/releases/tag/v4.4.0">v4.4.0</ulink></literal>.
There are also tags for each <ulink url="https://github.com/2ndQuadrant/repmgr/releases">&repmgr; release</ulink>, e.g.
<literal><ulink url="https://github.com/2ndQuadrant/repmgr/releases/tag/v4.4.0">v4.4.0</ulink></literal>.
</para>
<para>
Clone the source code using <application>git</application>:
<programlisting>
git clone https://github.com/EnterpriseDB/repmgr</programlisting>
git clone https://github.com/2ndQuadrant/repmgr</programlisting>
</para>
<para>

View File

@@ -3,16 +3,16 @@
<date>2017</date>
<copyright>
<year>2010-2021</year>
<holder>EnterpriseDB Corporation</holder>
<year>2010-2020</year>
<holder>2ndQuadrant, Ltd.</holder>
</copyright>
<legalnotice id="legalnotice">
<title>Legal Notice</title>
<para>
<productname>repmgr</productname> is Copyright &copy; 2010-2021
by EnterpriseDB Corporation All rights reserved.
<productname>repmgr</productname> is Copyright &copy; 2010-2020
by 2ndQuadrant, Ltd. All rights reserved.
</para>
<para>

View File

@@ -284,7 +284,7 @@
<tip>
<simpara>
For Debian-based distributions we recommend explicitly setting
For Debian-based distributions we recommend explictly setting
<option>pg_bindir</option> to the directory where <command>pg_ctl</command> and other binaries
not in the standard path are located. For PostgreSQL 9.6 this would be <filename>/usr/lib/postgresql/9.6/bin/</filename>.
</simpara>
@@ -302,7 +302,7 @@
<para>
See the file
<ulink url="https://raw.githubusercontent.com/EnterpriseDB/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink>
<ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink>
for details of all available configuration parameters.
</para>

View File

@@ -25,7 +25,7 @@
</para>
<para>
By default, &repmgr; will wait for up to 15 seconds to confirm that &repmgrd;
started. This behaviour can be overridden by specifying a different value using the <option>--wait</option>
started. This behaviour can be overridden by specifying a diffent value using the <option>--wait</option>
option, or disabled altogether with the <option>--no-wait</option> option.
</para>

View File

@@ -26,7 +26,7 @@
<para>
By default, &repmgr; will wait for up to 15 seconds to confirm that &repmgrd;
stopped. This behaviour can be overridden by specifying a different value using the <option>--wait</option>
stopped. This behaviour can be overridden by specifying a diffent value using the <option>--wait</option>
option, or disabled altogether with the <option>--no-wait</option> option.
</para>
<note>

View File

@@ -125,29 +125,12 @@
is correctly configured.
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title>repmgrd</title>
<para>
A separate check is available to verify whether &repmgrd; is running,
This is not included in the general output, as this does not
per-se constitute a check of the node's replication status.
</para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<option>--repmgrd</option>: checks whether &repmgrd; is running.
If &repmgrd; is running but paused, status <literal>1</literal>
(<literal>WARNING</literal>) is returned.
</simpara>
</listitem>
</itemizedlist>
</refsect1>
<refsect1>
<title>Additional checks</title>
<para>

View File

@@ -22,10 +22,6 @@
This can optionally use <application>pg_rewind</application> to re-integrate
a node which has diverged from the rest of the cluster, typically a failed primary.
</para>
<para>
Note that <command>repmgr node rejoin</command> can only be used to attach
a standby to the current primary, not another standby.
</para>
<tip>
<para>
@@ -285,7 +281,6 @@
<programlisting>
$ repmgr node rejoin -f /etc/repmgr.conf -d 'host=node3 dbname=repmgr user=repmgr' \
--force-rewind --config-files=postgresql.local.conf,postgresql.conf --verbose --dry-run
NOTICE: rejoin target is node "node3" (node ID: 3)
INFO: replication connection to the rejoin target node was successful
INFO: local and rejoin target system identifiers match
DETAIL: system identifier is 6652184002263212600
@@ -344,7 +339,6 @@
<programlisting>
$ repmgr node rejoin -f /etc/repmgr.conf -d 'host=node3 dbname=repmgr user=repmgr' \
--config-files=postgresql.local.conf,postgresql.conf --verbose --force-rewind --dry-run
NOTICE: rejoin target is node "node3" (node ID: 3)
INFO: replication connection to the rejoin target node was successful
INFO: local and rejoin target system identifiers match
DETAIL: system identifier is 6652460429293670710
@@ -455,16 +449,15 @@
</para>
<para>
Currently it is not possible to resolve this situation using <application>pg_rewind</application>.
A <ulink url="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=2b4f3130382fe2f8705863e4d38589d4d69cd695">patch</ulink>
has been successfully submitted and will be included the next PostgreSQL minor release round, scheduled for
February 2021.
A <ulink url="https://www.postgresql.org/message-id/flat/CABvVfJU-LDWvoz4-Yow3Ay5LZYTuPD7eSjjE4kGyNZpXC6FrVQ@mail.gmail.com">patch</ulink>
has been submitted and will hopefully be included in a forthcoming PostgreSQL minor release.
</para>
<para>
As a workaround, start the primary server the standby was previously attached to,
and ensure the standby can be attached to it. If <application>pg_rewind</application> was actually executed,
it will have copied in the <filename>.history</filename> file from the target primary server; this must
be removed. <command>repmgr node rejoin</command> can then be used to attach the standby to the original
primary. Ensure any changes pending on the primary have propagated to the standby. Then shut down the primary
primary. Ensure any changes pending on the primary have propogated to the standby. Then shut down the primary
server <emphasis>first</emphasis>, before shutting down the standby. It should then be possible to
use <command>repmgr node rejoin</command> to attach the standby to the new primary.
</para>

View File

@@ -260,29 +260,16 @@ pg_basebackup_options='--waldir=/path/to/wal-directory'</programlisting>
upstream node if required.
</para>
<para>
The upstream node must be running so the correct replication configuration can be obtained.
</para>
<para>
If the standby is running, the replication configuration will not be written unless the
Note that the upstream node must be running. In PostgreSQL 11 and earlier, an existing
<filename>recovery.conf</filename> will not be overwritten unless the
<option>-F/--force</option> option is provided.
</para>
<tip>
<para>
Execute <command>repmgr standby clone --replication-conf-only --dry-run</command>
to check the prerequisites for creating the recovery configuration,
and display the configuration changes which would be made without actually
making any changes.
</para>
</tip>
<para>
In PostgreSQL 13 and later, the PostgreSQL configuration must be reloaded for replication
configuration changes to take effect.
Execute <command>repmgr standby clone --replication-conf-only --dry-run</command>
to check the prerequisites for creating the recovery configuration,
and display the contents of the configuration which would be added without actually
making any changes.
</para>
<para>
In PostgreSQL 12 and earlier, the PostgreSQL instance must be restarted for replication
configuration changes to take effect.
</para>
</refsect1>
@@ -344,25 +331,6 @@ pg_basebackup_options='--waldir=/path/to/wal-directory'</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--recovery-min-apply-delay</option></term>
<listitem>
<para>
Set PostgreSQL configuration <option>recovery_min_apply_delay</option> parameter
to the provided value.
</para>
<para>
This overrides any <option>recovery_min_apply_delay</option> provided via
<filename>repmgr.conf</filename>.
</para>
<para>
For more details on this parameter, see:
<ulink url="https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-RECOVERY-MIN-APPLY-DELAY">recovery_min_apply_delay</ulink>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-R, --remote-user=USERNAME</option></term>
<listitem>
@@ -378,14 +346,14 @@ pg_basebackup_options='--waldir=/path/to/wal-directory'</programlisting>
<para>
Create recovery configuration for a previously cloned instance.
</para>
<para>
In PostgreSQL 12 and later, the replication configuration will be
written to <filename>postgresql.auto.conf</filename>.
</para>
<para>
In PostgreSQL 11 and earlier, the replication configuration will be
written to <filename>recovery.conf</filename>.
</para>
<para>
In PostgreSQL 12 and later, the replication configuration will be
written to <filename>postgresql.auto.conf</filename>.
</para>
</listitem>
</varlistentry>

View File

@@ -189,14 +189,14 @@
</listitem>
<listitem>
<simpara>
If the promotion candidate has insufficient free walsenders to accommodate the standbys which will
If the promotion candidate has insufficient free walsenders to accomodate the standbys which will
be attached to it, the standby will be promoted anyway.
</simpara>
</listitem>
<listitem>
<simpara>
If replication slots are in use but the promotion candidate has insufficient free replication slots
to accommodate the standbys which will be attached to it, the standby will be promoted anyway.
to accomodate the standbys which will be attached to it, the standby will be promoted anyway.
</simpara>
</listitem>
</itemizedlist>

View File

@@ -18,7 +18,7 @@
<title>repmgr &repmgrversion; Documentation</title>
<bookinfo>
<corpauthor>EnterpriseDB Corporation</corpauthor>
<corpauthor>2ndQuadrant Ltd</corpauthor>
<productname>repmgr</productname>
<productnumber>&repmgrversion;</productnumber>
&legal;
@@ -26,7 +26,7 @@
<abstract>
<para>
This is the official documentation of &repmgr; &repmgrversion; for
use with PostgreSQL 9.4 - PostgreSQL 14.
use with PostgreSQL 9.4 - PostgreSQL 13.
</para>
<para>
&repmgr; is being continually developed and we strongly recommend using the
@@ -38,20 +38,20 @@
<para>
&repmgr; is developed by
<ulink url="https://2ndquadrant.com">2ndQuadrant (EDB)</ulink>
<ulink url="https://2ndquadrant.com">2ndQuadrant</ulink>
along with contributions from other individuals and organisations.
Contributions from the community are appreciated and welcome - get
in touch via <ulink url="https://github.com/EnterpriseDB/repmgr">github</ulink>
in touch via <ulink url="https://github.com/2ndQuadrant/repmgr">github</ulink>
or <ulink url="https://groups.google.com/group/repmgr">the mailing list/forum</ulink>.
Multiple 2ndQuadrant (EDB) customers contribute funding
Multiple 2ndQuadrant customers contribute funding
to make repmgr development possible.
</para>
<para>
&repmgr; is fully supported by 2ndQuadrant (EDB)'s
&repmgr; is fully supported by 2ndQuadrant's
<ulink url="https://www.2ndquadrant.com/en/support/support-postgresql/">24/7 Production Support</ulink>.
EnterpriseDB Corporation, a Major Sponsor of the PostgreSQL project, continues to maintain &repmgr;.
We welcome participation from other organisations and individual developers.
2ndQuadrant, a Major Sponsor of the PostgreSQL project, continues to develop and maintain &repmgr;.
Other organisations as well as individual developers are welcome to participate in the efforts.
</para>
</abstract>

View File

@@ -586,7 +586,7 @@ INFO: node 3 received notification to rerun promotion candidate election
<sect2 id="repmgrd-primary-child-disconnection-caveats">
<title>Standby disconnections monitoring caveats</title>
<para>
The following caveats should be considered if you are intending to use this functionality.
The follwing caveats should be considered if you are intending to use this functionality.
</para>
<para>
<itemizedlist mark="bullet">

View File

@@ -89,10 +89,6 @@
<literal>query</literal> - determines server availability
by executing an SQL statement on the node via the existing connection
</simpara>
<simpara>
The query is a minimal throwaway query - <command>SELECT 1</command> -
which is used to determine that the server can accept queries.
</simpara>
</listitem>
</itemizedlist>
@@ -156,7 +152,7 @@
</variablelist>
<para>
See also <filename><ulink url="https://raw.githubusercontent.com/EnterpriseDB/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink></filename> for an annotated sample configuration file.
See also <filename><ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/master/repmgr.conf.sample">repmgr.conf.sample</ulink></filename> for an annotated sample configuration file.
</para>
<sect2 id="repmgrd-automatic-failover-configuration">
@@ -333,7 +329,7 @@
<title>Optional configuration for automatic failover</title>
<para>
The following configuraton options can be used to fine-tune automatic failover:
The following configuraton options can be use to fine-tune automatic failover:
</para>
<variablelist>
@@ -485,32 +481,6 @@
</listitem>
</varlistentry>
<varlistentry>
<term><option>repmgrd_exit_on_inactive_node</option></term>
<listitem>
<indexterm>
<primary>repmgrd_exit_on_inactive_node</primary>
</indexterm>
<para>
This parameter is available in &repmgr; 5.3 and later.
</para>
<para>
If a node was marked as inactive but is running, and this option is set to
<literal>true</literal>, &repmgrd; will abort on startup.
</para>
<para>
By default, <option>repmgrd_exit_on_inactive_node</option> is set
to <literal>false</literal>, in which case &repmgrd; will set the
node record to active on startup.
</para>
<para>
Setting this parameter to <literal>true</literal> causes &repmgrd;
to behave in the same way it did in &repmgr; 5.2 and earlier.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
@@ -569,7 +539,7 @@
</indexterm>
<para>
For further details and a reference implementation, see the separate document
<ulink url="https://github.com/EnterpriseDB/repmgr/blob/master/doc/repmgrd-node-fencing.md">Fencing a failed master node with repmgrd and PgBouncer</ulink>.
<ulink url="https://github.com/2ndQuadrant/repmgr/blob/master/doc/repmgrd-node-fencing.md">Fencing a failed master node with repmgrd and PgBouncer</ulink>.
</para>
</sect2>
@@ -999,7 +969,7 @@ repmgrd_service_stop_command='sudo systemctl repmgr12 stop'
</para>
<para>
If none of the above apply, &repmgrd; will create a PID file
in the operating system's temporary directory (as determined by the environment variable
in the operating system's temporary directory (as setermined by the environment variable
<varname>TMPDIR</varname>, or if that is not set, will use <filename>/tmp</filename>).
</para>
<para>
@@ -1079,29 +1049,6 @@ REPMGRD_OPTS="--daemonize=false"
</para>
</sect2>
<sect2 id="repmgrd-daemon-monitoring">
<title>repmgrd daemon monitoring</title>
<indexterm>
<primary>repmgrd</primary>
<secondary>monitoring</secondary>
</indexterm>
<indexterm>
<primary>monitoring</primary>
<secondary>repmgrd</secondary>
</indexterm>
<para>
The command <command><link linkend="repmgr-service-status">repmgr service status</link></command>
provides an overview of the &repmgrd; daemon status (including pause status)
on all nodes in the cluster.
</para>
<para>
From &repmgr; 5.3, <command><link linkend="repmgr-node-check">repmgr node check --repmgrd</link></command>
can be used to check the status of &repmgrd; (including pause status)
on the local node.
</para>
</sect2>
</sect1>
<sect1 id="repmgrd-connection-settings">

View File

@@ -120,19 +120,16 @@
</important>
<note>
<para>
<simpara>
On <literal>systemd</literal> systems we strongly recommend using the appropriate
<command>systemctl</command> commands (typically run via <command>sudo</command>) to ensure
<literal>systemd</literal> is informed about the status of the PostgreSQL service.
</para>
<para>
</simpara>
<simpara>
If using <command>sudo</command> for the <command>systemctl</command> calls, make sure the
<command>sudo</command> specification doesn't require a real tty for the user. If not set
this way, <command>repmgr</command> will fail to stop the primary.
</para>
<para>
See the <xref linkend="configuration-file-service-commands"/> documentation section for further details.
</para>
</simpara>
</note>
<para>

View File

@@ -482,7 +482,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
<simpara>
If you don't care about any data from the existing &repmgr; installation,
(e.g. the contents of the <structname>events</structname> and <structname>monitoring</structname>
tables), the following steps can be skipped; proceed to <xref linkend="upgrade-reregister-nodes"/>.
tables), the follwing steps can be skipped; proceed to <xref linkend="upgrade-reregister-nodes"/>.
</simpara>
</tip>
@@ -497,10 +497,10 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<ulink url="https://raw.githubusercontent.com/EnterpriseDB/repmgr/REL3_3_STABLE/sql/repmgr3.0_repmgr3.1.sql">repmgr3.0_repmgr3.1.sql</ulink></simpara>
<ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/REL3_3_STABLE/sql/repmgr3.0_repmgr3.1.sql">repmgr3.0_repmgr3.1.sql</ulink></simpara>
</listitem>
<listitem>
<simpara><ulink url="https://raw.githubusercontent.com/EnterpriseDB/repmgr/REL3_3_STABLE/sql/repmgr3.1.1_repmgr3.1.2.sql">repmgr3.1.1_repmgr3.1.2.sql</ulink></simpara>
<simpara><ulink url="https://raw.githubusercontent.com/2ndQuadrant/repmgr/REL3_3_STABLE/sql/repmgr3.1.1_repmgr3.1.2.sql">repmgr3.1.1_repmgr3.1.2.sql</ulink></simpara>
</listitem>
</itemizedlist>
</para>
@@ -532,7 +532,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
<sect2>
<title>Upgrading the repmgr schema (PostgreSQL 13 and later)</title>
<para>
Beginning with PostgreSQL 13, the <command>CREATE EXTENSION ... FROM unpackaged</command>
Beginning with PostgreSQL 13, the <command>CREATE EXTENSION ... FROM</command>
syntax is no longer available. In the unlikely event you have ended up with an
installation running PostgreSQL 13 or later and containing the legacy &repmgr;
schema, there is no convenient way of upgrading this; instead you'll just need

View File

@@ -1,6 +1,6 @@
/*
* errcode.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

2
log.c
View File

@@ -1,6 +1,6 @@
/*
* log.c - Logging methods
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

2
log.h
View File

@@ -1,6 +1,6 @@
/*
* log.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -1,10 +1,17 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION repmgr UPDATE" to load this file. \quit
\echo Use "CREATE EXTENSION repmgr" to load this file. \quit
-- This script is intentionally empty and exists to skip the CREATE FUNCTION
-- commands contained in the 4.2--4.3 and 4.3--4.4 extension upgrade scripts,
-- which reference C functions which no longer exist in 5.3 and later.
--
-- These functions will be explicitly created in the 5.2--5.3 extension
-- upgrade step with the correct C function references.
CREATE FUNCTION set_upstream_last_seen()
RETURNS VOID
AS 'MODULE_PATHNAME', 'set_upstream_last_seen'
LANGUAGE C STRICT;
CREATE FUNCTION get_upstream_last_seen()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_upstream_last_seen'
LANGUAGE C STRICT;
CREATE FUNCTION get_wal_receiver_pid()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_wal_receiver_pid'
LANGUAGE C STRICT;

View File

@@ -1,9 +1,19 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION repmgr UPDATE" to load this file. \quit
\echo Use "CREATE EXTENSION repmgr" to load this file. \quit
-- This script is intentionally empty and exists to skip the CREATE FUNCTION
-- commands contained in the 4.3--4.4 extension upgrade script, which reference
-- C functions which no longer exist in 5.3 and later.
--
-- These functions will be explicitly created in the 5.2--5.3 extension
-- upgrade step with the correct C function references.
DROP FUNCTION set_upstream_last_seen();
CREATE FUNCTION set_upstream_last_seen(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'set_upstream_last_seen'
LANGUAGE C STRICT;
CREATE FUNCTION get_upstream_node_id()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_upstream_node_id'
LANGUAGE C STRICT;
CREATE FUNCTION set_upstream_node_id(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'set_upstream_node_id'
LANGUAGE C STRICT;

View File

@@ -1,64 +0,0 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION repmgr" to load this file. \quit
CREATE OR REPLACE FUNCTION set_local_node_id(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_set_local_node_id'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION repmgr.get_local_node_id()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_local_node_id'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION standby_set_last_updated()
RETURNS TIMESTAMP WITH TIME ZONE
AS 'MODULE_PATHNAME', 'repmgr_standby_set_last_updated'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION standby_get_last_updated()
RETURNS TIMESTAMP WITH TIME ZONE
AS 'MODULE_PATHNAME', 'repmgr_standby_get_last_updated'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION set_upstream_last_seen(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_set_upstream_last_seen'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION get_upstream_last_seen()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_upstream_last_seen'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION get_upstream_node_id()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_upstream_node_id'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION set_upstream_node_id(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_set_upstream_node_id'
LANGUAGE C STRICT;
/* failover functions */
CREATE OR REPLACE FUNCTION notify_follow_primary(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_notify_follow_primary'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION get_new_primary()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_new_primary'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION reset_voting_status()
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_reset_voting_status'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION get_wal_receiver_pid()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_wal_receiver_pid'
LANGUAGE C STRICT;

View File

@@ -1,192 +0,0 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION repmgr" to load this file. \quit
CREATE TABLE repmgr.nodes (
node_id INTEGER PRIMARY KEY,
upstream_node_id INTEGER NULL REFERENCES nodes (node_id) DEFERRABLE,
active BOOLEAN NOT NULL DEFAULT TRUE,
node_name TEXT NOT NULL,
type TEXT NOT NULL CHECK (type IN('primary','standby','witness','bdr')),
location TEXT NOT NULL DEFAULT 'default',
priority INT NOT NULL DEFAULT 100,
conninfo TEXT NOT NULL,
repluser VARCHAR(63) NOT NULL,
slot_name TEXT NULL,
config_file TEXT NOT NULL
);
SELECT pg_catalog.pg_extension_config_dump('repmgr.nodes', '');
CREATE TABLE repmgr.events (
node_id INTEGER NOT NULL,
event TEXT NOT NULL,
successful BOOLEAN NOT NULL DEFAULT TRUE,
event_timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
details TEXT NULL
);
SELECT pg_catalog.pg_extension_config_dump('repmgr.events', '');
CREATE TABLE repmgr.monitoring_history (
primary_node_id INTEGER NOT NULL,
standby_node_id INTEGER NOT NULL,
last_monitor_time TIMESTAMP WITH TIME ZONE NOT NULL,
last_apply_time TIMESTAMP WITH TIME ZONE,
last_wal_primary_location PG_LSN NOT NULL,
last_wal_standby_location PG_LSN,
replication_lag BIGINT NOT NULL,
apply_lag BIGINT NOT NULL
);
CREATE INDEX idx_monitoring_history_time
ON repmgr.monitoring_history (last_monitor_time, standby_node_id);
SELECT pg_catalog.pg_extension_config_dump('repmgr.monitoring_history', '');
CREATE VIEW repmgr.show_nodes AS
SELECT n.node_id,
n.node_name,
n.active,
n.upstream_node_id,
un.node_name AS upstream_node_name,
n.type,
n.priority,
n.conninfo
FROM repmgr.nodes n
LEFT JOIN repmgr.nodes un
ON un.node_id = n.upstream_node_id;
CREATE TABLE repmgr.voting_term (
term INT NOT NULL
);
CREATE UNIQUE INDEX voting_term_restrict
ON repmgr.voting_term ((TRUE));
CREATE RULE voting_term_delete AS
ON DELETE TO repmgr.voting_term
DO INSTEAD NOTHING;
/* ================= */
/* repmgrd functions */
/* ================= */
/* monitoring functions */
CREATE FUNCTION set_local_node_id(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_set_local_node_id'
LANGUAGE C STRICT;
CREATE FUNCTION get_local_node_id()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_local_node_id'
LANGUAGE C STRICT;
CREATE FUNCTION standby_set_last_updated()
RETURNS TIMESTAMP WITH TIME ZONE
AS 'MODULE_PATHNAME', 'repmgr_standby_set_last_updated'
LANGUAGE C STRICT;
CREATE FUNCTION standby_get_last_updated()
RETURNS TIMESTAMP WITH TIME ZONE
AS 'MODULE_PATHNAME', 'repmgr_standby_get_last_updated'
LANGUAGE C STRICT;
CREATE FUNCTION set_upstream_last_seen(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_set_upstream_last_seen'
LANGUAGE C STRICT;
CREATE FUNCTION get_upstream_last_seen()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_upstream_last_seen'
LANGUAGE C STRICT;
CREATE FUNCTION get_upstream_node_id()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_upstream_node_id'
LANGUAGE C STRICT;
CREATE FUNCTION set_upstream_node_id(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_set_upstream_node_id'
LANGUAGE C STRICT;
/* failover functions */
CREATE FUNCTION notify_follow_primary(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_notify_follow_primary'
LANGUAGE C STRICT;
CREATE FUNCTION get_new_primary()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_new_primary'
LANGUAGE C STRICT;
CREATE FUNCTION reset_voting_status()
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_reset_voting_status'
LANGUAGE C STRICT;
CREATE FUNCTION get_repmgrd_pid()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_repmgrd_pid'
LANGUAGE C STRICT;
CREATE FUNCTION get_repmgrd_pidfile()
RETURNS TEXT
AS 'MODULE_PATHNAME', 'get_repmgrd_pidfile'
LANGUAGE C STRICT;
CREATE FUNCTION set_repmgrd_pid(INT, TEXT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'set_repmgrd_pid'
LANGUAGE C CALLED ON NULL INPUT;
CREATE FUNCTION repmgrd_is_running()
RETURNS BOOL
AS 'MODULE_PATHNAME', 'repmgrd_is_running'
LANGUAGE C STRICT;
CREATE FUNCTION repmgrd_pause(BOOL)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgrd_pause'
LANGUAGE C STRICT;
CREATE FUNCTION repmgrd_is_paused()
RETURNS BOOL
AS 'MODULE_PATHNAME', 'repmgrd_is_paused'
LANGUAGE C STRICT;
CREATE FUNCTION get_wal_receiver_pid()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_wal_receiver_pid'
LANGUAGE C STRICT;
/* views */
CREATE VIEW repmgr.replication_status AS
SELECT m.primary_node_id, m.standby_node_id, n.node_name AS standby_name,
n.type AS node_type, n.active, last_monitor_time,
CASE WHEN n.type='standby' THEN m.last_wal_primary_location ELSE NULL END AS last_wal_primary_location,
m.last_wal_standby_location,
CASE WHEN n.type='standby' THEN pg_catalog.pg_size_pretty(m.replication_lag) ELSE NULL END AS replication_lag,
CASE WHEN n.type='standby' THEN
CASE WHEN replication_lag > 0 THEN age(now(), m.last_apply_time) ELSE '0'::INTERVAL END
ELSE NULL
END AS replication_time_lag,
CASE WHEN n.type='standby' THEN pg_catalog.pg_size_pretty(m.apply_lag) ELSE NULL END AS apply_lag,
AGE(NOW(), CASE WHEN pg_catalog.pg_is_in_recovery() THEN repmgr.standby_get_last_updated() ELSE m.last_monitor_time END) AS communication_time_lag
FROM repmgr.monitoring_history m
JOIN repmgr.nodes n ON m.standby_node_id = n.node_id
WHERE (m.standby_node_id, m.last_monitor_time) IN (
SELECT m1.standby_node_id, MAX(m1.last_monitor_time)
FROM repmgr.monitoring_history m1 GROUP BY 1
);

View File

@@ -1,245 +0,0 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION repmgr" to load this file. \quit
-- extract the current schema name
-- NOTE: this assumes there will be only one schema matching 'repmgr_%';
-- user is responsible for ensuring this is the case
CREATE TEMPORARY TABLE repmgr_old_schema (schema_name TEXT);
INSERT INTO repmgr_old_schema (schema_name)
SELECT nspname AS schema_name
FROM pg_catalog.pg_namespace
WHERE nspname LIKE 'repmgr_%'
LIMIT 1;
-- move old objects into new schema
DO $repmgr$
DECLARE
old_schema TEXT;
BEGIN
SELECT schema_name FROM repmgr_old_schema
INTO old_schema;
EXECUTE format('ALTER TABLE %I.repl_nodes SET SCHEMA repmgr', old_schema);
EXECUTE format('ALTER TABLE %I.repl_events SET SCHEMA repmgr', old_schema);
EXECUTE format('ALTER TABLE %I.repl_monitor SET SCHEMA repmgr', old_schema);
EXECUTE format('DROP VIEW IF EXISTS %I.repl_show_nodes', old_schema);
EXECUTE format('DROP VIEW IF EXISTS %I.repl_status', old_schema);
END$repmgr$;
-- convert "repmgr_$cluster.repl_nodes" to "repmgr.nodes"
CREATE TABLE repmgr.nodes (
node_id INTEGER PRIMARY KEY,
upstream_node_id INTEGER NULL REFERENCES repmgr.nodes (node_id) DEFERRABLE,
active BOOLEAN NOT NULL DEFAULT TRUE,
node_name TEXT NOT NULL,
type TEXT NOT NULL CHECK (type IN('primary','standby','witness','bdr')),
location TEXT NOT NULL DEFAULT 'default',
priority INT NOT NULL DEFAULT 100,
conninfo TEXT NOT NULL,
repluser VARCHAR(63) NOT NULL,
slot_name TEXT NULL,
config_file TEXT NOT NULL
);
INSERT INTO repmgr.nodes
(node_id, upstream_node_id, active, node_name, type, location, priority, conninfo, repluser, slot_name, config_file)
SELECT id, upstream_node_id, active, name,
CASE WHEN type = 'master' THEN 'primary' ELSE type END,
'default', priority, conninfo, 'unknown', slot_name, 'unknown'
FROM repmgr.repl_nodes
ORDER BY id;
-- convert "repmgr_$cluster.repl_event" to "event"
CREATE TABLE repmgr.events (
node_id INTEGER NOT NULL,
event TEXT NOT NULL,
successful BOOLEAN NOT NULL DEFAULT TRUE,
event_timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
details TEXT NULL
);
INSERT INTO repmgr.events
(node_id, event, successful, event_timestamp, details)
SELECT node_id, event, successful, event_timestamp, details
FROM repmgr.repl_events;
-- create new table "repmgr.voting_term"
CREATE TABLE repmgr.voting_term (
term INT NOT NULL
);
CREATE UNIQUE INDEX voting_term_restrict
ON repmgr.voting_term ((TRUE));
CREATE RULE voting_term_delete AS
ON DELETE TO repmgr.voting_term
DO INSTEAD NOTHING;
INSERT INTO repmgr.voting_term (term) VALUES (1);
-- convert "repmgr_$cluster.repl_monitor" to "monitoring_history"
CREATE TABLE repmgr.monitoring_history (
primary_node_id INTEGER NOT NULL,
standby_node_id INTEGER NOT NULL,
last_monitor_time TIMESTAMP WITH TIME ZONE NOT NULL,
last_apply_time TIMESTAMP WITH TIME ZONE,
last_wal_primary_location PG_LSN NOT NULL,
last_wal_standby_location PG_LSN,
replication_lag BIGINT NOT NULL,
apply_lag BIGINT NOT NULL
);
INSERT INTO repmgr.monitoring_history
(primary_node_id, standby_node_id, last_monitor_time, last_apply_time, last_wal_primary_location, last_wal_standby_location, replication_lag, apply_lag)
SELECT primary_node, standby_node, last_monitor_time, last_apply_time, last_wal_primary_location::pg_lsn, last_wal_standby_location::pg_lsn, replication_lag, apply_lag
FROM repmgr.repl_monitor;
CREATE INDEX idx_monitoring_history_time
ON repmgr.monitoring_history (last_monitor_time, standby_node_id);
CREATE VIEW repmgr.show_nodes AS
SELECT n.node_id,
n.node_name,
n.active,
n.upstream_node_id,
un.node_name AS upstream_node_name,
n.type,
n.priority,
n.conninfo
FROM repmgr.nodes n
LEFT JOIN repmgr.nodes un
ON un.node_id = n.upstream_node_id;
/* ================= */
/* repmgrd functions */
/* ================= */
/* monitoring functions */
CREATE FUNCTION set_local_node_id(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'set_local_node_id'
LANGUAGE C STRICT;
CREATE FUNCTION get_local_node_id()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_local_node_id'
LANGUAGE C STRICT;
CREATE FUNCTION standby_set_last_updated()
RETURNS TIMESTAMP WITH TIME ZONE
AS 'MODULE_PATHNAME', 'standby_set_last_updated'
LANGUAGE C STRICT;
CREATE FUNCTION standby_get_last_updated()
RETURNS TIMESTAMP WITH TIME ZONE
AS 'MODULE_PATHNAME', 'standby_get_last_updated'
LANGUAGE C STRICT;
CREATE FUNCTION set_upstream_last_seen(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'set_upstream_last_seen'
LANGUAGE C STRICT;
CREATE FUNCTION get_upstream_last_seen()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_upstream_last_seen'
LANGUAGE C STRICT;
CREATE FUNCTION get_upstream_node_id()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_upstream_node_id'
LANGUAGE C STRICT;
CREATE FUNCTION set_upstream_node_id(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'set_upstream_node_id'
LANGUAGE C STRICT;
/* failover functions */
CREATE FUNCTION notify_follow_primary(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'notify_follow_primary'
LANGUAGE C STRICT;
CREATE FUNCTION get_new_primary()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_new_primary'
LANGUAGE C STRICT;
CREATE FUNCTION reset_voting_status()
RETURNS VOID
AS 'MODULE_PATHNAME', 'reset_voting_status'
LANGUAGE C STRICT;
CREATE FUNCTION get_repmgrd_pid()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_repmgrd_pid'
LANGUAGE C STRICT;
CREATE FUNCTION get_repmgrd_pidfile()
RETURNS TEXT
AS 'MODULE_PATHNAME', 'get_repmgrd_pidfile'
LANGUAGE C STRICT;
CREATE FUNCTION set_repmgrd_pid(INT, TEXT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'set_repmgrd_pid'
LANGUAGE C CALLED ON NULL INPUT;
CREATE FUNCTION repmgrd_is_running()
RETURNS BOOL
AS 'MODULE_PATHNAME', 'repmgrd_is_running'
LANGUAGE C STRICT;
CREATE FUNCTION repmgrd_pause(BOOL)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgrd_pause'
LANGUAGE C STRICT;
CREATE FUNCTION repmgrd_is_paused()
RETURNS BOOL
AS 'MODULE_PATHNAME', 'repmgrd_is_paused'
LANGUAGE C STRICT;
CREATE FUNCTION get_wal_receiver_pid()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_wal_receiver_pid'
LANGUAGE C STRICT;
/* views */
CREATE VIEW repmgr.replication_status AS
SELECT m.primary_node_id, m.standby_node_id, n.node_name AS standby_name,
n.type AS node_type, n.active, last_monitor_time,
CASE WHEN n.type='standby' THEN m.last_wal_primary_location ELSE NULL END AS last_wal_primary_location,
m.last_wal_standby_location,
CASE WHEN n.type='standby' THEN pg_catalog.pg_size_pretty(m.replication_lag) ELSE NULL END AS replication_lag,
CASE WHEN n.type='standby' THEN
CASE WHEN replication_lag > 0 THEN age(now(), m.last_apply_time) ELSE '0'::INTERVAL END
ELSE NULL
END AS replication_time_lag,
CASE WHEN n.type='standby' THEN pg_catalog.pg_size_pretty(m.apply_lag) ELSE NULL END AS apply_lag,
AGE(NOW(), CASE WHEN pg_catalog.pg_is_in_recovery() THEN repmgr.standby_get_last_updated() ELSE m.last_monitor_time END) AS communication_time_lag
FROM repmgr.monitoring_history m
JOIN repmgr.nodes n ON m.standby_node_id = n.node_id
WHERE (m.standby_node_id, m.last_monitor_time) IN (
SELECT m1.standby_node_id, MAX(m1.last_monitor_time)
FROM repmgr.monitoring_history m1 GROUP BY 1
);
/* drop old tables */
DROP TABLE repmgr.repl_nodes;
DROP TABLE repmgr.repl_monitor;
DROP TABLE repmgr.repl_events;
-- remove temporary table
DROP TABLE repmgr_old_schema;

View File

@@ -1,245 +0,0 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION repmgr" to load this file. \quit
-- extract the current schema name
-- NOTE: this assumes there will be only one schema matching 'repmgr_%';
-- user is responsible for ensuring this is the case
CREATE TEMPORARY TABLE repmgr_old_schema (schema_name TEXT);
INSERT INTO repmgr_old_schema (schema_name)
SELECT nspname AS schema_name
FROM pg_catalog.pg_namespace
WHERE nspname LIKE 'repmgr_%'
LIMIT 1;
-- move old objects into new schema
DO $repmgr$
DECLARE
old_schema TEXT;
BEGIN
SELECT schema_name FROM repmgr_old_schema
INTO old_schema;
EXECUTE format('ALTER TABLE %I.repl_nodes SET SCHEMA repmgr', old_schema);
EXECUTE format('ALTER TABLE %I.repl_events SET SCHEMA repmgr', old_schema);
EXECUTE format('ALTER TABLE %I.repl_monitor SET SCHEMA repmgr', old_schema);
EXECUTE format('DROP VIEW IF EXISTS %I.repl_show_nodes', old_schema);
EXECUTE format('DROP VIEW IF EXISTS %I.repl_status', old_schema);
END$repmgr$;
-- convert "repmgr_$cluster.repl_nodes" to "repmgr.nodes"
CREATE TABLE repmgr.nodes (
node_id INTEGER PRIMARY KEY,
upstream_node_id INTEGER NULL REFERENCES repmgr.nodes (node_id) DEFERRABLE,
active BOOLEAN NOT NULL DEFAULT TRUE,
node_name TEXT NOT NULL,
type TEXT NOT NULL CHECK (type IN('primary','standby','witness','bdr')),
location TEXT NOT NULL DEFAULT 'default',
priority INT NOT NULL DEFAULT 100,
conninfo TEXT NOT NULL,
repluser VARCHAR(63) NOT NULL,
slot_name TEXT NULL,
config_file TEXT NOT NULL
);
INSERT INTO repmgr.nodes
(node_id, upstream_node_id, active, node_name, type, location, priority, conninfo, repluser, slot_name, config_file)
SELECT id, upstream_node_id, active, name,
CASE WHEN type = 'master' THEN 'primary' ELSE type END,
'default', priority, conninfo, 'unknown', slot_name, 'unknown'
FROM repmgr.repl_nodes
ORDER BY id;
-- convert "repmgr_$cluster.repl_event" to "event"
CREATE TABLE repmgr.events (
node_id INTEGER NOT NULL,
event TEXT NOT NULL,
successful BOOLEAN NOT NULL DEFAULT TRUE,
event_timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
details TEXT NULL
);
INSERT INTO repmgr.events
(node_id, event, successful, event_timestamp, details)
SELECT node_id, event, successful, event_timestamp, details
FROM repmgr.repl_events;
-- create new table "repmgr.voting_term"
CREATE TABLE repmgr.voting_term (
term INT NOT NULL
);
CREATE UNIQUE INDEX voting_term_restrict
ON repmgr.voting_term ((TRUE));
CREATE RULE voting_term_delete AS
ON DELETE TO repmgr.voting_term
DO INSTEAD NOTHING;
INSERT INTO repmgr.voting_term (term) VALUES (1);
-- convert "repmgr_$cluster.repl_monitor" to "monitoring_history"
CREATE TABLE repmgr.monitoring_history (
primary_node_id INTEGER NOT NULL,
standby_node_id INTEGER NOT NULL,
last_monitor_time TIMESTAMP WITH TIME ZONE NOT NULL,
last_apply_time TIMESTAMP WITH TIME ZONE,
last_wal_primary_location PG_LSN NOT NULL,
last_wal_standby_location PG_LSN,
replication_lag BIGINT NOT NULL,
apply_lag BIGINT NOT NULL
);
INSERT INTO repmgr.monitoring_history
(primary_node_id, standby_node_id, last_monitor_time, last_apply_time, last_wal_primary_location, last_wal_standby_location, replication_lag, apply_lag)
SELECT primary_node, standby_node, last_monitor_time, last_apply_time, last_wal_primary_location::pg_lsn, last_wal_standby_location::pg_lsn, replication_lag, apply_lag
FROM repmgr.repl_monitor;
CREATE INDEX idx_monitoring_history_time
ON repmgr.monitoring_history (last_monitor_time, standby_node_id);
CREATE VIEW repmgr.show_nodes AS
SELECT n.node_id,
n.node_name,
n.active,
n.upstream_node_id,
un.node_name AS upstream_node_name,
n.type,
n.priority,
n.conninfo
FROM repmgr.nodes n
LEFT JOIN repmgr.nodes un
ON un.node_id = n.upstream_node_id;
/* ================= */
/* repmgrd functions */
/* ================= */
/* monitoring functions */
CREATE FUNCTION set_local_node_id(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_set_local_node_id'
LANGUAGE C STRICT;
CREATE FUNCTION get_local_node_id()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_local_node_id'
LANGUAGE C STRICT;
CREATE FUNCTION standby_set_last_updated()
RETURNS TIMESTAMP WITH TIME ZONE
AS 'MODULE_PATHNAME', 'repmgr_standby_set_last_updated'
LANGUAGE C STRICT;
CREATE FUNCTION standby_get_last_updated()
RETURNS TIMESTAMP WITH TIME ZONE
AS 'MODULE_PATHNAME', 'repmgr_standby_get_last_updated'
LANGUAGE C STRICT;
CREATE FUNCTION set_upstream_last_seen(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_set_upstream_last_seen'
LANGUAGE C STRICT;
CREATE FUNCTION get_upstream_last_seen()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_upstream_last_seen'
LANGUAGE C STRICT;
CREATE FUNCTION get_upstream_node_id()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_upstream_node_id'
LANGUAGE C STRICT;
CREATE FUNCTION set_upstream_node_id(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_set_upstream_node_id'
LANGUAGE C STRICT;
/* failover functions */
CREATE FUNCTION notify_follow_primary(INT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_notify_follow_primary'
LANGUAGE C STRICT;
CREATE FUNCTION get_new_primary()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_new_primary'
LANGUAGE C STRICT;
CREATE FUNCTION reset_voting_status()
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgr_reset_voting_status'
LANGUAGE C STRICT;
CREATE FUNCTION get_repmgrd_pid()
RETURNS INT
AS 'MODULE_PATHNAME', 'get_repmgrd_pid'
LANGUAGE C STRICT;
CREATE FUNCTION get_repmgrd_pidfile()
RETURNS TEXT
AS 'MODULE_PATHNAME', 'get_repmgrd_pidfile'
LANGUAGE C STRICT;
CREATE FUNCTION set_repmgrd_pid(INT, TEXT)
RETURNS VOID
AS 'MODULE_PATHNAME', 'set_repmgrd_pid'
LANGUAGE C CALLED ON NULL INPUT;
CREATE FUNCTION repmgrd_is_running()
RETURNS BOOL
AS 'MODULE_PATHNAME', 'repmgrd_is_running'
LANGUAGE C STRICT;
CREATE FUNCTION repmgrd_pause(BOOL)
RETURNS VOID
AS 'MODULE_PATHNAME', 'repmgrd_pause'
LANGUAGE C STRICT;
CREATE FUNCTION repmgrd_is_paused()
RETURNS BOOL
AS 'MODULE_PATHNAME', 'repmgrd_is_paused'
LANGUAGE C STRICT;
CREATE FUNCTION get_wal_receiver_pid()
RETURNS INT
AS 'MODULE_PATHNAME', 'repmgr_get_wal_receiver_pid'
LANGUAGE C STRICT;
/* views */
CREATE VIEW repmgr.replication_status AS
SELECT m.primary_node_id, m.standby_node_id, n.node_name AS standby_name,
n.type AS node_type, n.active, last_monitor_time,
CASE WHEN n.type='standby' THEN m.last_wal_primary_location ELSE NULL END AS last_wal_primary_location,
m.last_wal_standby_location,
CASE WHEN n.type='standby' THEN pg_catalog.pg_size_pretty(m.replication_lag) ELSE NULL END AS replication_lag,
CASE WHEN n.type='standby' THEN
CASE WHEN replication_lag > 0 THEN age(now(), m.last_apply_time) ELSE '0'::INTERVAL END
ELSE NULL
END AS replication_time_lag,
CASE WHEN n.type='standby' THEN pg_catalog.pg_size_pretty(m.apply_lag) ELSE NULL END AS apply_lag,
AGE(NOW(), CASE WHEN pg_catalog.pg_is_in_recovery() THEN repmgr.standby_get_last_updated() ELSE m.last_monitor_time END) AS communication_time_lag
FROM repmgr.monitoring_history m
JOIN repmgr.nodes n ON m.standby_node_id = n.node_id
WHERE (m.standby_node_id, m.last_monitor_time) IN (
SELECT m1.standby_node_id, MAX(m1.last_monitor_time)
FROM repmgr.monitoring_history m1 GROUP BY 1
);
/* drop old tables */
DROP TABLE repmgr.repl_nodes;
DROP TABLE repmgr.repl_monitor;
DROP TABLE repmgr.repl_events;
-- remove temporary table
DROP TABLE repmgr_old_schema;

View File

@@ -3,7 +3,7 @@
*
* Implements cluster information actions for the repmgr command line utility
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -1,6 +1,6 @@
/*
* repmgr-action-cluster.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -2,7 +2,7 @@
* repmgr-action-daemon.c
*
* Implements repmgrd actions for the repmgr command line utility
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -1,6 +1,6 @@
/*
* repmgr-action-daemon.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -3,7 +3,7 @@
*
* Implements actions available for any kind of node
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -35,7 +35,6 @@
static bool copy_file(const char *src_file, const char *dest_file);
static void format_archive_dir(PQExpBufferData *archive_dir);
static t_server_action parse_server_action(const char *action);
static const char *output_repmgrd_status(CheckStatus status);
static void exit_optformat_error(const char *error, int errcode);
@@ -53,11 +52,9 @@ static CheckStatus do_node_check_role(PGconn *conn, OutputMode mode, t_node_info
static CheckStatus do_node_check_slots(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output);
static CheckStatus do_node_check_missing_slots(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output);
static CheckStatus do_node_check_data_directory(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output);
static CheckStatus do_node_check_repmgrd(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output);
static CheckStatus do_node_check_replication_config_owner(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output);
static CheckStatus do_node_check_db_connection(PGconn *conn, OutputMode mode);
/*
* NODE STATUS
*
@@ -944,16 +941,6 @@ do_node_check(void)
exit(return_code);
}
if (runtime_options.repmgrd == true)
{
return_code = do_node_check_repmgrd(conn,
runtime_options.output_mode,
&node_info,
NULL);
PQfinish(conn);
exit(return_code);
}
if (runtime_options.replication_config_owner == true)
{
return_code = do_node_check_replication_config_owner(conn,
@@ -2037,6 +2024,7 @@ do_node_check_missing_slots(PGconn *conn, OutputMode mode, t_node_info *node_inf
return status;
}
CheckStatus
do_node_check_data_directory(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output)
{
@@ -2171,53 +2159,6 @@ do_node_check_data_directory(PGconn *conn, OutputMode mode, t_node_info *node_in
return status;
}
CheckStatus
do_node_check_repmgrd(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output)
{
CheckStatus status = CHECK_STATUS_OK;
if (mode == OM_CSV && list_output == NULL)
{
log_error(_("--csv output not provided with --repmgrd option"));
PQfinish(conn);
exit(ERR_BAD_CONFIG);
}
status = get_repmgrd_status(conn);
switch (mode)
{
case OM_OPTFORMAT:
printf("--repmgrd=%s\n",
output_check_status(status));
break;
case OM_NAGIOS:
printf("REPMGRD %s: %s\n",
output_check_status(status),
output_repmgrd_status(status));
break;
case OM_CSV:
case OM_TEXT:
if (list_output != NULL)
{
check_status_list_set(list_output,
"repmgrd",
status,
output_repmgrd_status(status));
}
else
{
printf("%s (%s)\n",
output_check_status(status),
output_repmgrd_status(status));
}
default:
break;
}
return status;
}
/*
* This is not included in the general list output
*/
@@ -2671,13 +2612,6 @@ do_node_rejoin(void)
exit(ERR_BAD_CONFIG);
}
/*
* Emit a notice about the identity of the rejoin target
*/
log_notice(_("rejoin target is node \"%s\" (ID: %i)"),
primary_node_record.node_name,
primary_node_record.node_id);
/* connect to registered primary and check it's not in recovery */
primary_conn = establish_db_connection(primary_node_record.conninfo, false);
@@ -2879,8 +2813,7 @@ do_node_rejoin(void)
log_notice(_("temporarily removing \"standby.signal\""));
log_detail(_("this is required so pg_rewind can fix the unclean shutdown"));
make_standby_signal_path(config_file_options.data_directory,
standby_signal_file_path);
make_standby_signal_path(standby_signal_file_path);
if (unlink(standby_signal_file_path) < 0 && errno != ENOENT)
{
@@ -2905,7 +2838,7 @@ do_node_rejoin(void)
* of whether the pg_rewind operation failed.
*/
log_notice(_("recreating \"standby.signal\""));
write_standby_signal(config_file_options.data_directory);
write_standby_signal();
}
if (ret == false)
@@ -3629,25 +3562,6 @@ copy_file(const char *src_file, const char *dest_file)
}
static const char *
output_repmgrd_status(CheckStatus status)
{
switch (status)
{
case CHECK_STATUS_OK:
return "repmgrd running";
case CHECK_STATUS_WARNING:
return "repmgrd running but paused";
case CHECK_STATUS_CRITICAL:
return "repmgrd not running";
case CHECK_STATUS_UNKNOWN:
return "repmgrd status unknown";
}
return "UNKNOWN";
}
void
do_node_help(void)
{
@@ -3685,12 +3599,11 @@ do_node_help(void)
printf(_(" Following options check an individual status:\n"));
printf(_(" --archive-ready number of WAL files ready for archiving\n"));
printf(_(" --downstream whether all downstream nodes are connected\n"));
printf(_(" --upstream whether the node is connected to its upstream\n"));
printf(_(" --uptream whether the node is connected to its upstream\n"));
printf(_(" --replication-lag replication lag in seconds (standbys only)\n"));
printf(_(" --role check node has expected role\n"));
printf(_(" --slots check for inactive replication slots\n"));
printf(_(" --missing-slots check for missing replication slots\n"));
printf(_(" --repmgrd check if repmgrd is running\n"));
printf(_(" --data-directory-config check repmgr's data directory configuration\n"));
puts("");
@@ -3704,7 +3617,7 @@ do_node_help(void)
printf(_(" --dry-run check that the prerequisites are met for rejoining the node\n" \
" (including usability of \"pg_rewind\" if requested)\n"));
printf(_(" --force-rewind[=VALUE] execute \"pg_rewind\" if necessary\n"));
printf(_(" (PostgreSQL 9.4 - provide full \"pg_rewind\" path)\n"));
printf(_(" (9.3 and 9.4 - provide full \"pg_rewind\" path)\n"));
printf(_(" --config-files comma-separated list of configuration files to retain\n" \
" after executing \"pg_rewind\"\n"));

View File

@@ -1,6 +1,6 @@
/*
* repmgr-action-node.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -3,7 +3,7 @@
*
* Implements primary actions for the repmgr command line utility
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -1,6 +1,6 @@
/*
* repmgr-action-primary.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -2,7 +2,7 @@
* repmgr-action-service.c
*
* Implements repmgrd actions for the repmgr command line utility
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -1,6 +1,6 @@
/*
* repmgr-action-service.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -3,7 +3,7 @@
*
* Implements standby actions for the repmgr command line utility
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -20,7 +20,6 @@
*/
#include <sys/stat.h>
#include <time.h>
#include "repmgr.h"
#include "dirutil.h"
@@ -174,6 +173,21 @@ do_standby_clone(void)
initialize_conninfo_params(&recovery_conninfo, false);
/*
* --replication-conf-only provided - we'll handle that separately
*/
if (runtime_options.replication_conf_only == true)
{
return _do_create_replication_conf();
}
/*
* conninfo params for the actual upstream node (which might be different
* to the node we're cloning from) to write to recovery.conf
*/
mode = get_standby_clone_mode();
/*
* Copy the provided data directory; if a configuration file was provided,
* use the (mandatory) value from that; if -D/--pgdata was provided, use
@@ -201,19 +215,6 @@ do_standby_clone(void)
exit(ERR_BAD_CONFIG);
}
/*
* --replication-conf-only provided - we'll handle that separately
*/
if (runtime_options.replication_conf_only == true)
{
return _do_create_replication_conf();
}
/*
* conninfo params for the actual upstream node (which might be different
* to the node we're cloning from) to write to recovery.conf
*/
mode = get_standby_clone_mode();
if (mode == barman)
{
@@ -669,15 +670,6 @@ do_standby_clone(void)
log_hint(_("consider using the -c/--fast-checkpoint option"));
}
if (mode == pg_basebackup)
{
/*
* In --dry-run mode, this will just output the pg_basebackup command which
* would be executed.
*/
run_basebackup(&local_node_record);
}
PQfinish(source_conn);
log_info(_("all prerequisites for \"standby clone\" are met"));
@@ -741,7 +733,7 @@ do_standby_clone(void)
drop_replication_slot_if_exists(source_conn, UNKNOWN_NODE_ID, local_node_record.slot_name);
}
log_error(_("unable to take a base backup of the source server"));
log_error(_("unable to take a base backup of the primary server"));
log_hint(_("data directory (\"%s\") may need to be cleaned up manually"),
local_data_directory);
@@ -771,7 +763,7 @@ do_standby_clone(void)
exit(ERR_BAD_CONFIG);
}
appendPQExpBufferChar(&command, ' ');
appendPQExpBufferStr(&command, " ");
/* Somewhat inconsistent, but pg_verifybackup doesn't accept a -D option */
appendShellString(&command,
@@ -846,16 +838,6 @@ do_standby_clone(void)
break;
}
/*
* Do a final check on the data directory permissions - if the user
* is cloning into an existing directory set to 0750, and the server
* is Pg10 or earlier, Pg will refuse to start. We might not have
* known the server version when creating the data directory
* (mainly if cloning from Barman with no upstream connection), hence
* the additional check here.
*/
set_dir_permissions(local_data_directory, source_server_version_num);
/*
* TODO: It might be nice to provide an option to have repmgr start the
* PostgreSQL server automatically
@@ -1308,64 +1290,6 @@ _do_create_replication_conf(void)
PQExpBufferData msg;
t_replication_slot slot_info = T_REPLICATION_SLOT_INITIALIZER;
/*
* Check the node record has slot_name set; if not we'll need to
* update it.
*/
if (local_node_record.slot_name[0] == '\0')
{
PGconn *primary_conn = NULL;
create_slot_name(local_node_record.slot_name, local_node_record.node_id);
/* Check we can connect to the primary so we can update the record */
if (get_recovery_type(upstream_conn) == RECTYPE_PRIMARY)
{
primary_conn = upstream_conn;
}
else
{
primary_conn = establish_primary_db_connection(upstream_conn, false);
if (primary_conn == NULL)
{
log_error(_("unable to connect to primary to update slot name for node \"%s\" (ID: %i)"),
local_node_record.node_name,
local_node_record.node_id);
PQfinish(upstream_conn);
termPQExpBuffer(&msg);
exit(ERR_BAD_CONFIG);
}
}
if (runtime_options.dry_run == true)
{
log_info(_("would set \"slot_name\" for node \"%s\" (ID: %i) to \"%s\""),
local_node_record.node_name,
local_node_record.node_id,
local_node_record.slot_name);
}
else
{
bool success = update_node_record_slot_name(primary_conn,
local_node_record.node_id,
local_node_record.slot_name);
if (primary_conn != upstream_conn)
PQfinish(primary_conn);
if (success == false)
{
log_error(_("unable to update slot name for node \"%s\" (ID: %i)"),
local_node_record.node_name,
local_node_record.node_id);
PQfinish(upstream_conn);
exit(ERR_BAD_CONFIG);
}
}
}
record_status = get_slot_record(upstream_conn, local_node_record.slot_name, &slot_info);
/* check if replication slot exists*/
@@ -1520,18 +1444,7 @@ _do_create_replication_conf(void)
if (node_is_running == true)
{
if (PQserverVersion(upstream_conn) >= 130000)
{
log_hint(_("configuration must be reloaded for the configuration changes to take effect"));
}
else if (PQserverVersion(upstream_conn) >= 120000)
{
log_hint(_("node must be restarted for the configuration changes to take effect"));
}
else
{
log_hint(_("node must be restarted for the new file to take effect"));
}
log_hint(_("node must be restarted for the new file to take effect"));
}
}
}
@@ -1546,7 +1459,7 @@ _do_create_replication_conf(void)
}
else
{
if (write_standby_signal(local_data_directory) == false)
if (write_standby_signal() == false)
{
log_error(_("unable to write \"standby.signal\" file"));
}
@@ -1998,7 +1911,7 @@ do_standby_register(void)
/*
* If --upstream-node-id not provided, we're defaulting to the primary as
* upstream node. If local node is available, double-check that it's attached
* to the primary, in case --upstream-node-id was an accidental omission.
* to the primary, in case --upstream-node-id was an accidental ommission.
*
* Currently we'll only do this for newly registered nodes.
*/
@@ -2007,7 +1920,7 @@ do_standby_register(void)
/* only do this if record does not exist */
if (record_status != RECORD_FOUND)
{
log_warning(_("--upstream-node-id not supplied, assuming upstream node is primary (node ID: %i)"),
log_warning(_("--upstream-node-id not supplied, assuming upstream node is primary (node ID %i)"),
primary_node_id);
/* check our standby is connected */
@@ -3461,7 +3374,7 @@ do_standby_follow_internal(PGconn *primary_conn, PGconn *follow_target_conn, t_n
goto cleanup;
}
/* In the unlikely event that fails, we'll fall back to a restart */
/* In the unlikley event that fails, we'll fall back to a restart */
log_warning(_("unable to reload server configuration"));
}
@@ -3652,9 +3565,8 @@ do_standby_switchover(void)
PQExpBufferData remote_command_str;
PQExpBufferData command_output;
PQExpBufferData node_rejoin_options;
PQExpBufferData logmsg;
PQExpBufferData errmsg;
PQExpBufferData detailmsg;
PQExpBufferData event_details;
int r,
i;
@@ -3671,9 +3583,6 @@ do_standby_switchover(void)
/* store list of configuration files on the demotion candidate */
KeyValueList remote_config_files = {NULL, NULL};
/* temporary log file for "repmgr node rejoin" on the demotion candidate */
char node_rejoin_log[MAXPGPATH] = "";
NodeInfoList sibling_nodes = T_NODE_INFO_LIST_INITIALIZER;
SiblingNodeStats sibling_nodes_stats = T_SIBLING_NODES_STATS_INITIALIZER;
@@ -3696,7 +3605,7 @@ do_standby_switchover(void)
* SANITY CHECKS
*
* We'll be doing a bunch of operations on the remote server (primary to
* be demoted) - careful checks needed before proceeding.
* be demoted) - careful checks needed before proceding.
*/
local_conn = establish_db_connection(config_file_options.conninfo, true);
@@ -3816,24 +3725,24 @@ do_standby_switchover(void)
* the demotion candidate as the rejoin will fail if we are unable to to write to that.
*/
initPQExpBuffer(&logmsg);
initPQExpBuffer(&errmsg);
initPQExpBuffer(&detailmsg);
if (check_replication_config_owner(PQserverVersion(local_conn),
config_file_options.data_directory,
&logmsg, &detailmsg) == false)
&errmsg, &detailmsg) == false)
{
log_error("%s", logmsg.data);
log_error("%s", errmsg.data);
log_detail("%s", detailmsg.data);
termPQExpBuffer(&logmsg);
termPQExpBuffer(&errmsg);
termPQExpBuffer(&detailmsg);
PQfinish(local_conn);
exit(ERR_BAD_CONFIG);
}
termPQExpBuffer(&logmsg);
termPQExpBuffer(&errmsg);
termPQExpBuffer(&detailmsg);
/* check remote server connection and retrieve its record */
@@ -4178,7 +4087,7 @@ do_standby_switchover(void)
if (command_success == false || command_output.data[0] == '0')
{
log_error(_("expected configuration file not found on the demotion candidate \"%s\" (ID: %i)"),
log_error(_("expected configuration file not found on the demotion candiate \"%s\" (ID: %i)"),
remote_node_record.node_name,
remote_node_record.node_id);
log_detail(_("registered configuration file is \"%s\""),
@@ -4278,7 +4187,7 @@ do_standby_switchover(void)
else if (remote_error == REMOTE_ERROR_CONNINFO_PARSE)
{
/* highly unlikely */
log_detail(_("an error was encountered when parsing the \"conninfo\" parameter in \"repmgr.conf\" on node \"%s\" (ID: %i)"),
log_detail(_("an error was encountered when parsing the \"conninfo\" parameter in \"rempgr.conf\" on node \"%s\" (ID: %i)"),
remote_node_record.node_name,
remote_node_record.node_id);
}
@@ -4781,7 +4690,6 @@ do_standby_switchover(void)
repmgrd_info = (RepmgrdInfo **) pg_malloc0(sizeof(RepmgrdInfo *) * all_nodes.node_count);
log_notice(_("attempting to pause repmgrd on %i nodes"), all_nodes.node_count);
for (cell = all_nodes.head; cell; cell = cell->next)
{
repmgrd_info[i] = pg_malloc0(sizeof(RepmgrdInfo));
@@ -4810,7 +4718,7 @@ do_standby_switchover(void)
unreachable_node_count++;
item_list_append_format(&repmgrd_connection_errors,
_("unable to connect to node \"%s\" (ID: %i):\n%s"),
_("unable to connect to node \"%s\" (ID %i):\n%s"),
cell->node_info->node_name,
cell->node_info->node_id,
PQerrorMessage(cell->node_info->conn));
@@ -4841,9 +4749,8 @@ do_standby_switchover(void)
initPQExpBuffer(&msg);
appendPQExpBuffer(&msg,
_("unable to connect to %i of %i node(s), unable to pause all repmgrd instances"),
unreachable_node_count,
all_nodes.node_count);
_("unable to connect to %i node(s), unable to pause all repmgrd instances"),
unreachable_node_count);
initPQExpBuffer(&detail);
@@ -4894,7 +4801,7 @@ do_standby_switchover(void)
*/
if (repmgrd_info[i]->pg_running == false)
{
log_warning(_("node \"%s\" (ID: %i) unreachable, unable to pause repmgrd"),
log_warning(_("node \"%s\" (ID %i) unreachable, unable to pause repmgrd"),
cell->node_info->node_name,
cell->node_info->node_id);
i++;
@@ -4907,7 +4814,7 @@ do_standby_switchover(void)
*/
if (repmgrd_info[i]->running == false)
{
log_notice(_("repmgrd not running on node \"%s\" (ID: %i), not pausing"),
log_warning(_("repmgrd not running on node \"%s\" (ID %i)"),
cell->node_info->node_name,
cell->node_info->node_id);
i++;
@@ -4928,14 +4835,14 @@ do_standby_switchover(void)
if (runtime_options.dry_run == true)
{
log_info(_("would pause repmgrd on node \"%s\" (ID: %i)"),
log_info(_("would pause repmgrd on node \"%s\" (ID %i)"),
cell->node_info->node_name,
cell->node_info->node_id);
}
else
{
/* XXX check result */
log_debug("pausing repmgrd on node \"%s\" (ID: %i)",
log_debug("pausing repmgrd on node \"%s\" (ID %i)",
cell->node_info->node_name,
cell->node_info->node_id);
@@ -5235,18 +5142,6 @@ do_standby_switchover(void)
format_lsn(replication_info.last_wal_receive_lsn),
format_lsn(remote_last_checkpoint_lsn));
/*
* optionally add a delay before promoting the standby; this is mainly
* useful for testing (e.g. for reappearance of the original primary) and
* is not documented.
*/
if (config_file_options.promote_delay > 0)
{
log_debug("sleeping %i seconds before promoting standby",
config_file_options.promote_delay);
sleep(config_file_options.promote_delay);
}
/*
* Promote standby (local node).
*
@@ -5372,21 +5267,6 @@ do_standby_switchover(void)
pfree(conninfo_normalized);
}
/* */
snprintf(node_rejoin_log, MAXPGPATH,
#if defined(__i386__) || defined(__i386)
"/tmp/node-rejoin.%u.log",
(unsigned)time(NULL)
#else
"/tmp/node-rejoin.%lu.log",
(unsigned long)time(NULL)
#endif
);
appendPQExpBuffer(&remote_command_str,
" > %s 2>&1 && echo \"1\" || echo \"0\"",
node_rejoin_log);
termPQExpBuffer(&node_rejoin_options);
log_debug("executing:\n %s", remote_command_str.data);
@@ -5400,161 +5280,78 @@ do_standby_switchover(void)
termPQExpBuffer(&remote_command_str);
initPQExpBuffer(&logmsg);
initPQExpBuffer(&detailmsg);
/* TODO: verify this node's record was updated correctly */
/* This is failure to execute the ssh command */
if (command_success == false)
{
log_error(_("rejoin failed with error code %i"), r);
switchover_success = false;
appendPQExpBuffer(&logmsg,
_("unable to execute \"repmgr node rejoin\" on demotion candidate \"%s\" (ID: %i)"),
remote_node_record.node_name,
remote_node_record.node_id);
appendPQExpBufferStr(&detailmsg,
command_output.data);
create_event_notification_extended(local_conn,
&config_file_options,
config_file_options.node_id,
"standby_switchover",
false,
command_output.data,
&event_info);
}
else
{
standy_join_status join_success = JOIN_UNKNOWN;
PQExpBufferData event_details;
standy_join_status join_success = check_standby_join(local_conn,
&local_node_record,
&remote_node_record);
/* "rempgr node rejoin" failed on the demotion candidate */
if (command_output.data[0] == '0')
initPQExpBuffer(&event_details);
switch (join_success) {
case JOIN_FAIL_NO_PING:
appendPQExpBuffer(&event_details,
_("node \"%s\" (ID: %i) promoted to primary, but demote node \"%s\" (ID: %i) did not beome available"),
config_file_options.node_name,
config_file_options.node_id,
remote_node_record.node_name,
remote_node_record.node_id);
switchover_success = false;
break;
case JOIN_FAIL_NO_REPLICATION:
appendPQExpBuffer(&event_details,
_("node \"%s\" (ID: %i) promoted to primary, but demote node \"%s\" (ID: %i) did not connect to the new primary"),
config_file_options.node_name,
config_file_options.node_id,
remote_node_record.node_name,
remote_node_record.node_id);
switchover_success = false;
break;
case JOIN_SUCCESS:
appendPQExpBuffer(&event_details,
_("node \"%s\" (ID: %i) promoted to primary, node \"%s\" (ID: %i) demoted to standby"),
config_file_options.node_name,
config_file_options.node_id,
remote_node_record.node_name,
remote_node_record.node_id);
}
create_event_notification_extended(local_conn,
&config_file_options,
config_file_options.node_id,
"standby_switchover",
switchover_success,
event_details.data,
&event_info);
if (switchover_success == true)
{
appendPQExpBuffer(&logmsg,
_("execution of \"repmgr node rejoin\" on demotion candidate \"%s\" (ID: %i) failed"),
remote_node_record.node_name,
remote_node_record.node_id);
/*
* Speculatively check if the demotion candidate has been restarted, e.g. by
* an external watchdog process which isn't aware a switchover is happening.
* This falls into the category "thing outside of our control which shouldn't
* happen, but if it does, make it easier to find out what happened".
*/
remote_conn = establish_db_connection(remote_node_record.conninfo, false);
if (PQstatus(remote_conn) == CONNECTION_OK)
{
if (get_recovery_type(remote_conn) == RECTYPE_PRIMARY)
{
appendPQExpBuffer(&detailmsg,
_("PostgreSQL instance on demotion candidate \"%s\" (ID: %i) is running as a primary\n"),
remote_node_record.node_name,
remote_node_record.node_id);
log_warning("%s", detailmsg.data);
}
}
PQfinish(remote_conn);
appendPQExpBuffer(&detailmsg,
"check log file \"%s\" on \"%s\" for details",
node_rejoin_log,
remote_node_record.node_name);
switchover_success = false;
join_success = JOIN_COMMAND_FAIL;
log_notice("%s", event_details.data);
}
else
{
join_success = check_standby_join(local_conn,
&local_node_record,
&remote_node_record);
switch (join_success) {
case JOIN_FAIL_NO_PING:
appendPQExpBuffer(&logmsg,
_("node \"%s\" (ID: %i) promoted to primary, but demotion candidate \"%s\" (ID: %i) did not become available"),
config_file_options.node_name,
config_file_options.node_id,
remote_node_record.node_name,
remote_node_record.node_id);
switchover_success = false;
break;
case JOIN_FAIL_NO_REPLICATION:
appendPQExpBuffer(&logmsg,
_("node \"%s\" (ID: %i) promoted to primary, but demotion candidate \"%s\" (ID: %i) did not connect to the new primary"),
config_file_options.node_name,
config_file_options.node_id,
remote_node_record.node_name,
remote_node_record.node_id);
switchover_success = false;
break;
case JOIN_SUCCESS:
appendPQExpBuffer(&logmsg,
_("node \"%s\" (ID: %i) promoted to primary, node \"%s\" (ID: %i) demoted to standby"),
config_file_options.node_name,
config_file_options.node_id,
remote_node_record.node_name,
remote_node_record.node_id);
break;
/* check_standby_join() does not return this */
case JOIN_COMMAND_FAIL:
break;
/* should never happen*/
case JOIN_UNKNOWN:
appendPQExpBuffer(&logmsg,
"unable to determine success of node rejoin action for demotion candidate \"%s\" (ID: %i)",
remote_node_record.node_name,
remote_node_record.node_id);
switchover_success = false;
break;
}
if (switchover_success == false)
{
appendPQExpBuffer(&detailmsg,
"check the PostgreSQL log file on demotion candidate \"%s\" (ID: %i)",
remote_node_record.node_name,
remote_node_record.node_id);
}
log_error("%s", event_details.data);
}
termPQExpBuffer(&event_details);
}
if (switchover_success == true)
{
/* TODO: verify demotion candidates's node record was updated correctly */
log_notice("%s", logmsg.data);
}
else
{
log_error("%s", logmsg.data);
}
initPQExpBuffer(&event_details);
appendPQExpBufferStr(&event_details, logmsg.data);
if (detailmsg.data[0] != '\0')
{
log_detail("%s", detailmsg.data);
appendPQExpBuffer(&event_details, "\n%s",
detailmsg.data);
}
create_event_notification_extended(local_conn,
&config_file_options,
config_file_options.node_id,
"standby_switchover",
switchover_success,
event_details.data,
&event_info);
termPQExpBuffer(&event_details);
termPQExpBuffer(&logmsg);
termPQExpBuffer(&detailmsg);
termPQExpBuffer(&command_output);
/*
* If --siblings-follow specified, attempt to make them follow the new
* primary
@@ -5667,7 +5464,7 @@ do_standby_switchover(void)
if (repmgrd_info[i]->paused == true && runtime_options.repmgrd_force_unpause == false)
{
log_debug("repmgrd on node \"%s\" (ID: %i) paused before switchover, --repmgrd-force-unpause not provided, not unpausing",
log_debug("repmgrd on node \"%s\" (ID %i) paused before switchover, --repmgrd-force-unpause not provided, not unpausing",
cell->node_info->node_name,
cell->node_info->node_id);
@@ -5675,7 +5472,7 @@ do_standby_switchover(void)
continue;
}
log_debug("unpausing repmgrd on node \"%s\" (ID: %i)",
log_debug("unpausing repmgrd on node \"%s\" (ID %i)",
cell->node_info->node_name,
cell->node_info->node_id);
@@ -5686,7 +5483,7 @@ do_standby_switchover(void)
if (repmgrd_pause(cell->node_info->conn, false) == false)
{
item_list_append_format(&repmgrd_unpause_errors,
_("unable to unpause node \"%s\" (ID: %i)"),
_("unable to unpause node \"%s\" (ID %i)"),
cell->node_info->node_name,
cell->node_info->node_id);
error_node_count++;
@@ -5695,7 +5492,7 @@ do_standby_switchover(void)
else
{
item_list_append_format(&repmgrd_unpause_errors,
_("unable to connect to node \"%s\" (ID: %i):\n%s"),
_("unable to connect to node \"%s\" (ID %i):\n%s"),
cell->node_info->node_name,
cell->node_info->node_id,
PQerrorMessage(cell->node_info->conn));
@@ -6979,13 +6776,6 @@ run_basebackup(t_node_info *node_record)
termPQExpBuffer(&params);
if (runtime_options.dry_run == true)
{
log_info(_("would execute:\n %s"), script.data);
termPQExpBuffer(&script);
return SUCCESS;
}
log_info(_("executing:\n %s"), script.data);
/*
@@ -7719,7 +7509,7 @@ stop_backup:
if (record_status == RECORD_FOUND)
{
log_verbose(LOG_INFO,
_("replication slot \"%s\" already exists on upstream node %i"),
_("replication slot \"%s\" aleady exists on upstream node %i"),
local_node_record->slot_name,
upstream_node_id);
}
@@ -7972,9 +7762,7 @@ static void
tablespace_data_append(TablespaceDataList *list, const char *name, const char *oid, const char *location)
{
TablespaceDataListCell *cell = NULL;
int oid_len = strlen(oid);
int name_len = strlen(name);
int location_len = strlen(location);
cell = (TablespaceDataListCell *) pg_malloc0(sizeof(TablespaceDataListCell));
if (cell == NULL)
@@ -7983,13 +7771,13 @@ tablespace_data_append(TablespaceDataList *list, const char *name, const char *o
exit(ERR_OUT_OF_MEMORY);
}
cell->oid = pg_malloc0(1 + oid_len);
cell->name = pg_malloc0(1 + name_len);
cell->location = pg_malloc0(1 + location_len);
cell->oid = pg_malloc(1 + strlen(oid));
cell->name = pg_malloc(1 + strlen(name));
cell->location = pg_malloc(1 + strlen(location));
strncpy(cell->oid, oid, oid_len);
strncpy(cell->name, name, name_len);
strncpy(cell->location, location, location_len);
strncpy(cell->oid, oid, 1 + strlen(oid));
strncpy(cell->name, name, 1 + strlen(name));
strncpy(cell->location, location, 1 + strlen(location));
if (list->tail)
list->tail->next = cell;
@@ -8149,9 +7937,9 @@ create_recovery_file(t_node_info *node_record, t_conninfo_param_list *primary_co
free(escaped);
}
/*
* Caller requests the generated file to be written into a buffer
*/
if (as_file == false)
{
/* create file in buffer */
@@ -8171,17 +7959,20 @@ create_recovery_file(t_node_info *node_record, t_conninfo_param_list *primary_co
return true;
}
/*
* PostgreSQL 12 and later: modify postgresql.auto.conf
*
*/
if (server_version_num >= 120000)
{
if (modify_auto_conf(dest, &recovery_config) == false)
{
return false;
}
if (write_standby_signal(dest) == false)
if (write_standby_signal() == false)
{
return false;
}
@@ -9120,8 +8911,6 @@ do_standby_help(void)
#endif
printf(_(" --without-barman do not clone from Barman even if configured\n"));
printf(_(" --replication-conf-only generate replication configuration for a previously cloned instance\n"));
printf(_(" --recovery-min-apply-delay set PostgreSQL configuration parameter \"recovery_min_apply_delay\"\n" \
" (overrides any setting in repmgr.conf)\n"));
puts("");
@@ -9174,7 +8963,7 @@ do_standby_help(void)
printf(_(" --dry-run perform checks etc. but don't actually execute switchover\n"));
printf(_(" -F, --force ignore warnings and continue anyway\n"));
printf(_(" --force-rewind[=VALUE] use \"pg_rewind\" to reintegrate the old primary if necessary\n"));
printf(_(" (PostgreSQL 9.4 - provide \"pg_rewind\" path)\n"));
printf(_(" (9.3 and 9.4 - provide \"pg_rewind\" path)\n"));
printf(_(" -R, --remote-user=USERNAME database server username for SSH operations (default: \"%s\")\n"), runtime_options.username);
printf(_(" -S, --superuser=USERNAME superuser to use, if repmgr user is not superuser\n"));

View File

@@ -1,6 +1,6 @@
/*
* repmgr-action-standby.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -3,7 +3,7 @@
*
* Implements witness actions for the repmgr command line utility
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -560,7 +560,7 @@ void do_witness_help(void)
printf(_("WITNESS UNREGISTER\n"));
puts("");
printf(_(" \"witness unregister\" unregisters a witness node.\n"));
printf(_(" \"witness register\" unregisters a witness node.\n"));
puts("");
printf(_(" --dry-run check prerequisites but don't make any changes\n"));
printf(_(" -F, --force unregister when witness node not running\n"));

View File

@@ -1,6 +1,6 @@
/*
* repmgr-action-witness.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -1,6 +1,6 @@
/*
* repmgr-client-global.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -84,7 +84,7 @@ typedef struct
bool fast_checkpoint;
bool rsync_only;
bool no_upstream_connection;
char recovery_min_apply_delay[MAXLEN]; /* overrides setting in repmgr.conf */
char recovery_min_apply_delay[MAXLEN];
char replication_user[MAXLEN];
char upstream_conninfo[MAXLEN];
bool without_barman;
@@ -120,7 +120,6 @@ typedef struct
bool missing_slots;
bool has_passfile;
bool replication_connection;
bool repmgrd;
bool data_directory_config;
bool replication_config_owner;
bool db_connection;
@@ -176,7 +175,7 @@ typedef struct
/* "node status" options */ \
false, \
/* "node check" options */ \
false, false, false, false, false, false, false, false, false, false, false, false, false, \
false, false, false, false, false, false, false, false, false, false, false, false, \
/* "node rejoin" options */ \
"", \
/* "node service" options */ \
@@ -220,9 +219,7 @@ typedef enum
typedef enum
{
JOIN_UNKNOWN = -1,
JOIN_SUCCESS,
JOIN_COMMAND_FAIL,
JOIN_FAIL_NO_PING,
JOIN_FAIL_NO_REPLICATION
} standy_join_status;
@@ -285,8 +282,8 @@ extern void get_node_config_directory(char *config_dir_buf);
extern void get_node_data_directory(char *data_dir_buf);
extern void init_node_record(t_node_info *node_record);
extern bool can_use_pg_rewind(PGconn *conn, const char *data_directory, PQExpBufferData *reason);
extern void make_standby_signal_path(const char *data_dir, char *buf);
extern bool write_standby_signal(const char *data_dir);
extern void make_standby_signal_path(char *buf);
extern bool write_standby_signal(void);
extern bool create_replication_slot(PGconn *conn, char *slot_name, t_node_info *upstream_node_record, PQExpBufferData *error_msg);
extern bool drop_replication_slot_if_exists(PGconn *conn, int node_id, char *slot_name);

View File

@@ -1,7 +1,7 @@
/*
* repmgr-client.c - Command interpreter for the repmgr package
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* Copyright (c) 2ndQuadrant, 2010-2020
*
* This module is a command-line utility to easily setup a cluster of
* hot standby servers for an HA environment
@@ -51,7 +51,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <pwd.h>
#include <unistd.h>
#include <sys/stat.h>
#include <signal.h>
@@ -123,7 +122,7 @@ main(int argc, char **argv)
/*
* Tell the logger we're a command-line program - this will ensure any
* output logged before the logger is initialized will be formatted
* correctly. Can be overridden with "--log-to-file".
* correctly. Can be overriden with "--log-to-file".
*/
logger_output_mode = OM_COMMAND_LINE;
@@ -439,11 +438,6 @@ main(int argc, char **argv)
runtime_options.replication_conf_only = true;
break;
/* --recovery-min-apply-delay */
case OPT_RECOVERY_MIN_APPLY_DELAY:
strncpy(runtime_options.recovery_min_apply_delay, optarg, sizeof(runtime_options.recovery_min_apply_delay));
break;
/* --verify-backup */
case OPT_VERIFY_BACKUP:
runtime_options.verify_backup = true;
@@ -550,10 +544,6 @@ main(int argc, char **argv)
runtime_options.data_directory_config = true;
break;
case OPT_REPMGRD:
runtime_options.repmgrd = true;
break;
case OPT_REPLICATION_CONFIG_OWNER:
runtime_options.replication_config_owner = true;
break;
@@ -1115,25 +1105,10 @@ main(int argc, char **argv)
exit(SUCCESS);
}
check_cli_parameters(action);
/*
* Command-line parameter --recovery-min-apply-delay overrides the equivalent
* setting in the config file. Note we'll need to parse it here to handle
* any formatting errors.
*/
if (*runtime_options.recovery_min_apply_delay != '\0')
{
parse_time_unit_parameter("--recovery-min-apply-delay",
runtime_options.recovery_min_apply_delay,
config_file_options.recovery_min_apply_delay,
&cli_errors);
config_file_options.recovery_min_apply_delay_provided = true;
}
/*
* Sanity checks for command line parameters completed by now; any further
* errors will be runtime ones
@@ -1194,7 +1169,7 @@ main(int argc, char **argv)
}
/*
* Check for configuration file items which can be overridden by runtime
* Check for configuration file items which can be overriden by runtime
* options
* =====================================================================
*/
@@ -2740,7 +2715,7 @@ do_help(void)
*
* Note:
* This is one of two places where superuser rights are required.
* We should also consider possible scenarios where a non-superuser
* We should also consider possible scenarious where a non-superuser
* has sufficient privileges to install the extension.
*/
@@ -2775,7 +2750,7 @@ create_repmgr_extension(PGconn *conn)
log_detail(_("version %s is installed but newer version %s is available"),
extversions.installed_version,
extversions.default_version);
log_hint(_("update the installed extension version by executing \"ALTER EXTENSION repmgr UPDATE\" in the repmgr database"));
log_hint(_("update the installed extension version by executing \"ALTER EXTENSION repmgr UPDATE\""));
return false;
case REPMGR_INSTALLED:
@@ -2941,7 +2916,7 @@ check_server_version(PGconn *conn, char *server_type, bool exit_on_error, char *
* PostgreSQL from a particular PostgreSQL release onwards (e.g. 4.4 with PostgreSQL
* 12 and later due to recovery.conf removal), set MAX_UNSUPPORTED_VERSION and
* MAX_UNSUPPORTED_VERSION_NUM in "repmgr.h" to define the first PostgreSQL
* version which can't be supported.
* version which can't be suppored.
*/
#ifdef MAX_UNSUPPORTED_VERSION_NUM
if (conn_server_version_num >= MAX_UNSUPPORTED_VERSION_NUM)
@@ -3666,11 +3641,11 @@ can_use_pg_rewind(PGconn *conn, const char *data_directory, PQExpBufferData *rea
void
make_standby_signal_path(const char *data_dir, char *buf)
make_standby_signal_path(char *buf)
{
snprintf(buf, MAXPGPATH,
"%s/%s",
data_dir,
config_file_options.data_directory,
STANDBY_SIGNAL_FILE);
}
@@ -3678,15 +3653,13 @@ make_standby_signal_path(const char *data_dir, char *buf)
* create standby.signal (PostgreSQL 12 and later)
*/
bool
write_standby_signal(const char *data_dir)
write_standby_signal(void)
{
char standby_signal_file_path[MAXPGPATH] = "";
FILE *file;
mode_t um;
Assert(data_dir != NULL);
make_standby_signal_path(data_dir, standby_signal_file_path);
make_standby_signal_path(standby_signal_file_path);
/* Set umask to 0600 */
um = umask((~(S_IRUSR | S_IWUSR)) & (S_IRWXG | S_IRWXO));
@@ -4093,7 +4066,7 @@ check_standby_join(PGconn *upstream_conn, t_node_info *upstream_node_record, t_n
if (node_attached == NODE_NOT_ATTACHED)
{
log_detail(_("node \"%s\" (ID: %i) is currently attached to its upstream node in state \"%s\""),
log_detail(_("node \"%s\" (ID: %i) is currrently attached to its upstream node in state \"%s\""),
upstream_node_record->node_name,
standby_node_record->node_id,
node_state);

View File

@@ -1,6 +1,6 @@
/*
* repmgr-client.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -99,8 +99,6 @@
#define OPT_REPLICATION_CONFIG_OWNER 1046
#define OPT_DB_CONNECTION 1047
#define OPT_VERIFY_BACKUP 1048
#define OPT_RECOVERY_MIN_APPLY_DELAY 1049
#define OPT_REPMGRD 1050
/* These options are for internal use only */
#define OPT_CONFIG_ARCHIVE_DIR 2001
@@ -166,7 +164,6 @@ static struct option long_options[] =
{"without-barman", no_argument, NULL, OPT_WITHOUT_BARMAN},
{"replication-conf-only", no_argument, NULL, OPT_REPLICATION_CONF_ONLY},
{"verify-backup", no_argument, NULL, OPT_VERIFY_BACKUP },
{"recovery-min-apply-delay", required_argument, NULL, OPT_RECOVERY_MIN_APPLY_DELAY },
/* deprecate this once Pg11 and earlier are unsupported */
{"recovery-conf-only", no_argument, NULL, OPT_REPLICATION_CONF_ONLY},
@@ -194,7 +191,6 @@ static struct option long_options[] =
{"role", no_argument, NULL, OPT_ROLE},
{"slots", no_argument, NULL, OPT_SLOTS},
{"missing-slots", no_argument, NULL, OPT_MISSING_SLOTS},
{"repmgrd", no_argument, NULL, OPT_REPMGRD},
{"has-passfile", no_argument, NULL, OPT_HAS_PASSFILE},
{"replication-connection", no_argument, NULL, OPT_REPL_CONN},
{"data-directory-config", no_argument, NULL, OPT_DATA_DIRECTORY_CONFIG},

View File

@@ -1,7 +1,7 @@
/*
* repmgr.c - repmgr extension
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* Copyright (c) 2ndQuadrant, 2010-2020
*
* This is the actual extension code; see repmgr-client.c for the code which
* generates the repmgr binary
@@ -88,24 +88,59 @@ void _PG_fini(void);
static void repmgr_shmem_startup(void);
PG_FUNCTION_INFO_V1(repmgr_set_local_node_id);
PG_FUNCTION_INFO_V1(repmgr_get_local_node_id);
PG_FUNCTION_INFO_V1(repmgr_standby_set_last_updated);
PG_FUNCTION_INFO_V1(repmgr_standby_get_last_updated);
PG_FUNCTION_INFO_V1(repmgr_set_upstream_last_seen);
PG_FUNCTION_INFO_V1(repmgr_get_upstream_last_seen);
PG_FUNCTION_INFO_V1(repmgr_get_upstream_node_id);
PG_FUNCTION_INFO_V1(repmgr_set_upstream_node_id);
PG_FUNCTION_INFO_V1(repmgr_notify_follow_primary);
PG_FUNCTION_INFO_V1(repmgr_get_new_primary);
PG_FUNCTION_INFO_V1(repmgr_reset_voting_status);
Datum set_local_node_id(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(set_local_node_id);
Datum get_local_node_id(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(get_local_node_id);
Datum standby_set_last_updated(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(standby_set_last_updated);
Datum standby_get_last_updated(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(standby_get_last_updated);
Datum set_upstream_last_seen(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(set_upstream_last_seen);
Datum get_upstream_last_seen(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(get_upstream_last_seen);
Datum get_upstream_node_id(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(get_upstream_node_id);
Datum set_upstream_node_id(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(set_upstream_node_id);
Datum notify_follow_primary(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(notify_follow_primary);
Datum get_new_primary(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(get_new_primary);
Datum reset_voting_status(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(reset_voting_status);
Datum set_repmgrd_pid(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(set_repmgrd_pid);
Datum get_repmgrd_pid(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(get_repmgrd_pid);
Datum get_repmgrd_pidfile(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(get_repmgrd_pidfile);
Datum repmgrd_is_running(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(repmgrd_is_running);
Datum repmgrd_pause(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(repmgrd_pause);
Datum repmgrd_is_paused(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(repmgrd_is_paused);
PG_FUNCTION_INFO_V1(repmgr_get_wal_receiver_pid);
Datum get_wal_receiver_pid(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(get_wal_receiver_pid);
/*
@@ -159,7 +194,7 @@ repmgr_shmem_startup(void)
shared_state = NULL;
/*
* Create or attach to the shared memory state
* Create or attach to the shared memory state, including hash table
*/
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
@@ -198,7 +233,7 @@ repmgr_shmem_startup(void)
/* ==================== */
Datum
repmgr_set_local_node_id(PG_FUNCTION_ARGS)
set_local_node_id(PG_FUNCTION_ARGS)
{
int local_node_id = UNKNOWN_NODE_ID;
int stored_node_id = UNKNOWN_NODE_ID;
@@ -268,7 +303,7 @@ repmgr_set_local_node_id(PG_FUNCTION_ARGS)
Datum
repmgr_get_local_node_id(PG_FUNCTION_ARGS)
get_local_node_id(PG_FUNCTION_ARGS)
{
int local_node_id = UNKNOWN_NODE_ID;
@@ -285,7 +320,7 @@ repmgr_get_local_node_id(PG_FUNCTION_ARGS)
/* update and return last updated with current timestamp */
Datum
repmgr_standby_set_last_updated(PG_FUNCTION_ARGS)
standby_set_last_updated(PG_FUNCTION_ARGS)
{
TimestampTz last_updated = GetCurrentTimestamp();
@@ -302,7 +337,7 @@ repmgr_standby_set_last_updated(PG_FUNCTION_ARGS)
/* get last updated timestamp */
Datum
repmgr_standby_get_last_updated(PG_FUNCTION_ARGS)
standby_get_last_updated(PG_FUNCTION_ARGS)
{
TimestampTz last_updated;
@@ -319,7 +354,7 @@ repmgr_standby_get_last_updated(PG_FUNCTION_ARGS)
Datum
repmgr_set_upstream_last_seen(PG_FUNCTION_ARGS)
set_upstream_last_seen(PG_FUNCTION_ARGS)
{
int upstream_node_id = UNKNOWN_NODE_ID;
@@ -342,7 +377,7 @@ repmgr_set_upstream_last_seen(PG_FUNCTION_ARGS)
Datum
repmgr_get_upstream_last_seen(PG_FUNCTION_ARGS)
get_upstream_last_seen(PG_FUNCTION_ARGS)
{
long secs;
int microsecs;
@@ -376,7 +411,7 @@ repmgr_get_upstream_last_seen(PG_FUNCTION_ARGS)
Datum
repmgr_get_upstream_node_id(PG_FUNCTION_ARGS)
get_upstream_node_id(PG_FUNCTION_ARGS)
{
int upstream_node_id = UNKNOWN_NODE_ID;
@@ -391,7 +426,7 @@ repmgr_get_upstream_node_id(PG_FUNCTION_ARGS)
}
Datum
repmgr_set_upstream_node_id(PG_FUNCTION_ARGS)
set_upstream_node_id(PG_FUNCTION_ARGS)
{
int upstream_node_id = UNKNOWN_NODE_ID;
int local_node_id = UNKNOWN_NODE_ID;
@@ -427,7 +462,7 @@ repmgr_set_upstream_node_id(PG_FUNCTION_ARGS)
Datum
repmgr_notify_follow_primary(PG_FUNCTION_ARGS)
notify_follow_primary(PG_FUNCTION_ARGS)
{
int primary_node_id = UNKNOWN_NODE_ID;
@@ -470,7 +505,7 @@ repmgr_notify_follow_primary(PG_FUNCTION_ARGS)
Datum
repmgr_get_new_primary(PG_FUNCTION_ARGS)
get_new_primary(PG_FUNCTION_ARGS)
{
int new_primary_node_id = UNKNOWN_NODE_ID;
@@ -492,7 +527,7 @@ repmgr_get_new_primary(PG_FUNCTION_ARGS)
Datum
repmgr_reset_voting_status(PG_FUNCTION_ARGS)
reset_voting_status(PG_FUNCTION_ARGS)
{
if (!shared_state)
PG_RETURN_NULL();
@@ -700,7 +735,7 @@ repmgrd_is_paused(PG_FUNCTION_ARGS)
Datum
repmgr_get_wal_receiver_pid(PG_FUNCTION_ARGS)
get_wal_receiver_pid(PG_FUNCTION_ARGS)
{
int wal_receiver_pid;

View File

@@ -69,7 +69,7 @@
#------------------------------------------------------------------------------
#replication_user='repmgr' # User to make replication connections with, if not set
# defaults to the user defined in "conninfo".
# defaults to the user defined in "conninfo".
#replication_type='physical' # Must "physical" (the default).
@@ -238,7 +238,7 @@ ssh_options='-q -o ConnectTimeout=10' # Options to append to "ssh"
#primary_follow_timeout=60 # The max length of time (in seconds) to wait
# for the new primary to become available
#standby_follow_timeout=30 # The max length of time (in seconds) to wait
#standby_follow_timeout=15 # The max length of time (in seconds) to wait
# for the standby to connect to the primary
#standby_follow_restart=false # Restart the standby instead of sending a SIGHUP
# (only for PostgreSQL 13 and later)
@@ -301,7 +301,7 @@ ssh_options='-q -o ConnectTimeout=10' # Options to append to "ssh"
#connection_check_type=ping # How to check availability of the upstream node; valid options:
# 'ping': use PQping() to check if the node is accepting connections
# 'connection': attempt to make a new connection to the node
# 'connection': execute a throwaway query on the current connection
# 'query': execute an SQL statement on the node via the existing connection
#reconnect_attempts=6 # Number of attempts which will be made to reconnect to an unreachable
# primary (or other upstream node)
@@ -314,7 +314,7 @@ ssh_options='-q -o ConnectTimeout=10' # Options to append to "ssh"
#follow_command='' # command repmgrd executes when instructing a standby to follow a new primary;
# use something like:
#
# repmgr standby follow -f /etc/repmgr.conf --upstream-node-id=%n
# repmgr standby follow -f /etc/repmgr.conf -W --upstream-node-id=%n
#
#primary_notification_timeout=60 # Interval (in seconds) which repmgrd on a standby
# will wait for a notification from the new primary,
@@ -323,7 +323,7 @@ ssh_options='-q -o ConnectTimeout=10' # Options to append to "ssh"
# for the the local node to restart and become ready to accept connections after
# executing "follow_command" (defaults to the value set in "standby_reconnect_timeout")
#monitoring_history=no # Whether to write monitoring data to the "monitoring_history" table
#monitoring_history=no # Whether to write monitoring data to the "montoring_history" table
#monitor_interval_secs=2 # Interval (in seconds) at which to write monitoring data
#degraded_monitoring_timeout=-1 # Interval (in seconds) after which repmgrd will terminate if the
# server(s) being monitored are no longer available. -1 (default)
@@ -337,7 +337,6 @@ ssh_options='-q -o ConnectTimeout=10' # Options to append to "ssh"
# "--no-pid-file" will force PID file creation to be skipped.
# Note: there is normally no need to set this, particularly if
# repmgr was installed from packages.
#repmgrd_exit_on_inactive_node=false # If "true", and the node record is marked as "inactive", abort repmgrd startup
#standby_disconnect_on_failover=false # If "true", in a failover situation wait for all standbys to
# disconnect their WAL receivers before electing a new primary
# (PostgreSQL 9.5 and later only; repmgr user must be a superuser for this)

View File

@@ -1,7 +1,8 @@
# repmgr extension
comment = 'Replication manager for PostgreSQL'
default_version = '5.3'
default_version = '5.2'
module_pathname = '$libdir/repmgr'
relocatable = false
schema = repmgr

View File

@@ -1,6 +1,6 @@
/*
* repmgr.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -77,6 +77,8 @@
#define MIN_SUPPORTED_VERSION "9.4"
#define MIN_SUPPORTED_VERSION_NUM 90400
#define REPLICATION_TYPE_PHYSICAL 1
#define UNKNOWN_SERVER_VERSION_NUM -1
#define UNKNOWN_REPMGR_VERSION_NUM -1
@@ -120,7 +122,6 @@
#define DEFAULT_NODE_REJOIN_TIMEOUT 60 /* seconds */
#define DEFAULT_ARCHIVE_READY_WARNING 16 /* WAL files */
#define DEFAULT_ARCHIVE_READY_CRITICAL 128 /* WAL files */
#define DEFAULT_REPLICATION_TYPE REPLICATION_TYPE_PHYSICAL
#define DEFAULT_REPLICATION_LAG_WARNING 300 /* seconds */
#define DEFAULT_REPLICATION_LAG_CRITICAL 600 /* seconds */
#define DEFAULT_WITNESS_SYNC_INTERVAL 15 /* seconds */
@@ -135,7 +136,6 @@
#define DEFAULT_ASYNC_QUERY_TIMEOUT 60 /* seconds */
#define DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT 60 /* seconds */
#define DEFAULT_REPMGRD_STANDBY_STARTUP_TIMEOUT -1 /*seconds */
#define DEFAULT_REPMGRD_EXIT_ON_INACTIVE_NODE false,
#define DEFAULT_STANDBY_DISCONNECT_ON_FAILOVER false
#define DEFAULT_SIBLING_NODES_DISCONNECT_TIMEOUT 30 /* seconds */
#define DEFAULT_CONNECTION_CHECK_TYPE CHECK_PING

View File

@@ -1,7 +1,5 @@
#define REPMGR_VERSION_DATE ""
#define REPMGR_VERSION "5.3.1"
#define REPMGR_VERSION_NUM 50301
#define REPMGR_EXTENSION_VERSION "5.3"
#define REPMGR_EXTENSION_NUM 50300
#define REPMGR_RELEASE_DATE "2022-02-15"
#define REPMGR_VERSION "5.2.0"
#define REPMGR_VERSION_NUM 50200
#define REPMGR_RELEASE_DATE "2020-XX-XX"
#define PG_ACTUAL_VERSION_NUM

View File

@@ -1,7 +1,7 @@
/*
* repmgrd-physical.c - physical (streaming) replication functionality for repmgrd
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -169,126 +169,45 @@ handle_sigint_physical(SIGNAL_ARGS)
/* perform some sanity checks on the node's configuration */
void
do_physical_node_check(PGconn *conn)
do_physical_node_check(void)
{
/*
* If node record is "inactive"; if not, attempt to set it to "active".
* Check if node record is active - if not, and `failover=automatic`, the
* node won't be considered as a promotion candidate; this often happens
* when a failed primary is recloned and the node was not re-registered,
* giving the impression failover capability is there when it's not. In
* this case abort with an error and a hint about registering.
*
* Usually it will have become inactive due to e.g. a standby being shut down
* while repmgrd was running in an unpaused state. In this case it's
* perfectly reasonable to automatically mark the node as "active".
* If `failover=manual`, repmgrd can continue to passively monitor the
* node, but we should nevertheless issue a warning and the same hint.
*/
if (local_node_info.active == false)
{
char *hint = "Check that \"repmgr (primary|standby) register\" was executed for this node";
RecoveryType recovery_type = get_recovery_type(conn);
/*
* If the local node's recovery status is incompatible with its registered
* status, e.g. registered as primary but running as a standby, refuse to start.
*
* This typically happens when a failed primary is recloned but the node was not
* re-registered, leaving the cluster in a potentially ambiguous state. In
* this case it would not be possible or desirable to attempt to set the
* node to active; the user should ensure the cluster is in the correct state.
*/
if (recovery_type != RECTYPE_UNKNOWN && local_node_info.type != UNKNOWN)
switch (config_file_options.failover)
{
bool require_reregister = false;
PQExpBufferData event_details;
initPQExpBuffer(&event_details);
/* "failover" is an enum, all values should be covered here */
if (recovery_type == RECTYPE_STANDBY && local_node_info.type != STANDBY)
{
appendPQExpBuffer(&event_details,
_("node is registered as a %s but running as a standby"),
get_node_type_string(local_node_info.type));
require_reregister = true;
}
else if (recovery_type == RECTYPE_PRIMARY && local_node_info.type == STANDBY)
{
log_error(_("node is registered as a standby but running as a %s"), get_node_type_string(local_node_info.type));
require_reregister = true;
}
if (require_reregister == true)
{
log_error("%s", event_details.data);
case FAILOVER_AUTOMATIC:
log_error(_("this node is marked as inactive and cannot be used as a failover target"));
log_hint(_("%s"), hint);
create_event_notification(NULL,
&config_file_options,
config_file_options.node_id,
"repmgrd_start",
"repmgrd_shutdown",
false,
event_details.data);
"node is inactive and cannot be used as a failover target");
termPQExpBuffer(&event_details);
terminate(ERR_BAD_CONFIG);
}
break;
termPQExpBuffer(&event_details);
}
/*
* Attempt to set node record active (unless explicitly configured not to)
*/
log_notice(_("setting node record for node \"%s\" (ID: %i) to \"active\""),
local_node_info.node_name,
local_node_info.node_id);
if (config_file_options.repmgrd_exit_on_inactive_node == false)
{
PGconn *primary_conn = get_primary_connection(conn, NULL, NULL);
bool success = true;
if (PQstatus(primary_conn) != CONNECTION_OK)
{
log_error(_("unable to connect to the primary node to activate the node record"));
success = false;
}
else
{
success = update_node_record_set_active(primary_conn, local_node_info.node_id, true);
PQfinish(primary_conn);
}
if (success == true)
{
local_node_info.active = true;
}
}
/*
* Corner-case where it was not possible to set the node to "active"
*/
if (local_node_info.active == false)
{
switch (config_file_options.failover)
{
/* "failover" is an enum, all values should be covered here */
case FAILOVER_AUTOMATIC:
log_error(_("this node is marked as inactive and cannot be used as a failover target"));
log_hint(_("%s"), hint);
create_event_notification(NULL,
&config_file_options,
config_file_options.node_id,
"repmgrd_start",
false,
"node is inactive and cannot be used as a failover target");
terminate(ERR_BAD_CONFIG);
break;
case FAILOVER_MANUAL:
log_warning(_("this node is marked as inactive and will be passively monitored only"));
log_hint(_("%s"), hint);
break;
}
case FAILOVER_MANUAL:
log_warning(_("this node is marked as inactive and will be passively monitored only"));
log_hint(_("%s"), hint);
break;
}
}
@@ -585,7 +504,6 @@ monitor_streaming_primary(void)
if (is_server_available(local_node_info.conninfo) == true)
{
close_connection(&local_conn);
local_conn = establish_db_connection(local_node_info.conninfo, false);
if (PQstatus(local_conn) != CONNECTION_OK)
@@ -819,7 +737,7 @@ check_primary_status(int degraded_monitoring_elapsed)
/* refresh our copy of the node record from the primary */
record_status = get_node_record(new_primary_conn, config_file_options.node_id, &local_node_info);
/* this is unlikely to happen */
/* this is unlikley to happen */
if (record_status != RECORD_FOUND)
{
log_warning(_("unable to retrieve local node record from primary node %i"), primary_node_id);
@@ -1193,7 +1111,7 @@ execute_child_nodes_disconnect_command(NodeInfoList *db_child_node_records, t_ch
/* calculate number of connected child nodes */
for (cell = db_child_node_records->head; cell; cell = cell->next)
{
/* exclude witness server from total, if necessary */
/* exclude witness server from total, if necessay */
if (config_file_options.child_nodes_connected_include_witness == false &&
cell->node_info->type == WITNESS)
continue;
@@ -1231,7 +1149,7 @@ execute_child_nodes_disconnect_command(NodeInfoList *db_child_node_records, t_ch
instr_time current_time = current_time_base;
int seconds_since_detached;
/* exclude witness server from calculation, if requested */
/* exclude witness server from calculatin if neccessary */
if (config_file_options.child_nodes_connected_include_witness == false &&
child_node_rec->type == WITNESS)
continue;
@@ -1814,10 +1732,7 @@ monitor_streaming_standby(void)
if (upstream_check_result == true)
{
if (config_file_options.connection_check_type != CHECK_QUERY)
{
close_connection(&upstream_conn);
upstream_conn = establish_db_connection(upstream_node_info.conninfo, false);
}
if (PQstatus(upstream_conn) == CONNECTION_OK)
{
@@ -1898,7 +1813,6 @@ monitor_streaming_standby(void)
int former_upstream_node_id = local_node_info.upstream_node_id;
NodeInfoList sibling_nodes = T_NODE_INFO_LIST_INITIALIZER;
PQExpBufferData event_details;
t_event_info event_info = T_EVENT_INFO_INITIALIZER;
update_node_record_set_primary(local_conn, local_node_info.node_id);
record_status = get_node_record(local_conn, local_node_info.node_id, &local_node_info);
@@ -1911,16 +1825,12 @@ monitor_streaming_standby(void)
initPQExpBuffer(&event_details);
appendPQExpBufferStr(&event_details,
_("promotion command failed but promotion completed successfully"));
event_info.node_id = former_upstream_node_id;
create_event_notification_extended(local_conn,
&config_file_options,
local_node_info.node_id,
"repmgrd_failover_promote",
true,
event_details.data,
&event_info);
create_event_notification(local_conn,
&config_file_options,
local_node_info.node_id,
"repmgrd_failover_promote",
true,
event_details.data);
termPQExpBuffer(&event_details);
@@ -2550,10 +2460,8 @@ monitor_streaming_witness(void)
if (check_upstream_connection(&primary_conn, upstream_node_info.conninfo, NULL) == true)
{
if (config_file_options.connection_check_type != CHECK_QUERY)
{
close_connection(&primary_conn);
primary_conn = establish_db_connection(upstream_node_info.conninfo, false);
}
if (PQstatus(primary_conn) == CONNECTION_OK)
{
PQExpBufferData event_details;
@@ -3067,6 +2975,7 @@ do_primary_failover(void)
t_node_info new_primary = T_NODE_INFO_INITIALIZER;
RecordStatus record_status = RECORD_NOT_FOUND;
PGconn *new_primary_conn;
record_status = get_node_record(local_conn, new_primary_id, &new_primary);
@@ -3078,7 +2987,6 @@ do_primary_failover(void)
else
{
PQExpBufferData event_details;
PGconn *new_primary_conn;
initPQExpBuffer(&event_details);
appendPQExpBuffer(&event_details,
@@ -3099,6 +3007,7 @@ do_primary_failover(void)
event_details.data);
close_connection(&new_primary_conn);
termPQExpBuffer(&event_details);
}
failover_state = FAILOVER_STATE_REQUIRES_MANUAL_FAILOVER;
}
@@ -3345,7 +3254,7 @@ update_monitoring_history(void)
*
* Attach cascaded standby to another node, currently the primary.
*
* Note that in contrast to a primary failover, where one of the downstream
* Note that in contrast to a primary failover, where one of the downstrean
* standby nodes will become a primary, a cascaded standby failover (where the
* upstream standby has gone away) is "just" a case of attaching the standby to
* another node.
@@ -3765,7 +3674,6 @@ promote_self(void)
{
PQExpBufferData event_details;
t_event_info event_info = T_EVENT_INFO_INITIALIZER;
/* update own internal node record */
record_status = get_node_record(local_conn, local_node_info.node_id, &local_node_info);
@@ -3782,16 +3690,13 @@ promote_self(void)
failed_primary.node_name,
failed_primary.node_id);
event_info.node_id = failed_primary.node_id;
/* local_conn is now the primary connection */
create_event_notification_extended(local_conn,
&config_file_options,
local_node_info.node_id,
"repmgrd_failover_promote",
true,
event_details.data,
&event_info);
create_event_notification(local_conn,
&config_file_options,
local_node_info.node_id,
"repmgrd_failover_promote",
true,
event_details.data);
termPQExpBuffer(&event_details);
}
@@ -4016,7 +3921,6 @@ follow_new_primary(int new_primary_id)
termPQExpBuffer(&event_details);
close_connection(&upstream_conn);
close_connection(&old_primary_conn);
return FAILOVER_STATE_PRIMARY_REAPPEARED;
@@ -4027,8 +3931,6 @@ follow_new_primary(int new_primary_id)
close_connection(&old_primary_conn);
}
close_connection(&upstream_conn);
return FAILOVER_STATE_FOLLOW_FAIL;
}
@@ -5479,7 +5381,7 @@ try_primary_reconnect(PGconn **conn, PGconn *local_conn, t_node_info *node_info)
time_t started_at = time(NULL);
int up_to;
bool sleep_now = false;
int max_sleep_seconds;
bool max_sleep_seconds;
log_info(_("checking state of node \"%s\" (ID: %i), %i of %i attempts"),
node_info->node_name,

View File

@@ -1,6 +1,6 @@
/*
* repmgrd-physical.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -19,7 +19,7 @@
#ifndef _REPMGRD_PHYSICAL_H_
#define _REPMGRD_PHYSICAL_H_
void do_physical_node_check(PGconn *conn);
void do_physical_node_check(void);
void monitor_streaming_primary(void);
void monitor_streaming_standby(void);

View File

@@ -1,7 +1,7 @@
/*
* repmgrd.c - Replication manager daemon
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -131,7 +131,7 @@ main(int argc, char **argv)
memset(pid_file, 0, MAXPGPATH);
while ((c = getopt_long(argc, argv, "?Vf:L:vdp:sm", long_options, &optindex)) != -1)
while ((c = getopt_long(argc, argv, "?Vf:L:vdp:m", long_options, &optindex)) != -1)
{
switch (c)
{
@@ -249,7 +249,7 @@ main(int argc, char **argv)
/*
* Parse the configuration file, if provided (if no configuration file was
* provided, an attempt will be made to find one in one of the default
* locations). If no configuration file is available, or it can't be parsed
* locations). If no conifguration file is available, or it can't be parsed
* parse_config() will abort anyway, with an appropriate message.
*/
load_config(config_file, verbose, false, argv[0]);
@@ -307,7 +307,7 @@ main(int argc, char **argv)
}
/* Some configuration file items can be overridden by command line options */
/* Some configuration file items can be overriden by command line options */
/*
* Command-line parameter -L/--log-level overrides any setting in config
@@ -396,14 +396,13 @@ main(int argc, char **argv)
* extension is the latest available according to "pg_available_extensions" -
* - does our (major) version match that?
*/
log_verbose(LOG_DEBUG, "expected extension version: %i; extension version: %i",
REPMGR_EXTENSION_NUM, extversions.installed_version_num);
if ((REPMGR_EXTENSION_NUM/100) < (extversions.installed_version_num / 100))
log_verbose(LOG_DEBUG, "binary version: %i; extension version: %i",
REPMGR_VERSION_NUM, extversions.installed_version_num);
if ((REPMGR_VERSION_NUM/100) < (extversions.installed_version_num / 100))
{
log_error(_("this \"repmgr\" version is older than the installed \"repmgr\" extension version"));
log_detail(_("\"repmgr\" version %s providing extension version %s is installed but extension is version %s"),
log_detail(_("\"repmgr\" version %s is installed but extension is version %s"),
REPMGR_VERSION,
REPMGR_EXTENSION_VERSION,
extversions.installed_version);
log_hint(_("update the repmgr binaries to match the installed extension version"));
@@ -411,14 +410,13 @@ main(int argc, char **argv)
exit(ERR_BAD_CONFIG);
}
if ((REPMGR_EXTENSION_NUM/100) > (extversions.installed_version_num / 100))
if ((REPMGR_VERSION_NUM/100) > (extversions.installed_version_num / 100))
{
log_error(_("this \"repmgr\" version is newer than the installed \"repmgr\" extension version"));
log_detail(_("\"repmgr\" version %s providing extension version %s is installed but extension is version %s"),
log_detail(_("\"repmgr\" version %s is installed but extension is version %s"),
REPMGR_VERSION,
REPMGR_EXTENSION_VERSION,
extversions.installed_version);
log_hint(_("update the installed extension version by executing \"ALTER EXTENSION repmgr UPDATE\" in the repmgr database"));
log_hint(_("update the installed extension version by executing \"ALTER EXTENSION repmgr UPDATE\""));
close_connection(&local_conn);
exit(ERR_BAD_CONFIG);
@@ -512,7 +510,7 @@ main(int argc, char **argv)
log_debug("node id is %i, upstream node id is %i",
local_node_info.node_id,
local_node_info.upstream_node_id);
do_physical_node_check(local_conn);
do_physical_node_check();
}
if (daemonize == true)

View File

@@ -1,6 +1,6 @@
/*
* repmgrd.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* Copyright (c) 2ndQuadrant, 2010-2020
*/

View File

@@ -1,7 +1,7 @@
/*
* strutil.c
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -369,6 +369,7 @@ check_status_list_free(CheckStatusList *list)
}
const char *
output_check_status(CheckStatus status)
{

View File

@@ -1,6 +1,6 @@
/*
* strutil.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -3,7 +3,7 @@
*
* Functions which need to be executed on the local system.
*
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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
@@ -289,19 +289,10 @@ disable_wal_receiver(PGconn *conn)
if (wal_retrieve_retry_interval < WALRECEIVER_DISABLE_TIMEOUT_VALUE)
{
bool success;
log_notice(_("setting \"wal_retrieve_retry_interval\" to %i milliseconds"),
new_wal_retrieve_retry_interval);
alter_system_int(conn, "wal_retrieve_retry_interval", new_wal_retrieve_retry_interval);
success = pg_reload_conf(conn);
if (success == false)
{
log_warning(_("unable to reload configuration"));
return UNKNOWN_PID;
}
pg_reload_conf(conn);
}
/*
@@ -363,12 +354,6 @@ enable_wal_receiver(PGconn *conn, bool wait_startup)
/* make timeout configurable */
int i, timeout = 30;
if (PQstatus(conn) != CONNECTION_OK)
{
log_error(_("database connection not available"));
return UNKNOWN_PID;
}
if (is_superuser_connection(conn, NULL) == false)
{
log_error(_("superuser connection required"));
@@ -409,13 +394,7 @@ enable_wal_receiver(PGconn *conn, bool wait_startup)
return UNKNOWN_PID;
}
success = pg_reload_conf(conn);
if (success == false)
{
log_warning(_("unable to reload configuration"));
return UNKNOWN_PID;
}
pg_reload_conf(conn);
}
else
{

View File

@@ -1,6 +1,6 @@
/*
* sysutils.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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

View File

@@ -1,6 +1,6 @@
/*
* voting.h
* Copyright (c) EnterpriseDB Corporation, 2010-2021
* 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