Compare commits

...

32 Commits

Author SHA1 Message Date
Ian Barwick
abe55e60e6 doc: update 5.2.1 release notes 2020-12-04 14:50:04 +09:00
Ian Barwick
220bcbd620 Minor string formatting optimization 2020-12-04 10:18:05 +09:00
Ian Barwick
e824dfd499 standby clone: tweak error message
Probably a remnant from the 9.1 era, where it was not possible to
take a base backup from a standby.
2020-12-04 10:18:02 +09:00
Ian Barwick
9fb9decf13 Fix return value of pg_reload_conf() database utility function
Would always return "false", but as the value wasn't used anywhere,
the issue was inconsequential.

However while we're at it, actually check the return value in the
two places it's called, to help diagnose any issues in the unlikely
event they occur.

Per issue reported via GitHub PR #671 from user duzhgg.
2020-12-02 09:27:14 +09:00
Ian Barwick
ad6dde4218 doc: update README
- remove partial sentence
- remove links to very dated blog entries
2020-12-02 09:26:06 +09:00
Ian Barwick
7cbaec6469 doc: update README
Link to release notes as a simple way of providing the latest release
information.
2020-12-02 09:25:59 +09:00
Ian Barwick
9d2c5921ee Add missing connection close
In a corner-case situation where a standby is unable to attach to
the new primary due to a mismatch in the WAL stream, the connection
used to verify the recovery status of the new primary was not being
closed, leading to a risk of connection exhaustion on the new primary.

Addresses GitHub #682.
2020-12-02 09:23:00 +09:00
Ian Barwick
21f94e6de3 doc: tweak "repmgr standby clone" reference
As recovery.conf starts to fade away, mention that last.
2020-12-02 09:22:49 +09:00
Ian Barwick
7418c7b8f0 Fix typo 2020-12-02 09:22:38 +09:00
Ian Barwick
7cee09dd95 standby clone: fix data directory permissions handling for Pg11 and later
Previously, repmgr would forcibly change the permissions on a data
directory to 0700. However from PostgreSQL 11, 0750 is also valid,
so that value should not be changed.
2020-12-01 11:49:13 +09:00
Ian Barwick
53774d6998 Bump version to 5.2.1 2020-11-30 17:33:42 +09:00
Ian Barwick
5a251ef268 standby clone: add --recovery-min-apply-delay to help output 2020-11-30 16:43:17 +09:00
Ian Barwick
b83ce6b147 doc: update 5.2.1 release notes 2020-11-30 16:14:37 +09:00
Ian Barwick
5f9f1f65ae repmgrd: fix issue with incorrect reconnect_interval
Addresses GitHub #673.
2020-11-25 20:42:29 +09:00
Ian Barwick
9d7eebef1b Update Makefile
We don't actually need $(LIBS) in there; this was cargo-culted in
from somewhere.
2020-11-24 17:37:54 +09:00
Ian Barwick
5cff7fab64 Avoid compiler warnings for various strncpy() operations
Here the compiler may complain that the source length is being used,
though in all cases the source length was previously used to
define the length of the destination buffer, so it's not actually
a problem.
2020-11-24 15:42:54 +09:00
Ian Barwick
2a8ac36aec repmgr: prevent termination in corner-case situation
If neither the local node nor the upstream are available, and
"standby_disconnect_on_failover" is set, attempting to fetch
the walreceiver PID will result in repmgrd terminating.

Add a check that the connection is valid before attempting to
fetch the walreceiver PID.

Addresses GitHub #675.
2020-11-17 16:35:03 +09:00
Ian Barwick
a5a5b506f9 standby clone: various clarifications for --replication-conf-only option
In particular, the emitted HINT was not really appropriate for Pg13 and
later.
2020-11-17 10:01:30 +09:00
Ian Barwick
bd6871817d Update corner-case error message
Not possible to build repmgr compatible with Pg12+ against Pg11
and earlier due to the addition of FullTransactionId.
2020-11-17 10:01:26 +09:00
Ian Barwick
bd35e503ec standby clone: add option --recovery-min-apply-delay
This overrides the equivalent setting in repmgr.conf, if present.

Note this option was available in repmgr versions prior to 4.0, but
was assumed to be redundant. However recently a use-case was made
for its reintroduction.
2020-11-10 16:05:14 +09:00
Romain Jacquier
15801b8f9e Fix help witness
Fix the `repmgr witness --help` command where at the "Unregister" section the message shown was
```
"witness register" unregisters a witness node.
```
instead of
```
"witness unregister" unregisters a witness node.
```

GitHub #676.
2020-11-09 13:35:23 +09:00
Ian Barwick
4d3262d306 standby clone: handle missing "postgresql.auto.conf"
In PostgreSQL 12 and later we need to append replication configuration
to "postgresql.auto.conf" to guarantee it will be read last, and hence
override any preceding replication configuration which may be haunting
the configuration files.

We've been assuming that "postgresql.auto.conf" will always be present,
but at least one corner case has been observed where that was not the
case on the node being cloned from. Moreover it's perfectly acceptable
that this file does not exist (it will be recreated the next time
ALTER SYSTEM is executed), so we should be prepared to handle that case.

In passing, improve handling of more unlikely errors which might be
encountered when processing "postgresql.auto.conf".
2020-10-30 12:26:56 +09:00
Ian Barwick
36a8dfcf4f Standardize code style 2020-10-30 11:06:46 +09:00
Ian Barwick
94612a336a config: fix parsing of "replication_type"
This is a legacy parameter which can currently only contain one value,
"physical" (the default).

It can be safely omitted.

Addresses GitHub #672.
2020-10-30 10:17:03 +09:00
Ian Barwick
de567d584f doc: update README 2020-10-22 21:21:16 +09:00
Ian Barwick
0fb3432398 Finalize release date 2020-10-22 17:15:37 +09:00
Ian Barwick
5e59e543d6 Additional fix to upgrade script
Drop old "repl_events" table.
2020-10-22 12:36:31 +09:00
Ian Barwick
4f6b642320 Fix extension script for unpackaged upgrades to 5.2
Apparently "ALTER TABLE" (which we were using to convert the
"repl_events" table) does not mark the table as being part of the
extension. Instead, we need to create the new table and copy the
data, as is done with the other tables.
2020-10-22 11:18:03 +09:00
Ian Barwick
c1973438f7 doc: add missing "unpackaged" reference 2020-10-21 17:31:22 +09:00
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
27 changed files with 655 additions and 97 deletions

13
HISTORY
View File

@@ -1,4 +1,15 @@
5.2.0 2020-??-??
5.2.1 2020-??-??
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
general: add support for PostgreSQL 13 (Ian)
general: remove support for PostgreSQL 9.3 (Ian)
config: add support for file inclusion directives (Ian)

View File

@@ -12,6 +12,7 @@ EXTENSION = repmgr
DATA = \
repmgr--unpackaged--4.0.sql \
repmgr--unpackaged--5.1.sql \
repmgr--unpackaged--5.2.sql \
repmgr--4.0.sql \
repmgr--4.0--4.1.sql \
repmgr--4.1.sql \
@@ -75,10 +76,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) $(LIBS) -o $@$(X)
$(CC) $(CFLAGS) $(REPMGR_CLIENT_OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) -o $@$(X)
repmgrd: $(REPMGRD_OBJS)
$(CC) $(CFLAGS) $(REPMGRD_OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
$(CC) $(CFLAGS) $(REPMGRD_OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) -o $@$(X)
$(REPMGR_CLIENT_OBJS): $(HEADERS)
$(REPMGRD_OBJS): $(HEADERS)

View File

@@ -7,8 +7,8 @@ replication capabilities with utilities to set up standby servers, monitor
replication, and perform administrative tasks such as failover or switchover
operations.
PostgreSQL 12, 11, 10, 9.6 and 9.5 are fully supported.
PostgreSQL 9.4 and 9.3 are supported, with some restrictions.
The most recent `repmgr` version (5.2.0) supports all PostgreSQL versions from
9.5 to 13. PostgreSQL 9.4 is also supported, with some restrictions.
`repmgr` is distributed under the GNU GPL 3 and maintained by 2ndQuadrant.
@@ -24,7 +24,8 @@ The old `README` file for `repmgr` 3.x is available here:
> 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 as soon as possible.
please upgrade to the [current repmgr version](https://repmgr.org/docs/current/appendix-release-notes.html)
as soon as possible.
Versions
--------
@@ -70,8 +71,6 @@ Please report bugs and other issues to:
* 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
@@ -100,7 +99,3 @@ 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/)
* 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

@@ -120,10 +120,10 @@ struct ConfigFileSetting config_file_settings[] =
/* replication_type */
{
"replication_type",
CONFIG_INT,
{ .intptr = &config_file_options.replication_type },
{ .intdefault = REPLICATION_TYPE_PHYSICAL },
{ .intminval = -1 },
CONFIG_REPLICATION_TYPE,
{ .replicationtypeptr = &config_file_options.replication_type },
{ .replicationtypedefault = DEFAULT_REPLICATION_TYPE },
{},
{},
{}
},

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, KeyValueList *contents, ItemList *error_list, ItemList *warning_list)
ProcessPostgresConfigFile(const char *config_file, const char *base_dir, bool strict, KeyValueList *contents, ItemList *error_list, ItemList *warning_list)
{
return ProcessConfigFile(base_dir, config_file, NULL, true, 0, contents, error_list, warning_list);
return ProcessConfigFile(base_dir, config_file, NULL, strict, 0, contents, error_list, warning_list);
}
static bool

View File

@@ -313,6 +313,9 @@ _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 */
@@ -566,6 +569,20 @@ 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,
@@ -1394,6 +1411,9 @@ 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);
@@ -1765,7 +1785,7 @@ modify_auto_conf(const char *data_dir, KeyValueList *items)
FILE *fp;
mode_t um;
struct stat auto_conf_st;
struct stat data_dir_st;
KeyValueList config = {NULL, NULL};
KeyValueListCell *cell = NULL;
@@ -1776,7 +1796,12 @@ 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, &config, NULL, NULL);
success = ProcessPostgresConfigFile(auto_conf.data,
NULL,
false, /* we don't care if the file does not exist */
&config,
NULL,
NULL);
if (success == false)
{
@@ -1787,7 +1812,7 @@ modify_auto_conf(const char *data_dir, KeyValueList *items)
}
/*
* Append requested items to items extracted from the existing file.
* Append requested items to any items extracted from the existing file.
*/
for (cell = items->head; cell; cell = cell->next)
{
@@ -1816,27 +1841,46 @@ modify_auto_conf(const char *data_dir, KeyValueList *items)
cell->key, cell->value);
}
stat(auto_conf.data, &auto_conf_st);
/* 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);
}
/*
* Set umask so the temporary file is created in the same mode as the original
* postgresql.auto.conf file.
* 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.
*/
um = umask(~(auto_conf_st.st_mode));
um = umask(~(data_dir_st.st_mode));
fp = fopen(auto_conf_tmp.data, "w");
umask(um);
if (fp == NULL)
{
fprintf(stderr, "unable to open \"%s\": %s\n",
fprintf(stderr, "unable to open \"%s\" for writing: %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
{
@@ -2167,6 +2211,20 @@ 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)
{
@@ -2192,6 +2250,7 @@ print_event_notification_list(EventNotificationList *list)
PQExpBufferData buf;
char *ptr;
EventNotificationListCell *cell;
int ptr_len;
initPQExpBuffer(&buf);
cell = list->head;
@@ -2206,8 +2265,10 @@ print_event_notification_list(EventNotificationList *list)
cell = cell->next;
}
ptr = palloc0(strlen(buf.data) + 1);
strncpy(ptr, buf.data, strlen(buf.data));
ptr_len = strlen(buf.data);
ptr = palloc0(ptr_len + 1);
strncpy(ptr, buf.data, ptr_len);
termPQExpBuffer(&buf);

View File

@@ -50,6 +50,11 @@ typedef enum
CHECK_CONNECTION
} ConnectionCheckType;
typedef enum
{
REPLICATION_TYPE_PHYSICAL
} ReplicationType;
typedef struct EventNotificationListCell
{
struct EventNotificationListCell *next;
@@ -86,7 +91,8 @@ typedef enum
CONFIG_FAILOVER_MODE,
CONFIG_CONNECTION_CHECK_TYPE,
CONFIG_EVENT_NOTIFICATION_LIST,
CONFIG_TABLESPACE_MAPPING
CONFIG_TABLESPACE_MAPPING,
CONFIG_REPLICATION_TYPE
} ConfigItemType;
@@ -103,6 +109,7 @@ typedef struct ConfigFileSetting
ConnectionCheckType *checktypeptr;
EventNotificationList *notificationlistptr;
TablespaceList *tablespacemappingptr;
ReplicationType *replicationtypeptr;
} val;
union {
int intdefault;
@@ -110,6 +117,7 @@ typedef struct ConfigFileSetting
bool booldefault;
failover_mode_opt failovermodedefault;
ConnectionCheckType checktypedefault;
ReplicationType replicationtypedefault;
} defval;
union {
int intminval;
@@ -138,7 +146,7 @@ typedef struct
char config_directory[MAXPGPATH];
char pg_bindir[MAXPGPATH];
char repmgr_bindir[MAXPGPATH];
int replication_type;
ReplicationType replication_type;
/* log settings */
char log_level[MAXLEN];
@@ -356,6 +364,7 @@ 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);
@@ -364,6 +373,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, KeyValueList *contents, 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);
#endif /* _REPMGR_CONFIGFILE_H_ */

20
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.2.
# Generated by GNU Autoconf 2.69 for repmgr 5.2.1.
#
# Report bugs to <repmgr@googlegroups.com>.
#
@@ -582,8 +582,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='repmgr'
PACKAGE_TARNAME='repmgr'
PACKAGE_VERSION='5.2'
PACKAGE_STRING='repmgr 5.2'
PACKAGE_VERSION='5.2.1'
PACKAGE_STRING='repmgr 5.2.1'
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.2 to adapt to many kinds of systems.
\`configure' configures repmgr 5.2.1 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.2:";;
short | recursive ) echo "Configuration of repmgr 5.2.1:";;
esac
cat <<\_ACEOF
@@ -1316,7 +1316,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
repmgr configure 5.2
repmgr configure 5.2.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -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.2, which was
It was created by repmgr $as_me 5.2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -1824,7 +1824,7 @@ if test "$major_version_num" -lt '10'; then
version_num_int=$(echo "$version_num"|
$SED -e 's/^\([0-9]*\)\.\([0-9]*\)$/\1\2/')
if test "$version_num_int" -lt '93'; then
if test "$version_num_int" -lt '94'; then
as_fn_error $? "repmgr is not compatible with detected PostgreSQL version: $version_num" "$LINENO" 5
fi
else
@@ -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.2, which was
This file was extended by repmgr $as_me 5.2.1, 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.2
repmgr config.status 5.2.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@@ -1,4 +1,4 @@
AC_INIT([repmgr], [5.2], [repmgr@googlegroups.com], [repmgr], [https://repmgr.org/])
AC_INIT([repmgr], [5.2.1], [repmgr@googlegroups.com], [repmgr], [https://repmgr.org/])
AC_COPYRIGHT([Copyright (c) 2010-2020, 2ndQuadrant Ltd.])
@@ -32,7 +32,7 @@ if test "$major_version_num" -lt '10'; then
version_num_int=$(echo "$version_num"|
$SED -e 's/^\([[0-9]]*\)\.\([[0-9]]*\)$/\1\2/')
if test "$version_num_int" -lt '93'; then
if test "$version_num_int" -lt '94'; then
AC_MSG_ERROR([repmgr is not compatible with detected PostgreSQL version: $version_num])
fi
else

View File

@@ -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\n");
fprintf(stderr, "ERROR: please use a repmgr version built for PostgreSQL 12 or later\n");
exit(ERR_BAD_CONFIG);
#endif
}

View File

@@ -1255,7 +1255,7 @@ bool
pg_reload_conf(PGconn *conn)
{
PGresult *res = NULL;
bool success = false;
bool success = true;
res = PQexec(conn, "SELECT pg_catalog.pg_reload_conf()");

View File

@@ -109,9 +109,56 @@ create_dir(const char *path)
bool
set_dir_permissions(const char *path)
set_dir_permissions(const char *path, int server_version_num)
{
return (chmod(path, 0700) != 0) ? false : true;
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;
}
@@ -303,7 +350,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))
@@ -314,14 +361,23 @@ create_pg_dir(const char *path, bool force)
}
break;
case DIR_EMPTY:
/* exists but empty, fix permissions and use it */
/*
* 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.
*/
log_info(_("checking and correcting permissions on existing directory \"%s\""),
path);
if (!set_dir_permissions(path))
if (!set_dir_permissions(path, UNKNOWN_SERVER_VERSION_NUM))
{
log_error(_("unable to change permissions of directory \"%s\""), path);
log_detail("%s", strerror(errno));
return false;
}
break;

View File

@@ -35,7 +35,7 @@ typedef enum
} PgDirState;
extern int mkdir_p(char *path, mode_t omode);
extern bool set_dir_permissions(const char *path);
extern bool set_dir_permissions(const char *path, int server_version_num);
extern DataDirState check_dir(const char *path);
extern bool create_dir(const char *path);

View File

@@ -15,17 +15,92 @@
See also: <xref linkend="upgrading-repmgr"/>
</para>
<sect1 id="release-5.2.1">
<title id="release-current">Release 5.2.1</title>
<para><emphasis>??? ?? 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>
<!-- remember to update the release date in ../repmgr_version.h.in -->
<sect1 id="release-5.2.0">
<title>Release 5.2.0</title>
<para><emphasis>??? ?? ???, 2020</emphasis></para>
<para><emphasis>Thu 22 October, 2020</emphasis></para>
<para>
&repmgr; 5.2.0 is a major release.
</para>
<para>
This release provides support for <ulink url="https://www.postgresql.org/docs/13/release-13.htmll">PostgreSQL 13</ulink>, released in September 2020.
This release provides support for <ulink url="https://www.postgresql.org/docs/13/release-13.html">PostgreSQL 13</ulink>, released in September 2020.
</para>
<para>
This release removes support for PostgreSQL 9.3, which was
@@ -220,7 +295,7 @@
</sect1>
<sect1 id="release-5.1.0">
<title id="release-current">Release 5.1.0</title>
<title>Release 5.1.0</title>
<para><emphasis>Mon 13 April, 2020</emphasis></para>
<para>

View File

@@ -133,10 +133,10 @@
&repmgr; 5.1
</entry>
<entry>
YES
NO
</entry>
<entry>
<link linkend="release-5.1.0">5.1</link> (2020-04-13)
<link linkend="release-5.1.0">5.1.0</link> (2020-04-13)
</entry>
<entry>
9.3, 9.4, 9.5, 9.6, 10, 11, 12

View File

@@ -260,16 +260,29 @@ pg_basebackup_options='--waldir=/path/to/wal-directory'</programlisting>
upstream node if required.
</para>
<para>
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.
The upstream node must be running so the correct replication configuration can be obtained.
</para>
<para>
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.
If the standby is running, the replication configuration will not be written 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.
</para>
<para>
In PostgreSQL 12 and earlier, the PostgreSQL instance must be restarted for replication
configuration changes to take effect.
</para>
</refsect1>
@@ -331,6 +344,25 @@ 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>
@@ -346,14 +378,14 @@ pg_basebackup_options='--waldir=/path/to/wal-directory'</programlisting>
<para>
Create recovery configuration for a previously cloned instance.
</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>
<para>
In PostgreSQL 11 and earlier, the replication configuration will be
written to <filename>recovery.conf</filename>.
</para>
</listitem>
</varlistentry>

View File

@@ -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</command>
Beginning with PostgreSQL 13, the <command>CREATE EXTENSION ... FROM unpackaged</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

245
repmgr--unpackaged--5.2.sql Normal file
View File

@@ -0,0 +1,245 @@
-- 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

@@ -733,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 primary server"));
log_error(_("unable to take a base backup of the source server"));
log_hint(_("data directory (\"%s\") may need to be cleaned up manually"),
local_data_directory);
@@ -763,7 +763,7 @@ do_standby_clone(void)
exit(ERR_BAD_CONFIG);
}
appendPQExpBufferStr(&command, " ");
appendPQExpBufferChar(&command, ' ');
/* Somewhat inconsistent, but pg_verifybackup doesn't accept a -D option */
appendShellString(&command,
@@ -838,6 +838,16 @@ 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
@@ -1444,7 +1454,18 @@ _do_create_replication_conf(void)
if (node_is_running == true)
{
log_hint(_("node must be restarted for the new file to take effect"));
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"));
}
}
}
}
@@ -5962,19 +5983,22 @@ check_source_server_via_barman()
initPQExpBuffer(&command_output);
maxlen_snprintf(buf,
"ssh %s \"psql -Aqt \\\"%s\\\" -c \\\""
"psql -AqtX -d \\\"%s\\\" -c \\\""
" SELECT conninfo"
" FROM repmgr.nodes"
" WHERE %s"
" AND active IS TRUE"
"\\\"\"",
config_file_options.barman_host,
"\\\"",
repmgr_conninfo_buf.data,
where_condition);
termPQExpBuffer(&repmgr_conninfo_buf);
command_success = local_command(buf, &command_output);
command_success = remote_command(config_file_options.barman_host,
runtime_options.remote_user,
buf,
config_file_options.ssh_options,
&command_output);
if (command_success == false)
{
@@ -7759,7 +7783,9 @@ 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)
@@ -7768,13 +7794,13 @@ tablespace_data_append(TablespaceDataList *list, const char *name, const char *o
exit(ERR_OUT_OF_MEMORY);
}
cell->oid = pg_malloc(1 + strlen(oid));
cell->name = pg_malloc(1 + strlen(name));
cell->location = pg_malloc(1 + strlen(location));
cell->oid = pg_malloc0(1 + oid_len);
cell->name = pg_malloc0(1 + name_len);
cell->location = pg_malloc0(1 + location_len);
strncpy(cell->oid, oid, 1 + strlen(oid));
strncpy(cell->name, name, 1 + strlen(name));
strncpy(cell->location, location, 1 + strlen(location));
strncpy(cell->oid, oid, oid_len);
strncpy(cell->name, name, name_len);
strncpy(cell->location, location, location_len);
if (list->tail)
list->tail->next = cell;
@@ -8908,6 +8934,8 @@ 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("");

View File

@@ -560,7 +560,7 @@ void do_witness_help(void)
printf(_("WITNESS UNREGISTER\n"));
puts("");
printf(_(" \"witness register\" unregisters a witness node.\n"));
printf(_(" \"witness unregister\" 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

@@ -84,7 +84,7 @@ typedef struct
bool fast_checkpoint;
bool rsync_only;
bool no_upstream_connection;
char recovery_min_apply_delay[MAXLEN];
char recovery_min_apply_delay[MAXLEN]; /* overrides setting in repmgr.conf */
char replication_user[MAXLEN];
char upstream_conninfo[MAXLEN];
bool without_barman;

View File

@@ -438,6 +438,11 @@ 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;
@@ -1105,10 +1110,25 @@ 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
@@ -1169,7 +1189,7 @@ main(int argc, char **argv)
}
/*
* Check for configuration file items which can be overriden by runtime
* Check for configuration file items which can be overridden by runtime
* options
* =====================================================================
*/

View File

@@ -99,6 +99,7 @@
#define OPT_REPLICATION_CONFIG_OWNER 1046
#define OPT_DB_CONNECTION 1047
#define OPT_VERIFY_BACKUP 1048
#define OPT_RECOVERY_MIN_APPLY_DELAY 1049
/* These options are for internal use only */
#define OPT_CONFIG_ARCHIVE_DIR 2001
@@ -164,6 +165,7 @@ 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},

View File

@@ -77,8 +77,6 @@
#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
@@ -122,6 +120,7 @@
#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 */

View File

@@ -1,5 +1,5 @@
#define REPMGR_VERSION_DATE ""
#define REPMGR_VERSION "5.2dev"
#define REPMGR_VERSION_NUM 50200
#define REPMGR_RELEASE_DATE "2020-XX-XX"
#define REPMGR_VERSION "5.2.1"
#define REPMGR_VERSION_NUM 50201
#define REPMGR_RELEASE_DATE "2020-12-??"
#define PG_ACTUAL_VERSION_NUM

View File

@@ -3921,6 +3921,7 @@ follow_new_primary(int new_primary_id)
termPQExpBuffer(&event_details);
close_connection(&upstream_conn);
close_connection(&old_primary_conn);
return FAILOVER_STATE_PRIMARY_REAPPEARED;
@@ -3931,6 +3932,8 @@ follow_new_primary(int new_primary_id)
close_connection(&old_primary_conn);
}
close_connection(&upstream_conn);
return FAILOVER_STATE_FOLLOW_FAIL;
}
@@ -5381,7 +5384,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;
bool max_sleep_seconds;
int max_sleep_seconds;
log_info(_("checking state of node \"%s\" (ID: %i), %i of %i attempts"),
node_info->node_name,

View File

@@ -289,10 +289,19 @@ 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);
pg_reload_conf(conn);
success = pg_reload_conf(conn);
if (success == false)
{
log_warning(_("unable to reload configuration"));
return UNKNOWN_PID;
}
}
/*
@@ -354,6 +363,12 @@ 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"));
@@ -394,7 +409,13 @@ enable_wal_receiver(PGconn *conn, bool wait_startup)
return UNKNOWN_PID;
}
pg_reload_conf(conn);
success = pg_reload_conf(conn);
if (success == false)
{
log_warning(_("unable to reload configuration"));
return UNKNOWN_PID;
}
}
else
{