repmgr: improve standby clone when synchronous replication in use

Fixes GitHub #277
This commit is contained in:
Ian Barwick
2017-03-16 16:40:54 +09:00
parent 478407fd86
commit 0ef532dcff
4 changed files with 55 additions and 26 deletions

View File

@@ -6,6 +6,7 @@
repmgr: if replication slots in use, where possible delete slot on old
upstream node after following new upstream (Ian)
repmgr: improve logging of rsync actions (Ian)
repmgr: improve `standby clone` when synchronous replication in use (Ian)
3.3 2016-12-27
repmgr: always log to STDERR even if log facility defined (Ian)

View File

@@ -33,6 +33,7 @@ char repmgr_schema[MAXLEN] = "";
char repmgr_schema_quoted[MAXLEN] = "";
static int _get_node_record(PGconn *conn, char *cluster, char *sqlquery, t_node_info *node_info);
static bool _set_config(PGconn *conn, const char *config_param, const char *sqlquery);
PGconn *
_establish_db_connection(const char *conninfo, const bool exit_on_error, const bool log_notice, const bool verbose_only)
@@ -1150,19 +1151,12 @@ stop_backup(PGconn *conn, char *last_wal_segment)
}
bool
set_config_bool(PGconn *conn, const char *config_param, bool state)
_set_config(PGconn *conn, const char *config_param, const char *sqlquery)
{
char sqlquery[QUERY_STR_LEN];
PGresult *res;
sqlquery_snprintf(sqlquery,
"SET %s TO %s",
config_param,
state ? "TRUE" : "FALSE");
log_verbose(LOG_DEBUG, "set_config_bool():\n%s\n", sqlquery);
res = PQexec(conn, sqlquery);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
@@ -1177,6 +1171,36 @@ set_config_bool(PGconn *conn, const char *config_param, bool state)
return true;
}
bool
set_config(PGconn *conn, const char *config_param, const char *config_value)
{
char sqlquery[QUERY_STR_LEN];
sqlquery_snprintf(sqlquery,
"SET %s TO '%s'",
config_param,
config_value);
log_verbose(LOG_DEBUG, "set_config():\n%s\n", sqlquery);
return _set_config(conn, config_param, sqlquery);
}
bool
set_config_bool(PGconn *conn, const char *config_param, bool state)
{
char sqlquery[QUERY_STR_LEN];
sqlquery_snprintf(sqlquery,
"SET %s TO %s",
config_param,
state ? "TRUE" : "FALSE");
log_verbose(LOG_DEBUG, "set_config_bool():\n%s\n", sqlquery);
return _set_config(conn, config_param, sqlquery);
}
/*
* witness_copy_node_records()

View File

@@ -124,6 +124,7 @@ int get_slot_record(PGconn *conn, char *slot_name, t_replication_slot *record)
bool drop_replication_slot(PGconn *conn, char *slot_name);
bool start_backup(PGconn *conn, char *first_wal_segment, bool fast_checkpoint);
bool stop_backup(PGconn *conn, char *last_wal_segment);
bool set_config(PGconn *conn, const char *config_param, const char *config_value);
bool set_config_bool(PGconn *conn, const char *config_param, bool state);
bool witness_copy_node_records(PGconn *masterconn, PGconn *witnessconn, char *cluster_name);
bool create_node_record(PGconn *conn, char *action, int node, char *type, int upstream_node, char *cluster_name, char *node_name, char *conninfo, int priority, char *slot_name, bool active);

View File

@@ -758,7 +758,7 @@ main(int argc, char **argv)
{
if (optind < argc)
{
if (runtime_options.host_param_provided == true)
if (runtime_options.host[0])
{
PQExpBufferData additional_host_arg;
initPQExpBuffer(&additional_host_arg);
@@ -2954,6 +2954,8 @@ do_standby_clone(void)
primary_conn = source_conn;
}
/*
* Sanity-check that the master node has a repmgr schema - if not
* present, fail with an error (unless -F/--force is used)
@@ -2973,6 +2975,7 @@ do_standby_clone(void)
log_warning(_("expected repmgr schema '%s' not found on master server\n"), get_repmgr_schema());
}
/* Fetch the source's data directory */
if (get_pg_setting(source_conn, "data_directory", master_data_directory) == false)
{
@@ -2994,6 +2997,8 @@ do_standby_clone(void)
log_hint(_("use -D/--data-dir to explicitly specify a data directory\n"));
}
/*
* Copy the source connection so that we have some default values,
* particularly stuff like passwords extracted from PGPASSFILE;
@@ -3017,6 +3022,18 @@ do_standby_clone(void)
strncpy(recovery_conninfo_str, upstream_node_record.conninfo_str, MAXLEN);
}
}
/* Finally, set `synchronous_commit` to `local` to avoid problems
* if synchronous commit is in use.
*/
if (primary_conn != NULL && PQstatus(primary_conn) == CONNECTION_OK)
{
if (set_config(primary_conn, "synchronous_commit", "local") == false)
{
exit(ERR_DB_QUERY);
}
}
}
if (mode == barman && PQstatus(source_conn) != CONNECTION_OK)
@@ -3578,9 +3595,6 @@ do_standby_clone(void)
/*
* We must create some PGDATA subdirectories because they are
* not included in the Barman backup.
*
* See class RsyncBackupExecutor in the Barman source (barman/backup_executor.py)
* for a definitive list of excluded directories.
*/
{
const char* const dirs[] = {
@@ -3591,14 +3605,14 @@ do_standby_clone(void)
/* Only from 9.4 */
"pg_dynshmem", "pg_logical", "pg_logical/snapshots", "pg_logical/mappings", "pg_replslot",
/* Already in 9.3 */
"pg_notify", "pg_serial", "pg_snapshots", "pg_stat", "pg_stat_tmp", "pg_tblspc",
"pg_serial", "pg_snapshots", "pg_stat", "pg_stat_tmp", "pg_tblspc",
"pg_twophase", "pg_xlog", 0
};
const int vers[] = {
100000,
90500,
90400, 90400, 90400, 90400, 90400,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, -100000, 0
};
for (i = 0; dirs[i]; i++)
@@ -3628,17 +3642,6 @@ do_standby_clone(void)
initPQExpBuffer(&tablespace_map);
}
/*
* From 9.1 default is to wait for a sync standby to ack, avoid that by
* turning off sync rep for this session
*/
if (set_config_bool(source_conn, "synchronous_commit", false) == false)
{
r = ERR_BAD_CONFIG;
retval = ERR_BAD_CONFIG;
goto stop_backup;
}
if (start_backup(source_conn, first_wal_segment, runtime_options.fast_checkpoint) == false)
{
r = ERR_BAD_BASEBACKUP;