diff --git a/configfile.c b/configfile.c index c590309c..f6a17321 100644 --- a/configfile.c +++ b/configfile.c @@ -260,6 +260,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList * options->tablespace_mapping.head = NULL; options->tablespace_mapping.tail = NULL; memset(options->recovery_min_apply_delay, 0, sizeof(options->recovery_min_apply_delay)); + options->recovery_min_apply_delay_provided = false; options->use_primary_conninfo_password = false; /*----------------- @@ -435,7 +436,10 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList * else if (strcmp(name, "restore_command") == 0) strncpy(options->restore_command, value, MAXLEN); else if (strcmp(name, "recovery_min_apply_delay") == 0) + { parse_time_unit_parameter(name, value, options->recovery_min_apply_delay, error_list); + options->recovery_min_apply_delay_provided = true; + } else if (strcmp(name, "use_primary_conninfo_password") == 0) options->use_primary_conninfo_password = parse_bool(value, name, error_list); diff --git a/configfile.h b/configfile.h index 7beb4961..13504e77 100644 --- a/configfile.h +++ b/configfile.h @@ -88,6 +88,7 @@ typedef struct char restore_command[MAXLEN]; TablespaceList tablespace_mapping; char recovery_min_apply_delay[MAXLEN]; + bool recovery_min_apply_delay_provided; bool use_primary_conninfo_password; /* node check settings */ @@ -152,7 +153,7 @@ typedef struct /* log settings */ \ "", "", "", DEFAULT_LOG_STATUS_INTERVAL, \ /* standby action settings */ \ - false, "", "", { NULL, NULL }, "", false, \ + false, "", "", { NULL, NULL }, "", false, false, \ /* node check settings */ \ DEFAULT_ARCHIVE_READY_WARNING, DEFAULT_ARCHIVE_READY_CRITICAL, \ DEFAULT_REPLICATION_LAG_WARNING, DEFAULT_REPLICATION_LAG_CRITICAL, \ diff --git a/repmgr-action-node.c b/repmgr-action-node.c index c97d81d8..3fbf8ca2 100644 --- a/repmgr-action-node.c +++ b/repmgr-action-node.c @@ -1598,6 +1598,7 @@ do_node_rejoin(void) t_node_info primary_node_record = T_NODE_INFO_INITIALIZER; bool success = true; + int server_version_num = UNKNOWN_SERVER_VERSION_NUM; /* check node is not actually running */ @@ -1646,6 +1647,12 @@ do_node_rejoin(void) /* check provided upstream connection */ upstream_conn = establish_db_connection_by_params(&source_conninfo, true); + /* sanity-checks for 9.3 */ + server_version_num = get_server_version(upstream_conn, NULL); + + if (server_version_num < 90400) + check_93_config(); + /* establish_db_connection(runtime_options.upstream_conninfo, true); */ if (get_primary_node_record(upstream_conn, &primary_node_record) == false) diff --git a/repmgr-action-standby.c b/repmgr-action-standby.c index f0160d50..bedff698 100644 --- a/repmgr-action-standby.c +++ b/repmgr-action-standby.c @@ -81,7 +81,6 @@ static bool check_upstream_config(PGconn *conn, int server_version_num, t_node_i static void check_primary_standby_version_match(PGconn *conn, PGconn *primary_conn); static void check_recovery_type(PGconn *conn); - static void initialise_direct_clone(t_node_info *node_record); static int run_basebackup(t_node_info *node_record); static int run_file_backup(t_node_info *node_record); @@ -1544,6 +1543,7 @@ do_standby_follow(void) RecordStatus record_status = RECORD_NOT_FOUND; int timer = 0; + int server_version_num = UNKNOWN_SERVER_VERSION_NUM; PQExpBufferData follow_output; bool success = false; @@ -1562,6 +1562,12 @@ do_standby_follow(void) /* check this is a standby */ check_recovery_type(local_conn); + /* sanity-checks for 9.3 */ + server_version_num = get_server_version(local_conn, NULL); + + if (server_version_num < 90400) + check_93_config(); + if (runtime_options.upstream_node_id != NO_UPSTREAM_NODE) { /* check not self! */ @@ -1682,13 +1688,11 @@ do_standby_follow(void) initPQExpBuffer(&follow_output); - success = do_standby_follow_internal( - primary_conn, + success = do_standby_follow_internal(primary_conn, &primary_node_record, &follow_output); - create_event_notification( - primary_conn, + create_event_notification(primary_conn, &config_file_options, config_file_options.node_id, "standby_follow", @@ -1718,6 +1722,9 @@ do_standby_follow(void) /* * Perform the actuall "follow" operation; this is executed by * "node rejoin" too. + * + * For PostgreSQL 9.3, ensure check_93_config() was called before calling + * this function. */ bool do_standby_follow_internal(PGconn *primary_conn, t_node_info *primary_node_record, PQExpBufferData *output) @@ -3103,6 +3110,10 @@ check_source_server() } } + /* disable configuration file options incompatible with 9.3 */ + if (source_server_version_num < 90400) + check_93_config(); + check_upstream_config(source_conn, source_server_version_num, &node_record, true); } @@ -3203,6 +3214,8 @@ check_source_server_via_barman() * Perform sanity check on upstream server configuration before starting cloning * process * + * For PostreSQL 9.3, ensure check_93_config() is called before calling this. + * * TODO: * - check user is qualified to perform base backup */ @@ -3253,6 +3266,12 @@ check_upstream_config(PGconn *conn, int server_version_num, t_node_info *node_in xlog_stream = false; /* Check that WAL level is set correctly */ + if (server_version_num < 90400) + { + i = guc_set(conn, "wal_level", "=", "hot_standby"); + wal_error_message = _("parameter \"wal_level\" must be set to \"hot_standby\""); + } + else { char *levels_pre96[] = { "hot_standby", @@ -3277,12 +3296,12 @@ check_upstream_config(PGconn *conn, int server_version_num, t_node_info *node_in if (server_version_num < 90600) { levels = (char **) levels_pre96; - wal_error_message = _("parameter 'wal_level' must be set to 'hot_standby' or 'logical'"); + wal_error_message = _("parameter \"wal_level\" must be set to \"hot_standby\" or \"logical\""); } else { levels = (char **) levels_96plus; - wal_error_message = _("parameter 'wal_level' must be set to 'replica' or 'logical'"); + wal_error_message = _("parameter \"wal_level\" must be set to \"replica\" or \"logical\""); } do @@ -4838,7 +4857,7 @@ create_recovery_file(t_node_info *node_record, t_conninfo_param_list *recovery_c log_debug("recovery.conf: %s", line); /* recovery_min_apply_delay = ... (optional) */ - if (*config_file_options.recovery_min_apply_delay) + if (config_file_options.recovery_min_apply_delay_provided == true) { maxlen_snprintf(line, "recovery_min_apply_delay = %s\n", config_file_options.recovery_min_apply_delay); diff --git a/repmgr-client-global.h b/repmgr-client-global.h index 334881ed..30018650 100644 --- a/repmgr-client-global.h +++ b/repmgr-client-global.h @@ -198,6 +198,7 @@ extern t_node_info target_node_info; extern int check_server_version(PGconn *conn, char *server_type, bool exit_on_error, char *server_version_string); +extern void check_93_config(void); extern bool create_repmgr_extension(PGconn *conn); extern int test_ssh_connection(char *host, char *remote_user); extern bool local_command(const char *command, PQExpBufferData *outputbuf); diff --git a/repmgr-client.c b/repmgr-client.c index f1a27e14..4105758c 100644 --- a/repmgr-client.c +++ b/repmgr-client.c @@ -1998,6 +1998,30 @@ check_server_version(PGconn *conn, char *server_type, bool exit_on_error, char * } + +/* + * check_93_config() + * + * Disable options not compatible with PostgreSQL 9.3 + */ +void +check_93_config(void) +{ + if (config_file_options.recovery_min_apply_delay_provided == true) + { + config_file_options.recovery_min_apply_delay_provided = false; + log_warning(_("configuration file option \"recovery_min_apply_delay\" not compatible with PostgreSQL 9.3, ignoring")); + } + + if (config_file_options.use_replication_slots == true) + { + config_file_options.use_replication_slots = false; + log_warning(_("configuration file option \"use_replication_slots\" not compatible with PostgreSQL 9.3, ignoring")); + log_hint(_("replication slots are available from PostgreSQL 9.4")); + } +} + + int test_ssh_connection(char *host, char *remote_user) {