mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-26 00:26:30 +00:00
Write replication configuration for Pg12 and later
This commit is contained in:
22
configfile.c
22
configfile.c
@@ -1875,7 +1875,7 @@ tablespace_list_append(t_configuration_options *options, const char *arg)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
modify_auto_conf(const char *data_dir)
|
modify_auto_conf(const char *data_dir, KeyValueList *items)
|
||||||
{
|
{
|
||||||
PQExpBufferData auto_conf;
|
PQExpBufferData auto_conf;
|
||||||
PQExpBufferData auto_conf_tmp;
|
PQExpBufferData auto_conf_tmp;
|
||||||
@@ -1902,10 +1902,21 @@ modify_auto_conf(const char *data_dir)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX check return value
|
||||||
(void) ProcessPostgresConfigFile(fp, auto_conf.data, &config, NULL, NULL);
|
(void) ProcessPostgresConfigFile(fp, auto_conf.data, &config, NULL, NULL);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Append requested items to items extracted from the existing file.
|
||||||
|
*/
|
||||||
|
for (cell = items->head; cell; cell = cell->next)
|
||||||
|
{
|
||||||
|
key_value_list_replace_or_set(&config,
|
||||||
|
cell->key,
|
||||||
|
cell->value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
initPQExpBuffer(&auto_conf_tmp);
|
initPQExpBuffer(&auto_conf_tmp);
|
||||||
appendPQExpBuffer(&auto_conf_tmp, "%s.tmp",
|
appendPQExpBuffer(&auto_conf_tmp, "%s.tmp",
|
||||||
auto_conf.data);
|
auto_conf.data);
|
||||||
@@ -1943,6 +1954,13 @@ modify_auto_conf(const char *data_dir)
|
|||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: durable_rename() is not exposed to frontend code before Pg 10.
|
||||||
|
* We only really need to be modifying postgresql.auto.conf from Pg 12,
|
||||||
|
* but provide backwards compatibitilty for Pg 9.6 and earlier for the
|
||||||
|
* (unlikely) event that a repmgr built against one of those versions
|
||||||
|
* is being used against Pg 12 and later.
|
||||||
|
*/
|
||||||
// XXX check return values
|
// XXX check return values
|
||||||
#if (PG_ACTUAL_VERSION_NUM >= 100000)
|
#if (PG_ACTUAL_VERSION_NUM >= 100000)
|
||||||
(void) durable_rename(auto_conf_tmp.data, auto_conf.data, LOG);
|
(void) durable_rename(auto_conf_tmp.data, auto_conf.data, LOG);
|
||||||
|
|||||||
@@ -350,7 +350,7 @@ 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_connection_check_type(ConnectionCheckType type);
|
const char *print_connection_check_type(ConnectionCheckType type);
|
||||||
|
|
||||||
extern bool modify_auto_conf(const char *data_dir);
|
extern bool modify_auto_conf(const char *data_dir, KeyValueList *items);
|
||||||
|
|
||||||
extern bool ProcessRepmgrConfigFile(FILE *fp, const char *config_file, t_configuration_options *options, ItemList *error_list, ItemList *warning_list);
|
extern bool ProcessRepmgrConfigFile(FILE *fp, const char *config_file, t_configuration_options *options, ItemList *error_list, ItemList *warning_list);
|
||||||
|
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ do_standby_clone(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialise list of conninfo parameters which will later be used to
|
* Initialise list of conninfo parameters which will later be used to
|
||||||
* create the `primary_conninfo` string in recovery.conf .
|
* create the "primary_conninfo" recovery parameter.
|
||||||
*
|
*
|
||||||
* We'll initialise it with the host settings specified on the command
|
* We'll initialise it with the host settings specified on the command
|
||||||
* line. As it's possible the standby will be cloned from a node different
|
* line. As it's possible the standby will be cloned from a node different
|
||||||
@@ -6936,7 +6936,7 @@ check_recovery_type(PGconn *conn)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates a recovery.conf file for a standby
|
* Creates recovery configuration for a standby.
|
||||||
*
|
*
|
||||||
* A database connection pointer is required for escaping primary_conninfo
|
* A database connection pointer is required for escaping primary_conninfo
|
||||||
* parameters. When cloning from Barman and --no-upstream-connection supplied,
|
* parameters. When cloning from Barman and --no-upstream-connection supplied,
|
||||||
@@ -6946,39 +6946,42 @@ static bool
|
|||||||
create_recovery_file(t_node_info *node_record, t_conninfo_param_list *primary_conninfo, char *dest, bool as_file)
|
create_recovery_file(t_node_info *node_record, t_conninfo_param_list *primary_conninfo, char *dest, bool as_file)
|
||||||
{
|
{
|
||||||
PQExpBufferData recovery_file_buf;
|
PQExpBufferData recovery_file_buf;
|
||||||
|
PQExpBufferData primary_conninfo_buf;
|
||||||
char recovery_file_path[MAXPGPATH] = "";
|
char recovery_file_path[MAXPGPATH] = "";
|
||||||
FILE *recovery_file;
|
FILE *recovery_file;
|
||||||
mode_t um;
|
mode_t um;
|
||||||
|
|
||||||
/* create file in buffer */
|
KeyValueList recovery_config = {NULL, NULL};
|
||||||
initPQExpBuffer(&recovery_file_buf);
|
KeyValueListCell *cell = NULL;
|
||||||
|
|
||||||
|
initPQExpBuffer(&primary_conninfo_buf);
|
||||||
|
|
||||||
/* standby_mode = 'on' */
|
/* standby_mode = 'on' */
|
||||||
appendPQExpBufferStr(&recovery_file_buf,
|
key_value_list_set(&recovery_config,
|
||||||
"standby_mode = 'on'\n");
|
"standby_mode", "on");
|
||||||
|
|
||||||
/* primary_conninfo = '...' */
|
/* primary_conninfo = '...' */
|
||||||
write_primary_conninfo(&recovery_file_buf, primary_conninfo);
|
write_primary_conninfo(&primary_conninfo_buf, primary_conninfo);
|
||||||
|
key_value_list_set(&recovery_config,
|
||||||
|
"primary_conninfo", primary_conninfo_buf.data);
|
||||||
|
|
||||||
/* recovery_target_timeline = 'latest' */
|
/* recovery_target_timeline = 'latest' */
|
||||||
appendPQExpBufferStr(&recovery_file_buf,
|
key_value_list_set(&recovery_config,
|
||||||
"recovery_target_timeline = 'latest'\n");
|
"recovery_target_timeline", "latest");
|
||||||
|
|
||||||
|
|
||||||
/* recovery_min_apply_delay = ... (optional) */
|
/* recovery_min_apply_delay = ... (optional) */
|
||||||
if (config_file_options.recovery_min_apply_delay_provided == true)
|
if (config_file_options.recovery_min_apply_delay_provided == true)
|
||||||
{
|
{
|
||||||
appendPQExpBuffer(&recovery_file_buf,
|
key_value_list_set(&recovery_config,
|
||||||
"recovery_min_apply_delay = %s\n",
|
"recovery_min_apply_delay", config_file_options.recovery_min_apply_delay);
|
||||||
config_file_options.recovery_min_apply_delay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* primary_slot_name = '...' (optional, for 9.4 and later) */
|
/* primary_slot_name = '...' (optional, for 9.4 and later) */
|
||||||
if (config_file_options.use_replication_slots)
|
if (config_file_options.use_replication_slots)
|
||||||
{
|
{
|
||||||
appendPQExpBuffer(&recovery_file_buf,
|
key_value_list_set(&recovery_config,
|
||||||
"primary_slot_name = %s\n",
|
"primary_slot_name", node_record->slot_name);
|
||||||
node_record->slot_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6989,9 +6992,8 @@ create_recovery_file(t_node_info *node_record, t_conninfo_param_list *primary_co
|
|||||||
{
|
{
|
||||||
char *escaped = escape_recovery_conf_value(config_file_options.restore_command);
|
char *escaped = escape_recovery_conf_value(config_file_options.restore_command);
|
||||||
|
|
||||||
appendPQExpBuffer(&recovery_file_buf,
|
key_value_list_set(&recovery_config,
|
||||||
"restore_command = '%s'\n",
|
"restore_command", escaped);
|
||||||
escaped);
|
|
||||||
free(escaped);
|
free(escaped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6999,33 +7001,73 @@ create_recovery_file(t_node_info *node_record, t_conninfo_param_list *primary_co
|
|||||||
if (config_file_options.archive_cleanup_command[0] != '\0')
|
if (config_file_options.archive_cleanup_command[0] != '\0')
|
||||||
{
|
{
|
||||||
char *escaped = escape_recovery_conf_value(config_file_options.archive_cleanup_command);
|
char *escaped = escape_recovery_conf_value(config_file_options.archive_cleanup_command);
|
||||||
appendPQExpBuffer(&recovery_file_buf,
|
|
||||||
"archive_cleanup_command = '%s'\n",
|
key_value_list_set(&recovery_config,
|
||||||
escaped);
|
"archive_cleanup_command", escaped);
|
||||||
free(escaped);
|
free(escaped);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (as_file == true)
|
|
||||||
|
|
||||||
|
|
||||||
|
if (as_file == false)
|
||||||
{
|
{
|
||||||
maxpath_snprintf(recovery_file_path, "%s/%s", dest, RECOVERY_COMMAND_FILE);
|
/* create file in buffer */
|
||||||
log_debug("create_recovery_file(): creating \"%s\"...",
|
initPQExpBuffer(&recovery_file_buf);
|
||||||
recovery_file_path);
|
|
||||||
|
|
||||||
/* Set umask to 0600 */
|
for (cell = recovery_config.head; cell; cell = cell->next)
|
||||||
um = umask((~(S_IRUSR | S_IWUSR)) & (S_IRWXG | S_IRWXO));
|
|
||||||
recovery_file = fopen(recovery_file_path, "w");
|
|
||||||
umask(um);
|
|
||||||
|
|
||||||
if (recovery_file == NULL)
|
|
||||||
{
|
{
|
||||||
log_error(_("unable to create recovery.conf file at \"%s\""),
|
appendPQExpBuffer(&recovery_file_buf,
|
||||||
recovery_file_path);
|
"%s = '%s'\n",
|
||||||
log_detail("%s", strerror(errno));
|
cell->key, cell->value);
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug("recovery file is:\n%s", recovery_file_buf.data);
|
maxlen_snprintf(dest, "%s", recovery_file_buf.data);
|
||||||
|
|
||||||
|
termPQExpBuffer(&recovery_file_buf);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PostgreSQL 12 and later: modify postgresql.auto.conf
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (source_server_version_num >= 120000)
|
||||||
|
{
|
||||||
|
return modify_auto_conf(dest, &recovery_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PostgreSQL 11 and earlier: write recovery.conf
|
||||||
|
*/
|
||||||
|
maxpath_snprintf(recovery_file_path, "%s/%s", dest, RECOVERY_COMMAND_FILE);
|
||||||
|
log_debug("create_recovery_file(): creating \"%s\"...",
|
||||||
|
recovery_file_path);
|
||||||
|
|
||||||
|
/* Set umask to 0600 */
|
||||||
|
um = umask((~(S_IRUSR | S_IWUSR)) & (S_IRWXG | S_IRWXO));
|
||||||
|
recovery_file = fopen(recovery_file_path, "w");
|
||||||
|
umask(um);
|
||||||
|
|
||||||
|
if (recovery_file == NULL)
|
||||||
|
{
|
||||||
|
log_error(_("unable to create recovery.conf file at \"%s\""),
|
||||||
|
recovery_file_path);
|
||||||
|
log_detail("%s", strerror(errno));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug("recovery file is:\n%s", recovery_file_buf.data);
|
||||||
|
|
||||||
|
for (cell = recovery_config.head; cell; cell = cell->next)
|
||||||
|
{
|
||||||
|
initPQExpBuffer(&recovery_file_buf);
|
||||||
|
appendPQExpBuffer(&recovery_file_buf,
|
||||||
|
"%s = '%s'\n",
|
||||||
|
cell->key, cell->value);
|
||||||
|
|
||||||
if (fputs(recovery_file_buf.data, recovery_file) == EOF)
|
if (fputs(recovery_file_buf.data, recovery_file) == EOF)
|
||||||
{
|
{
|
||||||
@@ -7035,14 +7077,11 @@ create_recovery_file(t_node_info *node_record, t_conninfo_param_list *primary_co
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(recovery_file);
|
termPQExpBuffer(&recovery_file_buf);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
maxlen_snprintf(dest, "%s", recovery_file_buf.data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
termPQExpBuffer(&recovery_file_buf);
|
|
||||||
|
fclose(recovery_file);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -7132,8 +7171,7 @@ write_primary_conninfo(PQExpBufferData *dest, t_conninfo_param_list *param_list)
|
|||||||
|
|
||||||
escaped = escape_recovery_conf_value(conninfo_buf.data);
|
escaped = escape_recovery_conf_value(conninfo_buf.data);
|
||||||
|
|
||||||
appendPQExpBuffer(dest,
|
appendPQExpBufferStr(dest, escaped);
|
||||||
"primary_conninfo = '%s'\n", escaped);
|
|
||||||
|
|
||||||
free(escaped);
|
free(escaped);
|
||||||
free_conninfo_params(&env_conninfo);
|
free_conninfo_params(&env_conninfo);
|
||||||
|
|||||||
Reference in New Issue
Block a user