mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-23 15:16:29 +00:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54851e8df1 | ||
|
|
a2166d0024 | ||
|
|
abe55e60e6 | ||
|
|
220bcbd620 | ||
|
|
e824dfd499 | ||
|
|
9fb9decf13 | ||
|
|
ad6dde4218 | ||
|
|
7cbaec6469 | ||
|
|
9d2c5921ee | ||
|
|
21f94e6de3 | ||
|
|
7418c7b8f0 | ||
|
|
7cee09dd95 | ||
|
|
53774d6998 | ||
|
|
5a251ef268 | ||
|
|
b83ce6b147 | ||
|
|
5f9f1f65ae | ||
|
|
9d7eebef1b | ||
|
|
5cff7fab64 | ||
|
|
2a8ac36aec | ||
|
|
a5a5b506f9 | ||
|
|
bd6871817d | ||
|
|
bd35e503ec | ||
|
|
15801b8f9e | ||
|
|
4d3262d306 | ||
|
|
36a8dfcf4f | ||
|
|
94612a336a | ||
|
|
de567d584f | ||
|
|
0fb3432398 | ||
|
|
5e59e543d6 | ||
|
|
4f6b642320 | ||
|
|
c1973438f7 | ||
|
|
fe5904e04e | ||
|
|
2cb1f4f728 | ||
|
|
5b90842c55 |
13
HISTORY
13
HISTORY
@@ -1,4 +1,15 @@
|
|||||||
5.2.0 2020-??-??
|
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
|
||||||
general: add support for PostgreSQL 13 (Ian)
|
general: add support for PostgreSQL 13 (Ian)
|
||||||
general: remove support for PostgreSQL 9.3 (Ian)
|
general: remove support for PostgreSQL 9.3 (Ian)
|
||||||
config: add support for file inclusion directives (Ian)
|
config: add support for file inclusion directives (Ian)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ EXTENSION = repmgr
|
|||||||
DATA = \
|
DATA = \
|
||||||
repmgr--unpackaged--4.0.sql \
|
repmgr--unpackaged--4.0.sql \
|
||||||
repmgr--unpackaged--5.1.sql \
|
repmgr--unpackaged--5.1.sql \
|
||||||
|
repmgr--unpackaged--5.2.sql \
|
||||||
repmgr--4.0.sql \
|
repmgr--4.0.sql \
|
||||||
repmgr--4.0--4.1.sql \
|
repmgr--4.0--4.1.sql \
|
||||||
repmgr--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_CLIENT_OBJS): repmgr-client.h repmgr_version.h
|
||||||
|
|
||||||
repmgr: $(REPMGR_CLIENT_OBJS)
|
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)
|
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)
|
$(REPMGR_CLIENT_OBJS): $(HEADERS)
|
||||||
$(REPMGRD_OBJS): $(HEADERS)
|
$(REPMGRD_OBJS): $(HEADERS)
|
||||||
|
|||||||
13
README.md
13
README.md
@@ -7,8 +7,8 @@ replication capabilities with utilities to set up standby servers, monitor
|
|||||||
replication, and perform administrative tasks such as failover or switchover
|
replication, and perform administrative tasks such as failover or switchover
|
||||||
operations.
|
operations.
|
||||||
|
|
||||||
PostgreSQL 12, 11, 10, 9.6 and 9.5 are fully supported.
|
The most recent `repmgr` version (5.2.0) supports all PostgreSQL versions from
|
||||||
PostgreSQL 9.4 and 9.3 are supported, with some restrictions.
|
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.
|
`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
|
> 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;
|
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
|
Versions
|
||||||
--------
|
--------
|
||||||
@@ -70,8 +71,6 @@ Please report bugs and other issues to:
|
|||||||
|
|
||||||
* https://github.com/2ndQuadrant/repmgr
|
* https://github.com/2ndQuadrant/repmgr
|
||||||
|
|
||||||
See
|
|
||||||
|
|
||||||
Further information is available at https://repmgr.org/
|
Further information is available at https://repmgr.org/
|
||||||
|
|
||||||
We'd love to hear from you about how you use repmgr. Case studies and
|
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)
|
* [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 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 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/
|
|
||||||
|
|||||||
@@ -120,10 +120,10 @@ struct ConfigFileSetting config_file_settings[] =
|
|||||||
/* replication_type */
|
/* replication_type */
|
||||||
{
|
{
|
||||||
"replication_type",
|
"replication_type",
|
||||||
CONFIG_INT,
|
CONFIG_REPLICATION_TYPE,
|
||||||
{ .intptr = &config_file_options.replication_type },
|
{ .replicationtypeptr = &config_file_options.replication_type },
|
||||||
{ .intdefault = REPLICATION_TYPE_PHYSICAL },
|
{ .replicationtypedefault = DEFAULT_REPLICATION_TYPE },
|
||||||
{ .intminval = -1 },
|
{},
|
||||||
{},
|
{},
|
||||||
{}
|
{}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -107,9 +107,9 @@ ProcessRepmgrConfigFile(const char *config_file, const char *base_dir, ItemList
|
|||||||
|
|
||||||
|
|
||||||
extern bool
|
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
|
static bool
|
||||||
|
|||||||
81
configfile.c
81
configfile.c
@@ -313,6 +313,9 @@ _parse_config(ItemList *error_list, ItemList *warning_list)
|
|||||||
case CONFIG_CONNECTION_CHECK_TYPE:
|
case CONFIG_CONNECTION_CHECK_TYPE:
|
||||||
*setting->val.checktypeptr = setting->defval.checktypedefault;
|
*setting->val.checktypeptr = setting->defval.checktypedefault;
|
||||||
break;
|
break;
|
||||||
|
case CONFIG_REPLICATION_TYPE:
|
||||||
|
*setting->val.replicationtypeptr = setting->defval.replicationtypedefault;
|
||||||
|
break;
|
||||||
case CONFIG_EVENT_NOTIFICATION_LIST:
|
case CONFIG_EVENT_NOTIFICATION_LIST:
|
||||||
case CONFIG_TABLESPACE_MAPPING:
|
case CONFIG_TABLESPACE_MAPPING:
|
||||||
/* no default for these types; lists cleared above */
|
/* no default for these types; lists cleared above */
|
||||||
@@ -566,6 +569,20 @@ parse_configuration_item(ItemList *error_list, ItemList *warning_list, const cha
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
case CONFIG_EVENT_NOTIFICATION_LIST:
|
||||||
{
|
{
|
||||||
parse_event_notifications_list((EventNotificationList *)setting->val.notificationlistptr,
|
parse_event_notifications_list((EventNotificationList *)setting->val.notificationlistptr,
|
||||||
@@ -1394,6 +1411,9 @@ dump_config(void)
|
|||||||
case CONFIG_CONNECTION_CHECK_TYPE:
|
case CONFIG_CONNECTION_CHECK_TYPE:
|
||||||
printf("%s", print_connection_check_type(*setting->val.checktypeptr));
|
printf("%s", print_connection_check_type(*setting->val.checktypeptr));
|
||||||
break;
|
break;
|
||||||
|
case CONFIG_REPLICATION_TYPE:
|
||||||
|
printf("%s", print_replication_type(*setting->val.replicationtypeptr));
|
||||||
|
break;
|
||||||
case CONFIG_EVENT_NOTIFICATION_LIST:
|
case CONFIG_EVENT_NOTIFICATION_LIST:
|
||||||
{
|
{
|
||||||
char *list = print_event_notification_list(setting->val.notificationlistptr);
|
char *list = print_event_notification_list(setting->val.notificationlistptr);
|
||||||
@@ -1765,7 +1785,7 @@ modify_auto_conf(const char *data_dir, KeyValueList *items)
|
|||||||
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
mode_t um;
|
mode_t um;
|
||||||
struct stat auto_conf_st;
|
struct stat data_dir_st;
|
||||||
|
|
||||||
KeyValueList config = {NULL, NULL};
|
KeyValueList config = {NULL, NULL};
|
||||||
KeyValueListCell *cell = NULL;
|
KeyValueListCell *cell = NULL;
|
||||||
@@ -1776,7 +1796,12 @@ modify_auto_conf(const char *data_dir, KeyValueList *items)
|
|||||||
appendPQExpBuffer(&auto_conf, "%s/%s",
|
appendPQExpBuffer(&auto_conf, "%s/%s",
|
||||||
data_dir, PG_AUTOCONF_FILENAME);
|
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)
|
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)
|
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);
|
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
|
* Set umask so the temporary file is created in the same mode as the data
|
||||||
* postgresql.auto.conf file.
|
* 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");
|
fp = fopen(auto_conf_tmp.data, "w");
|
||||||
|
|
||||||
umask(um);
|
umask(um);
|
||||||
|
|
||||||
if (fp == NULL)
|
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,
|
auto_conf_tmp.data,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
success = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (fwrite(auto_conf_contents.data, strlen(auto_conf_contents.data), 1, fp) != 1)
|
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);
|
fclose(fp);
|
||||||
|
success = false;
|
||||||
}
|
}
|
||||||
else
|
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 *
|
const char *
|
||||||
print_connection_check_type(ConnectionCheckType type)
|
print_connection_check_type(ConnectionCheckType type)
|
||||||
{
|
{
|
||||||
@@ -2192,6 +2250,7 @@ print_event_notification_list(EventNotificationList *list)
|
|||||||
PQExpBufferData buf;
|
PQExpBufferData buf;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
EventNotificationListCell *cell;
|
EventNotificationListCell *cell;
|
||||||
|
int ptr_len;
|
||||||
|
|
||||||
initPQExpBuffer(&buf);
|
initPQExpBuffer(&buf);
|
||||||
cell = list->head;
|
cell = list->head;
|
||||||
@@ -2206,8 +2265,10 @@ print_event_notification_list(EventNotificationList *list)
|
|||||||
cell = cell->next;
|
cell = cell->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = palloc0(strlen(buf.data) + 1);
|
ptr_len = strlen(buf.data);
|
||||||
strncpy(ptr, buf.data, strlen(buf.data));
|
ptr = palloc0(ptr_len + 1);
|
||||||
|
|
||||||
|
strncpy(ptr, buf.data, ptr_len);
|
||||||
|
|
||||||
termPQExpBuffer(&buf);
|
termPQExpBuffer(&buf);
|
||||||
|
|
||||||
|
|||||||
15
configfile.h
15
configfile.h
@@ -50,6 +50,11 @@ typedef enum
|
|||||||
CHECK_CONNECTION
|
CHECK_CONNECTION
|
||||||
} ConnectionCheckType;
|
} ConnectionCheckType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
REPLICATION_TYPE_PHYSICAL
|
||||||
|
} ReplicationType;
|
||||||
|
|
||||||
typedef struct EventNotificationListCell
|
typedef struct EventNotificationListCell
|
||||||
{
|
{
|
||||||
struct EventNotificationListCell *next;
|
struct EventNotificationListCell *next;
|
||||||
@@ -86,7 +91,8 @@ typedef enum
|
|||||||
CONFIG_FAILOVER_MODE,
|
CONFIG_FAILOVER_MODE,
|
||||||
CONFIG_CONNECTION_CHECK_TYPE,
|
CONFIG_CONNECTION_CHECK_TYPE,
|
||||||
CONFIG_EVENT_NOTIFICATION_LIST,
|
CONFIG_EVENT_NOTIFICATION_LIST,
|
||||||
CONFIG_TABLESPACE_MAPPING
|
CONFIG_TABLESPACE_MAPPING,
|
||||||
|
CONFIG_REPLICATION_TYPE
|
||||||
} ConfigItemType;
|
} ConfigItemType;
|
||||||
|
|
||||||
|
|
||||||
@@ -103,6 +109,7 @@ typedef struct ConfigFileSetting
|
|||||||
ConnectionCheckType *checktypeptr;
|
ConnectionCheckType *checktypeptr;
|
||||||
EventNotificationList *notificationlistptr;
|
EventNotificationList *notificationlistptr;
|
||||||
TablespaceList *tablespacemappingptr;
|
TablespaceList *tablespacemappingptr;
|
||||||
|
ReplicationType *replicationtypeptr;
|
||||||
} val;
|
} val;
|
||||||
union {
|
union {
|
||||||
int intdefault;
|
int intdefault;
|
||||||
@@ -110,6 +117,7 @@ typedef struct ConfigFileSetting
|
|||||||
bool booldefault;
|
bool booldefault;
|
||||||
failover_mode_opt failovermodedefault;
|
failover_mode_opt failovermodedefault;
|
||||||
ConnectionCheckType checktypedefault;
|
ConnectionCheckType checktypedefault;
|
||||||
|
ReplicationType replicationtypedefault;
|
||||||
} defval;
|
} defval;
|
||||||
union {
|
union {
|
||||||
int intminval;
|
int intminval;
|
||||||
@@ -138,7 +146,7 @@ typedef struct
|
|||||||
char config_directory[MAXPGPATH];
|
char config_directory[MAXPGPATH];
|
||||||
char pg_bindir[MAXPGPATH];
|
char pg_bindir[MAXPGPATH];
|
||||||
char repmgr_bindir[MAXPGPATH];
|
char repmgr_bindir[MAXPGPATH];
|
||||||
int replication_type;
|
ReplicationType replication_type;
|
||||||
|
|
||||||
/* log settings */
|
/* log settings */
|
||||||
char log_level[MAXLEN];
|
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 exit_with_cli_errors(ItemList *error_list, const char *repmgr_command);
|
||||||
|
|
||||||
void print_item_list(ItemList *item_list);
|
void print_item_list(ItemList *item_list);
|
||||||
|
const char *print_replication_type(ReplicationType type);
|
||||||
const char *print_connection_check_type(ConnectionCheckType type);
|
const char *print_connection_check_type(ConnectionCheckType type);
|
||||||
char *print_event_notification_list(EventNotificationList *list);
|
char *print_event_notification_list(EventNotificationList *list);
|
||||||
char *print_tablespace_mapping(TablespaceList *tablespacemappingptr);
|
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 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_ */
|
#endif /* _REPMGR_CONFIGFILE_H_ */
|
||||||
|
|||||||
20
configure
vendored
20
configure
vendored
@@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# 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>.
|
# Report bugs to <repmgr@googlegroups.com>.
|
||||||
#
|
#
|
||||||
@@ -582,8 +582,8 @@ MAKEFLAGS=
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='repmgr'
|
PACKAGE_NAME='repmgr'
|
||||||
PACKAGE_TARNAME='repmgr'
|
PACKAGE_TARNAME='repmgr'
|
||||||
PACKAGE_VERSION='5.2'
|
PACKAGE_VERSION='5.2.1'
|
||||||
PACKAGE_STRING='repmgr 5.2'
|
PACKAGE_STRING='repmgr 5.2.1'
|
||||||
PACKAGE_BUGREPORT='repmgr@googlegroups.com'
|
PACKAGE_BUGREPORT='repmgr@googlegroups.com'
|
||||||
PACKAGE_URL='https://repmgr.org/'
|
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.
|
# 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.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
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]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@@ -1242,7 +1242,7 @@ fi
|
|||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of repmgr 5.2:";;
|
short | recursive ) echo "Configuration of repmgr 5.2.1:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@@ -1316,7 +1316,7 @@ fi
|
|||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
repmgr configure 5.2
|
repmgr configure 5.2.1
|
||||||
generated by GNU Autoconf 2.69
|
generated by GNU Autoconf 2.69
|
||||||
|
|
||||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
@@ -1335,7 +1335,7 @@ cat >config.log <<_ACEOF
|
|||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
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
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
@@ -1824,7 +1824,7 @@ if test "$major_version_num" -lt '10'; then
|
|||||||
version_num_int=$(echo "$version_num"|
|
version_num_int=$(echo "$version_num"|
|
||||||
$SED -e 's/^\([0-9]*\)\.\([0-9]*\)$/\1\2/')
|
$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
|
as_fn_error $? "repmgr is not compatible with detected PostgreSQL version: $version_num" "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
@@ -2487,7 +2487,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
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
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@@ -2550,7 +2550,7 @@ _ACEOF
|
|||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
repmgr config.status 5.2
|
repmgr config.status 5.2.1
|
||||||
configured by $0, generated by GNU Autoconf 2.69,
|
configured by $0, generated by GNU Autoconf 2.69,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
|||||||
@@ -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.])
|
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"|
|
version_num_int=$(echo "$version_num"|
|
||||||
$SED -e 's/^\([[0-9]]*\)\.\([[0-9]]*\)$/\1\2/')
|
$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])
|
AC_MSG_ERROR([repmgr is not compatible with detected PostgreSQL version: $version_num])
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ get_controlfile(const char *DataDir)
|
|||||||
control_file_info->minRecoveryPointTLI = ptr->minRecoveryPointTLI;
|
control_file_info->minRecoveryPointTLI = ptr->minRecoveryPointTLI;
|
||||||
control_file_info->minRecoveryPoint = ptr->minRecoveryPoint;
|
control_file_info->minRecoveryPoint = ptr->minRecoveryPoint;
|
||||||
#else
|
#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);
|
exit(ERR_BAD_CONFIG);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1255,7 +1255,7 @@ bool
|
|||||||
pg_reload_conf(PGconn *conn)
|
pg_reload_conf(PGconn *conn)
|
||||||
{
|
{
|
||||||
PGresult *res = NULL;
|
PGresult *res = NULL;
|
||||||
bool success = false;
|
bool success = true;
|
||||||
|
|
||||||
res = PQexec(conn, "SELECT pg_catalog.pg_reload_conf()");
|
res = PQexec(conn, "SELECT pg_catalog.pg_reload_conf()");
|
||||||
|
|
||||||
|
|||||||
70
dirutil.c
70
dirutil.c
@@ -109,9 +109,56 @@ create_dir(const char *path)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
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))
|
switch (check_dir(path))
|
||||||
{
|
{
|
||||||
case DIR_NOENT:
|
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);
|
log_info(_("creating directory \"%s\"..."), path);
|
||||||
|
|
||||||
if (!create_dir(path))
|
if (!create_dir(path))
|
||||||
@@ -314,14 +361,23 @@ create_pg_dir(const char *path, bool force)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DIR_EMPTY:
|
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\""),
|
log_info(_("checking and correcting permissions on existing directory \"%s\""),
|
||||||
path);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ typedef enum
|
|||||||
} PgDirState;
|
} PgDirState;
|
||||||
|
|
||||||
extern int mkdir_p(char *path, mode_t omode);
|
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 DataDirState check_dir(const char *path);
|
||||||
extern bool create_dir(const char *path);
|
extern bool create_dir(const char *path);
|
||||||
|
|||||||
@@ -17,15 +17,91 @@
|
|||||||
|
|
||||||
<!-- remember to update the release date in ../repmgr_version.h.in -->
|
<!-- remember to update the release date in ../repmgr_version.h.in -->
|
||||||
|
|
||||||
|
<sect1 id="release-5.2.1">
|
||||||
|
<title id="release-current">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">
|
<sect1 id="release-5.2.0">
|
||||||
<title>Release 5.2.0</title>
|
<title>Release 5.2.0</title>
|
||||||
<para><emphasis>??? ?? ???, 2020</emphasis></para>
|
<para><emphasis>Thu 22 October, 2020</emphasis></para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
&repmgr; 5.2.0 is a major release.
|
&repmgr; 5.2.0 is a major release.
|
||||||
</para>
|
</para>
|
||||||
<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>
|
||||||
<para>
|
<para>
|
||||||
This release removes support for PostgreSQL 9.3, which was
|
This release removes support for PostgreSQL 9.3, which was
|
||||||
@@ -220,7 +296,7 @@
|
|||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="release-5.1.0">
|
<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><emphasis>Mon 13 April, 2020</emphasis></para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
|||||||
@@ -133,10 +133,10 @@
|
|||||||
&repmgr; 5.1
|
&repmgr; 5.1
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
<entry>
|
||||||
YES
|
NO
|
||||||
</entry>
|
</entry>
|
||||||
<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>
|
||||||
<entry>
|
<entry>
|
||||||
9.3, 9.4, 9.5, 9.6, 10, 11, 12
|
9.3, 9.4, 9.5, 9.6, 10, 11, 12
|
||||||
|
|||||||
@@ -260,16 +260,29 @@ pg_basebackup_options='--waldir=/path/to/wal-directory'</programlisting>
|
|||||||
upstream node if required.
|
upstream node if required.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Note that the upstream node must be running. In PostgreSQL 11 and earlier, an existing
|
The upstream node must be running so the correct replication configuration can be obtained.
|
||||||
<filename>recovery.conf</filename> will not be overwritten unless the
|
|
||||||
<option>-F/--force</option> option is provided.
|
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Execute <command>repmgr standby clone --replication-conf-only --dry-run</command>
|
If the standby is running, the replication configuration will not be written unless the
|
||||||
to check the prerequisites for creating the recovery configuration,
|
<option>-F/--force</option> option is provided.
|
||||||
and display the contents of the configuration which would be added without actually
|
|
||||||
making any changes.
|
|
||||||
</para>
|
</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>
|
</refsect1>
|
||||||
|
|
||||||
@@ -331,6 +344,25 @@ pg_basebackup_options='--waldir=/path/to/wal-directory'</programlisting>
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term><option>-R, --remote-user=USERNAME</option></term>
|
<term><option>-R, --remote-user=USERNAME</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@@ -346,14 +378,14 @@ pg_basebackup_options='--waldir=/path/to/wal-directory'</programlisting>
|
|||||||
<para>
|
<para>
|
||||||
Create recovery configuration for a previously cloned instance.
|
Create recovery configuration for a previously cloned instance.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
In PostgreSQL 11 and earlier, the replication configuration will be
|
|
||||||
written to <filename>recovery.conf</filename>.
|
|
||||||
</para>
|
|
||||||
<para>
|
<para>
|
||||||
In PostgreSQL 12 and later, the replication configuration will be
|
In PostgreSQL 12 and later, the replication configuration will be
|
||||||
written to <filename>postgresql.auto.conf</filename>.
|
written to <filename>postgresql.auto.conf</filename>.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
In PostgreSQL 11 and earlier, the replication configuration will be
|
||||||
|
written to <filename>recovery.conf</filename>.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|||||||
@@ -532,7 +532,7 @@ ALTER EXTENSION repmgr UPDATE</programlisting>
|
|||||||
<sect2>
|
<sect2>
|
||||||
<title>Upgrading the repmgr schema (PostgreSQL 13 and later)</title>
|
<title>Upgrading the repmgr schema (PostgreSQL 13 and later)</title>
|
||||||
<para>
|
<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
|
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;
|
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
|
schema, there is no convenient way of upgrading this; instead you'll just need
|
||||||
|
|||||||
245
repmgr--unpackaged--5.2.sql
Normal file
245
repmgr--unpackaged--5.2.sql
Normal 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;
|
||||||
@@ -733,7 +733,7 @@ do_standby_clone(void)
|
|||||||
drop_replication_slot_if_exists(source_conn, UNKNOWN_NODE_ID, local_node_record.slot_name);
|
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"),
|
log_hint(_("data directory (\"%s\") may need to be cleaned up manually"),
|
||||||
local_data_directory);
|
local_data_directory);
|
||||||
|
|
||||||
@@ -763,7 +763,7 @@ do_standby_clone(void)
|
|||||||
exit(ERR_BAD_CONFIG);
|
exit(ERR_BAD_CONFIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
appendPQExpBufferStr(&command, " ");
|
appendPQExpBufferChar(&command, ' ');
|
||||||
|
|
||||||
/* Somewhat inconsistent, but pg_verifybackup doesn't accept a -D option */
|
/* Somewhat inconsistent, but pg_verifybackup doesn't accept a -D option */
|
||||||
appendShellString(&command,
|
appendShellString(&command,
|
||||||
@@ -838,6 +838,16 @@ do_standby_clone(void)
|
|||||||
break;
|
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
|
* TODO: It might be nice to provide an option to have repmgr start the
|
||||||
* PostgreSQL server automatically
|
* PostgreSQL server automatically
|
||||||
@@ -1444,7 +1454,18 @@ _do_create_replication_conf(void)
|
|||||||
|
|
||||||
if (node_is_running == true)
|
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);
|
initPQExpBuffer(&command_output);
|
||||||
maxlen_snprintf(buf,
|
maxlen_snprintf(buf,
|
||||||
"ssh %s \"psql -Aqt \\\"%s\\\" -c \\\""
|
"psql -AqtX -d \\\"%s\\\" -c \\\""
|
||||||
" SELECT conninfo"
|
" SELECT conninfo"
|
||||||
" FROM repmgr.nodes"
|
" FROM repmgr.nodes"
|
||||||
" WHERE %s"
|
" WHERE %s"
|
||||||
" AND active IS TRUE"
|
" AND active IS TRUE"
|
||||||
"\\\"\"",
|
"\\\"",
|
||||||
config_file_options.barman_host,
|
|
||||||
repmgr_conninfo_buf.data,
|
repmgr_conninfo_buf.data,
|
||||||
where_condition);
|
where_condition);
|
||||||
|
|
||||||
termPQExpBuffer(&repmgr_conninfo_buf);
|
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)
|
if (command_success == false)
|
||||||
{
|
{
|
||||||
@@ -7759,7 +7783,9 @@ static void
|
|||||||
tablespace_data_append(TablespaceDataList *list, const char *name, const char *oid, const char *location)
|
tablespace_data_append(TablespaceDataList *list, const char *name, const char *oid, const char *location)
|
||||||
{
|
{
|
||||||
TablespaceDataListCell *cell = NULL;
|
TablespaceDataListCell *cell = NULL;
|
||||||
|
int oid_len = strlen(oid);
|
||||||
|
int name_len = strlen(name);
|
||||||
|
int location_len = strlen(location);
|
||||||
cell = (TablespaceDataListCell *) pg_malloc0(sizeof(TablespaceDataListCell));
|
cell = (TablespaceDataListCell *) pg_malloc0(sizeof(TablespaceDataListCell));
|
||||||
|
|
||||||
if (cell == NULL)
|
if (cell == NULL)
|
||||||
@@ -7768,13 +7794,13 @@ tablespace_data_append(TablespaceDataList *list, const char *name, const char *o
|
|||||||
exit(ERR_OUT_OF_MEMORY);
|
exit(ERR_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
cell->oid = pg_malloc(1 + strlen(oid));
|
cell->oid = pg_malloc0(1 + oid_len);
|
||||||
cell->name = pg_malloc(1 + strlen(name));
|
cell->name = pg_malloc0(1 + name_len);
|
||||||
cell->location = pg_malloc(1 + strlen(location));
|
cell->location = pg_malloc0(1 + location_len);
|
||||||
|
|
||||||
strncpy(cell->oid, oid, 1 + strlen(oid));
|
strncpy(cell->oid, oid, oid_len);
|
||||||
strncpy(cell->name, name, 1 + strlen(name));
|
strncpy(cell->name, name, name_len);
|
||||||
strncpy(cell->location, location, 1 + strlen(location));
|
strncpy(cell->location, location, location_len);
|
||||||
|
|
||||||
if (list->tail)
|
if (list->tail)
|
||||||
list->tail->next = cell;
|
list->tail->next = cell;
|
||||||
@@ -8908,6 +8934,8 @@ do_standby_help(void)
|
|||||||
#endif
|
#endif
|
||||||
printf(_(" --without-barman do not clone from Barman even if configured\n"));
|
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(_(" --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("");
|
puts("");
|
||||||
|
|
||||||
|
|||||||
@@ -560,7 +560,7 @@ void do_witness_help(void)
|
|||||||
|
|
||||||
printf(_("WITNESS UNREGISTER\n"));
|
printf(_("WITNESS UNREGISTER\n"));
|
||||||
puts("");
|
puts("");
|
||||||
printf(_(" \"witness register\" unregisters a witness node.\n"));
|
printf(_(" \"witness unregister\" unregisters a witness node.\n"));
|
||||||
puts("");
|
puts("");
|
||||||
printf(_(" --dry-run check prerequisites but don't make any changes\n"));
|
printf(_(" --dry-run check prerequisites but don't make any changes\n"));
|
||||||
printf(_(" -F, --force unregister when witness node not running\n"));
|
printf(_(" -F, --force unregister when witness node not running\n"));
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ typedef struct
|
|||||||
bool fast_checkpoint;
|
bool fast_checkpoint;
|
||||||
bool rsync_only;
|
bool rsync_only;
|
||||||
bool no_upstream_connection;
|
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 replication_user[MAXLEN];
|
||||||
char upstream_conninfo[MAXLEN];
|
char upstream_conninfo[MAXLEN];
|
||||||
bool without_barman;
|
bool without_barman;
|
||||||
|
|||||||
@@ -438,6 +438,11 @@ main(int argc, char **argv)
|
|||||||
runtime_options.replication_conf_only = true;
|
runtime_options.replication_conf_only = true;
|
||||||
break;
|
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 */
|
/* --verify-backup */
|
||||||
case OPT_VERIFY_BACKUP:
|
case OPT_VERIFY_BACKUP:
|
||||||
runtime_options.verify_backup = true;
|
runtime_options.verify_backup = true;
|
||||||
@@ -1105,10 +1110,25 @@ main(int argc, char **argv)
|
|||||||
exit(SUCCESS);
|
exit(SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
check_cli_parameters(action);
|
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
|
* Sanity checks for command line parameters completed by now; any further
|
||||||
* errors will be runtime ones
|
* 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
|
* options
|
||||||
* =====================================================================
|
* =====================================================================
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -99,6 +99,7 @@
|
|||||||
#define OPT_REPLICATION_CONFIG_OWNER 1046
|
#define OPT_REPLICATION_CONFIG_OWNER 1046
|
||||||
#define OPT_DB_CONNECTION 1047
|
#define OPT_DB_CONNECTION 1047
|
||||||
#define OPT_VERIFY_BACKUP 1048
|
#define OPT_VERIFY_BACKUP 1048
|
||||||
|
#define OPT_RECOVERY_MIN_APPLY_DELAY 1049
|
||||||
|
|
||||||
/* These options are for internal use only */
|
/* These options are for internal use only */
|
||||||
#define OPT_CONFIG_ARCHIVE_DIR 2001
|
#define OPT_CONFIG_ARCHIVE_DIR 2001
|
||||||
@@ -164,6 +165,7 @@ static struct option long_options[] =
|
|||||||
{"without-barman", no_argument, NULL, OPT_WITHOUT_BARMAN},
|
{"without-barman", no_argument, NULL, OPT_WITHOUT_BARMAN},
|
||||||
{"replication-conf-only", no_argument, NULL, OPT_REPLICATION_CONF_ONLY},
|
{"replication-conf-only", no_argument, NULL, OPT_REPLICATION_CONF_ONLY},
|
||||||
{"verify-backup", no_argument, NULL, OPT_VERIFY_BACKUP },
|
{"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 */
|
/* deprecate this once Pg11 and earlier are unsupported */
|
||||||
{"recovery-conf-only", no_argument, NULL, OPT_REPLICATION_CONF_ONLY},
|
{"recovery-conf-only", no_argument, NULL, OPT_REPLICATION_CONF_ONLY},
|
||||||
|
|
||||||
|
|||||||
3
repmgr.h
3
repmgr.h
@@ -77,8 +77,6 @@
|
|||||||
#define MIN_SUPPORTED_VERSION "9.4"
|
#define MIN_SUPPORTED_VERSION "9.4"
|
||||||
#define MIN_SUPPORTED_VERSION_NUM 90400
|
#define MIN_SUPPORTED_VERSION_NUM 90400
|
||||||
|
|
||||||
#define REPLICATION_TYPE_PHYSICAL 1
|
|
||||||
|
|
||||||
#define UNKNOWN_SERVER_VERSION_NUM -1
|
#define UNKNOWN_SERVER_VERSION_NUM -1
|
||||||
#define UNKNOWN_REPMGR_VERSION_NUM -1
|
#define UNKNOWN_REPMGR_VERSION_NUM -1
|
||||||
|
|
||||||
@@ -122,6 +120,7 @@
|
|||||||
#define DEFAULT_NODE_REJOIN_TIMEOUT 60 /* seconds */
|
#define DEFAULT_NODE_REJOIN_TIMEOUT 60 /* seconds */
|
||||||
#define DEFAULT_ARCHIVE_READY_WARNING 16 /* WAL files */
|
#define DEFAULT_ARCHIVE_READY_WARNING 16 /* WAL files */
|
||||||
#define DEFAULT_ARCHIVE_READY_CRITICAL 128 /* 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_WARNING 300 /* seconds */
|
||||||
#define DEFAULT_REPLICATION_LAG_CRITICAL 600 /* seconds */
|
#define DEFAULT_REPLICATION_LAG_CRITICAL 600 /* seconds */
|
||||||
#define DEFAULT_WITNESS_SYNC_INTERVAL 15 /* seconds */
|
#define DEFAULT_WITNESS_SYNC_INTERVAL 15 /* seconds */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#define REPMGR_VERSION_DATE ""
|
#define REPMGR_VERSION_DATE ""
|
||||||
#define REPMGR_VERSION "5.2dev"
|
#define REPMGR_VERSION "5.2.1"
|
||||||
#define REPMGR_VERSION_NUM 50200
|
#define REPMGR_VERSION_NUM 50201
|
||||||
#define REPMGR_RELEASE_DATE "2020-XX-XX"
|
#define REPMGR_RELEASE_DATE "2020-12-07"
|
||||||
#define PG_ACTUAL_VERSION_NUM
|
#define PG_ACTUAL_VERSION_NUM
|
||||||
|
|||||||
@@ -3921,6 +3921,7 @@ follow_new_primary(int new_primary_id)
|
|||||||
|
|
||||||
termPQExpBuffer(&event_details);
|
termPQExpBuffer(&event_details);
|
||||||
|
|
||||||
|
close_connection(&upstream_conn);
|
||||||
close_connection(&old_primary_conn);
|
close_connection(&old_primary_conn);
|
||||||
|
|
||||||
return FAILOVER_STATE_PRIMARY_REAPPEARED;
|
return FAILOVER_STATE_PRIMARY_REAPPEARED;
|
||||||
@@ -3931,6 +3932,8 @@ follow_new_primary(int new_primary_id)
|
|||||||
close_connection(&old_primary_conn);
|
close_connection(&old_primary_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close_connection(&upstream_conn);
|
||||||
|
|
||||||
return FAILOVER_STATE_FOLLOW_FAIL;
|
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);
|
time_t started_at = time(NULL);
|
||||||
int up_to;
|
int up_to;
|
||||||
bool sleep_now = false;
|
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"),
|
log_info(_("checking state of node \"%s\" (ID: %i), %i of %i attempts"),
|
||||||
node_info->node_name,
|
node_info->node_name,
|
||||||
|
|||||||
25
sysutils.c
25
sysutils.c
@@ -289,10 +289,19 @@ disable_wal_receiver(PGconn *conn)
|
|||||||
|
|
||||||
if (wal_retrieve_retry_interval < WALRECEIVER_DISABLE_TIMEOUT_VALUE)
|
if (wal_retrieve_retry_interval < WALRECEIVER_DISABLE_TIMEOUT_VALUE)
|
||||||
{
|
{
|
||||||
|
bool success;
|
||||||
|
|
||||||
log_notice(_("setting \"wal_retrieve_retry_interval\" to %i milliseconds"),
|
log_notice(_("setting \"wal_retrieve_retry_interval\" to %i milliseconds"),
|
||||||
new_wal_retrieve_retry_interval);
|
new_wal_retrieve_retry_interval);
|
||||||
alter_system_int(conn, "wal_retrieve_retry_interval", 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 */
|
/* make timeout configurable */
|
||||||
int i, timeout = 30;
|
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)
|
if (is_superuser_connection(conn, NULL) == false)
|
||||||
{
|
{
|
||||||
log_error(_("superuser connection required"));
|
log_error(_("superuser connection required"));
|
||||||
@@ -394,7 +409,13 @@ enable_wal_receiver(PGconn *conn, bool wait_startup)
|
|||||||
return UNKNOWN_PID;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user