From 1f9b19f3ff19a63d84925f8e8aedc8be1b059ba3 Mon Sep 17 00:00:00 2001 From: Ian Barwick Date: Thu, 5 Mar 2015 13:46:55 +0900 Subject: [PATCH] Add configuration option `ignore_external_config_files` --- FAQ.md | 28 ++++++++++++++++ config.c | 2 ++ config.h | 3 +- repmgr.c | 82 +++++++++++++++++++++++++++++++--------------- repmgr.conf.sample | 14 +++++++- 5 files changed, 100 insertions(+), 29 deletions(-) diff --git a/FAQ.md b/FAQ.md index 6d7667aa..2d99ea02 100644 --- a/FAQ.md +++ b/FAQ.md @@ -1,6 +1,7 @@ FAQ - Frequently Asked Questions about repmgr ============================================= +This FAQ applies to `repmgr` 3.0 and later. General ------- @@ -40,12 +41,39 @@ General Yes, this is no problem. +- How can a failed master be re-added as a standby? + - Is there an easy way to check my master server is correctly configured for use with `repmgr`? Yes - execute `repmgr` with the `--check-upstream-config` option, and it will let you know which items in `postgresql.conf` need to be modified. +- Even though I specified custom `rsync` options, `rempgr` appends + the `--checksum` - why? + + When syncing a stale data directory from an active server, it's + essential that `rsync` compares the content of files rather than + just timestamp and size, to ensure that all changed files are + copied and prevent corruption. + +- How can I prevent `rempgr` from copying `postgresql.conf` and + `pg_hba.conf` from the PostgreSQL configuration directory in `/etc`? + + Include the option `ignore_external_config_files=1` in `repmgr.conf` + +- How can I prevent `rempgr` from copying local configuration files + in the data directory? + + If you're updating an existing but stale data directory which + contains e.g. configuration files you don't want to be overwritten + with the same file from the master, specify the files in the + `rsync_options` configuration option, e.g. + + rsync_options=--exclude=postgresql.local.conf + + This option is only available when using the `--rsync-only` option. + `repmgrd` --------- diff --git a/config.c b/config.c index cf521991..10a9e8fe 100644 --- a/config.c +++ b/config.c @@ -207,6 +207,8 @@ parse_config(const char *config_file, t_configuration_options *options) options->retry_promote_interval_secs = atoi(value); else if (strcmp(name, "use_replication_slots") == 0) options->use_replication_slots = atoi(value); + else if (strcmp(name, "ignore_external_config_files") == 0) + options->ignore_external_config_files = atoi(value); else if (strcmp(name, "tablespace_mapping") == 0) tablespace_list_append(options, value); else diff --git a/config.h b/config.h index ccec3004..2ca5d354 100644 --- a/config.h +++ b/config.h @@ -61,10 +61,11 @@ typedef struct int monitor_interval_secs; int retry_promote_interval_secs; int use_replication_slots; + int ignore_external_config_files; TablespaceList tablespace_mapping; } t_configuration_options; -#define T_CONFIGURATION_OPTIONS_INITIALIZER { "", -1, NO_UPSTREAM_NODE, "", MANUAL_FAILOVER, -1, "", "", "", "", "", "", "", -1, -1, -1, "", "", "", "", 0, 0, 0, {NULL, NULL} } +#define T_CONFIGURATION_OPTIONS_INITIALIZER { "", -1, NO_UPSTREAM_NODE, "", MANUAL_FAILOVER, -1, "", "", "", "", "", "", "", -1, -1, -1, "", "", "", "", 0, 0, 0, 0, {NULL, NULL} } bool parse_config(const char *config_file, t_configuration_options *options); diff --git a/repmgr.c b/repmgr.c index 9b841551..8eb76153 100644 --- a/repmgr.c +++ b/repmgr.c @@ -903,12 +903,15 @@ do_standby_clone(void) char master_config_file[MAXFILENAME] = ""; char local_config_file[MAXFILENAME] = ""; + bool config_file_outside_pgdata = false; char master_hba_file[MAXFILENAME] = ""; char local_hba_file[MAXFILENAME] = ""; + bool hba_file_outside_pgdata = false; char master_ident_file[MAXFILENAME] = ""; char local_ident_file[MAXFILENAME] = ""; + bool ident_file_outside_pgdata = false; char master_control_file[MAXFILENAME] = ""; char local_control_file[MAXFILENAME] = ""; @@ -1051,6 +1054,7 @@ do_standby_clone(void) { if(strcmp(PQgetvalue(res, i, 2), "f") == 0) { + config_file_outside_pgdata = true; config_file_copy_required = true; strncpy(master_config_file, PQgetvalue(res, i, 1), MAXFILENAME); } @@ -1059,6 +1063,7 @@ do_standby_clone(void) { if(strcmp(PQgetvalue(res, i, 2), "f") == 0) { + hba_file_outside_pgdata = true; config_file_copy_required = true; strncpy(master_hba_file, PQgetvalue(res, i, 1), MAXFILENAME); } @@ -1067,6 +1072,7 @@ do_standby_clone(void) { if(strcmp(PQgetvalue(res, i, 2), "f") == 0) { + ident_file_outside_pgdata = true; config_file_copy_required = true; strncpy(master_ident_file, PQgetvalue(res, i, 1), MAXFILENAME); } @@ -1088,6 +1094,9 @@ do_standby_clone(void) strncpy(local_hba_file, runtime_options.dest_dir, MAXFILENAME); strncpy(local_ident_file, runtime_options.dest_dir, MAXFILENAME); } + /* + * Otherwise use the same data directory as on the remote host + */ else { strncpy(local_data_directory, master_data_directory, MAXFILENAME); @@ -1099,8 +1108,7 @@ do_standby_clone(void) log_notice(_("Starting backup...\n")); /* - * When using rsync only, we need to check the SSH connection - * early + * When using rsync only, we need to check the SSH connection early */ if(runtime_options.rsync_only) { @@ -1128,7 +1136,6 @@ do_standby_clone(void) if(runtime_options.rsync_only) { - /* * From pg 9.1 default is to wait for a sync standby to ack, avoid that by * turning off sync rep for this session @@ -1294,43 +1301,64 @@ do_standby_clone(void) if(strlen(master_config_file)) { - log_info(_("standby clone: master config file '%s'\n"), master_config_file); - r = copy_remote_files(runtime_options.host, runtime_options.remote_user, - master_config_file, local_config_file, false, server_version_num); - if (r != 0) + if(options.ignore_external_config_files && config_file_outside_pgdata) { - log_warning(_("standby clone: failed copying master config file '%s'\n"), - master_config_file); - retval = ERR_BAD_SSH; - goto stop_backup; + log_notice(_("standby clone: not copying master config file '%s'\n"), master_config_file); + } + else + { + log_info(_("standby clone: master config file '%s'\n"), master_config_file); + r = copy_remote_files(runtime_options.host, runtime_options.remote_user, + master_config_file, local_config_file, false, server_version_num); + if (r != 0) + { + log_warning(_("standby clone: failed copying master config file '%s'\n"), + master_config_file); + retval = ERR_BAD_SSH; + goto stop_backup; + } } } if(strlen(master_hba_file)) { - log_info(_("standby clone: master hba file '%s'\n"), master_hba_file); - r = copy_remote_files(runtime_options.host, runtime_options.remote_user, - master_hba_file, local_hba_file, false, server_version_num); - if (r != 0) + if(options.ignore_external_config_files && hba_file_outside_pgdata) { - log_warning(_("standby clone: failed copying master hba file '%s'\n"), - master_hba_file); - retval = ERR_BAD_SSH; - goto stop_backup; + log_notice(_("standby clone: not copying master config file '%s'\n"), master_hba_file); + } + else + { + log_info(_("standby clone: master hba file '%s'\n"), master_hba_file); + r = copy_remote_files(runtime_options.host, runtime_options.remote_user, + master_hba_file, local_hba_file, false, server_version_num); + if (r != 0) + { + log_warning(_("standby clone: failed copying master hba file '%s'\n"), + master_hba_file); + retval = ERR_BAD_SSH; + goto stop_backup; + } } } if(strlen(master_ident_file)) { - log_info(_("standby clone: master ident file '%s'\n"), master_ident_file); - r = copy_remote_files(runtime_options.host, runtime_options.remote_user, - master_ident_file, local_ident_file, false, server_version_num); - if (r != 0) + if(options.ignore_external_config_files && ident_file_outside_pgdata) { - log_warning(_("standby clone: failed copying master ident file '%s'\n"), - master_ident_file); - retval = ERR_BAD_SSH; - goto stop_backup; + log_notice(_("standby clone: not copying master config file '%s'\n"), master_ident_file); + } + else + { + log_info(_("standby clone: master ident file '%s'\n"), master_ident_file); + r = copy_remote_files(runtime_options.host, runtime_options.remote_user, + master_ident_file, local_ident_file, false, server_version_num); + if (r != 0) + { + log_warning(_("standby clone: failed copying master ident file '%s'\n"), + master_ident_file); + retval = ERR_BAD_SSH; + goto stop_backup; + } } } diff --git a/repmgr.conf.sample b/repmgr.conf.sample index 0f0e9bae..ab752a98 100644 --- a/repmgr.conf.sample +++ b/repmgr.conf.sample @@ -61,7 +61,19 @@ pg_bindir=/usr/bin/ # # retry_promote_interval_secs=300 +# Command line arguments for pg_basebackup +# +# pg_basebackup_options= + +# Don't copy configuration files located outside the data directory. +# +# ignore_external_config_files=1 +# +# By default repmgr will attempt to copy postgresql.conf, pg_hba.conf and pg_ident.conf +# from the master, however this may not be desirable if the files are e.g.maintained +# by configuration management software. + # physical replication slots - PostgreSQL 9.4 and later only # -# use_replication_slots=1 \ No newline at end of file +# use_replication_slots=1