Use pg_basebackup

This commit is contained in:
Ian Barwick
2014-12-31 11:04:01 +09:00
parent 8b69b1e16f
commit 7700086703

103
repmgr.c
View File

@@ -57,6 +57,7 @@ static bool create_recovery_file(const char *data_dir);
static int test_ssh_connection(char *host, char *remote_user); static int test_ssh_connection(char *host, char *remote_user);
static int copy_remote_files(char *host, char *remote_user, char *remote_path, static int copy_remote_files(char *host, char *remote_user, char *remote_path,
char *local_path, bool is_directory); char *local_path, bool is_directory);
static int run_basebackup(void);
static bool check_parameters_for_action(const int action); static bool check_parameters_for_action(const int action);
static bool create_schema(PGconn *conn); static bool create_schema(PGconn *conn);
static bool copy_configuration(PGconn *masterconn, PGconn *witnessconn); static bool copy_configuration(PGconn *masterconn, PGconn *witnessconn);
@@ -786,7 +787,6 @@ do_standby_register(void)
{ {
PQfinish(conn); PQfinish(conn);
PQfinish(master_conn); PQfinish(master_conn);
/* XXX format version numbers */
log_err(_("%s needs versions of both master (%s) and standby (%s) to match.\n"), log_err(_("%s needs versions of both master (%s) and standby (%s) to match.\n"),
progname, master_version, standby_version); progname, master_version, standby_version);
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
@@ -850,6 +850,7 @@ do_standby_clone(void)
int r = 0, int r = 0,
retval = SUCCESS; retval = SUCCESS;
int i, int i,
is_standby_retval; is_standby_retval;
bool flag_success = false; bool flag_success = false;
@@ -864,8 +865,6 @@ do_standby_clone(void)
char master_stats_temp_directory[MAXFILENAME]; char master_stats_temp_directory[MAXFILENAME];
char local_stats_temp_directory[MAXFILENAME]; char local_stats_temp_directory[MAXFILENAME];
char master_control_file[MAXFILENAME];
char local_control_file[MAXFILENAME];
char master_config_file[MAXFILENAME]; char master_config_file[MAXFILENAME];
char local_config_file[MAXFILENAME]; char local_config_file[MAXFILENAME];
char master_hba_file[MAXFILENAME]; char master_hba_file[MAXFILENAME];
@@ -873,9 +872,6 @@ do_standby_clone(void)
char master_ident_file[MAXFILENAME]; char master_ident_file[MAXFILENAME];
char local_ident_file[MAXFILENAME]; char local_ident_file[MAXFILENAME];
char *first_wal_segment = NULL;
const char *last_wal_segment = NULL;
int master_version_num = 0; int master_version_num = 0;
/* /*
@@ -916,6 +912,7 @@ do_standby_clone(void)
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }
/* ZZZ check user is qualified to perform base backup */
/* Check we are cloning a primary node */ /* Check we are cloning a primary node */
is_standby_retval = is_standby(conn); is_standby_retval = is_standby(conn);
if (is_standby_retval) if (is_standby_retval)
@@ -938,6 +935,8 @@ do_standby_clone(void)
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }
/* ZZZ change this */
i = guc_set_typed(conn, "wal_keep_segments", ">=", i = guc_set_typed(conn, "wal_keep_segments", ">=",
runtime_options.wal_keep_segments, "integer"); runtime_options.wal_keep_segments, "integer");
if (i == 0 || i == -1) if (i == 0 || i == -1)
@@ -1020,7 +1019,7 @@ do_standby_clone(void)
PQclear(res); PQclear(res);
/* Get the data directory full path and the configuration files location */ /* Get the data directory full path and the configuration files location */
sqlquery_snprintf(sqlquery, /* sqlquery_snprintf(sqlquery,
"SELECT name, setting " "SELECT name, setting "
" FROM pg_settings " " FROM pg_settings "
" WHERE name IN ('data_directory', 'config_file', 'hba_file', 'ident_file', 'stats_temp_directory')"); " WHERE name IN ('data_directory', 'config_file', 'hba_file', 'ident_file', 'stats_temp_directory')");
@@ -1033,10 +1032,10 @@ do_standby_clone(void)
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }*/
/* We need all 5 parameters, and they can be retrieved only by superusers */ /* We need all 5 parameters, and they can be retrieved only by superusers */
if (PQntuples(res) != 5) /* if (PQntuples(res) != 5)
{ {
log_err("%s: STANDBY CLONE should be run by a SUPERUSER\n", progname); log_err("%s: STANDBY CLONE should be run by a SUPERUSER\n", progname);
PQclear(res); PQclear(res);
@@ -1061,6 +1060,7 @@ do_standby_clone(void)
log_warning(_("unknown parameter: %s\n"), PQgetvalue(res, i, 0)); log_warning(_("unknown parameter: %s\n"), PQgetvalue(res, i, 0));
} }
PQclear(res); PQclear(res);
*/
cluster_size = get_cluster_size(conn); cluster_size = get_cluster_size(conn);
if (cluster_size == NULL) if (cluster_size == NULL)
@@ -1096,14 +1096,14 @@ do_standby_clone(void)
strncpy(local_xlog_directory, master_xlog_directory, MAXFILENAME); strncpy(local_xlog_directory, master_xlog_directory, MAXFILENAME);
} }
r = test_ssh_connection(runtime_options.host, runtime_options.remote_user); /* r = test_ssh_connection(runtime_options.host, runtime_options.remote_user);
if (r != 0) if (r != 0)
{ {
log_err(_("%s: Aborting, remote host %s is not reachable.\n"), log_err(_("%s: Aborting, remote host %s is not reachable.\n"),
progname, runtime_options.host); progname, runtime_options.host);
PQfinish(conn); PQfinish(conn);
exit(ERR_BAD_SSH); exit(ERR_BAD_SSH);
} }*/
log_notice(_("Starting backup...\n")); log_notice(_("Starting backup...\n"));
@@ -1111,7 +1111,7 @@ do_standby_clone(void)
* in pg 9.1 default is to wait for a sync standby to ack, avoid that by * in pg 9.1 default is to wait for a sync standby to ack, avoid that by
* turning off sync rep for this session * turning off sync rep for this session
*/ */
sqlquery_snprintf(sqlquery, "SET synchronous_commit TO OFF"); /* sqlquery_snprintf(sqlquery, "SET synchronous_commit TO OFF");
res = PQexec(conn, sqlquery); res = PQexec(conn, sqlquery);
if (PQresultStatus(res) != PGRES_COMMAND_OK) if (PQresultStatus(res) != PGRES_COMMAND_OK)
{ {
@@ -1119,13 +1119,13 @@ do_standby_clone(void)
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }*/
/* /*
* inform the master we will start a backup and get the first XLog * inform the master we will start a backup and get the first XLog
* filename so we can say to the user we need those files * filename so we can say to the user we need those files
*/ */
sqlquery_snprintf( /* sqlquery_snprintf(
sqlquery, sqlquery,
"SELECT pg_xlogfile_name(pg_start_backup('repmgr_standby_clone_%ld'))", "SELECT pg_xlogfile_name(pg_start_backup('repmgr_standby_clone_%ld'))",
time(NULL)); time(NULL));
@@ -1137,8 +1137,8 @@ do_standby_clone(void)
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }*/
/*
if (runtime_options.verbose) if (runtime_options.verbose)
{ {
char *first_wal_seg_pq = PQgetvalue(res, 0, 0); char *first_wal_seg_pq = PQgetvalue(res, 0, 0);
@@ -1148,9 +1148,12 @@ do_standby_clone(void)
xsnprintf(first_wal_segment, buf_sz + 1, "%s", first_wal_seg_pq); xsnprintf(first_wal_segment, buf_sz + 1, "%s", first_wal_seg_pq);
} }
PQclear(res); PQclear(res);*/
/* Check the directory could be used as a PGDATA dir */ /* Check the directory could be used as a PGDATA dir */
/* ZZZ pg_basebackup can do this too, but better to check explicitly */
/* ZZZ maybe check tablespace, xlog dirs too */
if (!create_pg_dir(local_data_directory, runtime_options.force)) if (!create_pg_dir(local_data_directory, runtime_options.force))
{ {
log_err(_("%s: couldn't use directory %s ...\nUse --force option to force\n"), log_err(_("%s: couldn't use directory %s ...\nUse --force option to force\n"),
@@ -1175,7 +1178,7 @@ do_standby_clone(void)
*/ */
/* need to create the global sub directory */ /* need to create the global sub directory */
maxlen_snprintf(master_control_file, "%s/global/pg_control", /* maxlen_snprintf(master_control_file, "%s/global/pg_control",
master_data_directory); master_data_directory);
maxlen_snprintf(local_control_file, "%s/global", local_data_directory); maxlen_snprintf(local_control_file, "%s/global", local_data_directory);
log_info(_("standby clone: master control file '%s'\n"), log_info(_("standby clone: master control file '%s'\n"),
@@ -1209,7 +1212,7 @@ do_standby_clone(void)
log_warning(_("standby clone: failed copying master data directory '%s'\n"), log_warning(_("standby clone: failed copying master data directory '%s'\n"),
master_data_directory); master_data_directory);
goto stop_backup; goto stop_backup;
} }*/
/* /*
* Copy tablespace locations, i'm doing this separately because i couldn't * Copy tablespace locations, i'm doing this separately because i couldn't
@@ -1218,7 +1221,7 @@ do_standby_clone(void)
* test_mode but it does not hurt too much (except if a tablespace is * test_mode but it does not hurt too much (except if a tablespace is
* created during the test) * created during the test)
*/ */
if (master_version_num < 90200) /* if (master_version_num < 90200)
sqlquery_snprintf(sqlquery, sqlquery_snprintf(sqlquery,
"SELECT spclocation " "SELECT spclocation "
" FROM pg_tablespace " " FROM pg_tablespace "
@@ -1254,8 +1257,8 @@ do_standby_clone(void)
goto stop_backup; goto stop_backup;
} }
} }
PQclear(res); PQclear(res);*/
/*
log_info(_("standby clone: master config file '%s'\n"), 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, r = copy_remote_files(runtime_options.host, runtime_options.remote_user,
master_config_file, local_config_file, master_config_file, local_config_file,
@@ -1287,8 +1290,17 @@ do_standby_clone(void)
log_warning(_("standby clone: failed copying master ident file '%s'\n"), log_warning(_("standby clone: failed copying master ident file '%s'\n"),
master_ident_file); master_ident_file);
goto stop_backup; goto stop_backup;
}*/
r = run_basebackup();
if (r != 0)
{
log_warning(_("standby clone: base backup failed\n"));
goto stop_backup;
} }
// ZZZ possibly add sanity checks, e.g. that backup_label created?
/* we success so far, flag that to allow a better HINT */ /* we success so far, flag that to allow a better HINT */
flag_success = true; flag_success = true;
@@ -1298,7 +1310,7 @@ stop_backup:
* Inform the master that we have finished the backup. * Inform the master that we have finished the backup.
*/ */
log_notice(_("Finishing backup...\n")); log_notice(_("Finishing backup...\n"));
sqlquery_snprintf(sqlquery, "SELECT pg_xlogfile_name(pg_stop_backup())"); /* sqlquery_snprintf(sqlquery, "SELECT pg_xlogfile_name(pg_stop_backup())");
log_debug(_("standby clone: %s\n"), sqlquery); log_debug(_("standby clone: %s\n"), sqlquery);
res = PQexec(conn, sqlquery); res = PQexec(conn, sqlquery);
@@ -1313,18 +1325,18 @@ stop_backup:
if (runtime_options.verbose) if (runtime_options.verbose)
log_info(_("%s requires primary to keep WAL files %s until at least %s\n"), log_info(_("%s requires primary to keep WAL files %s until at least %s\n"),
progname, first_wal_segment, last_wal_segment); progname, first_wal_segment, last_wal_segment);*/
/* Finished with the database connection now */ /* Finished with the database connection now */
PQclear(res); /* PQclear(res);
PQfinish(conn); PQfinish(conn);*/
/* /*
* Only free the first_wal_segment since it was copied out of the * Only free the first_wal_segment since it was copied out of the
* pqresult. * pqresult.
*/ */
free(first_wal_segment); /* free(first_wal_segment);
first_wal_segment = NULL; first_wal_segment = NULL;*/
/* If the rsync failed then exit */ /* If the rsync failed then exit */
if (r != 0) if (r != 0)
@@ -1337,16 +1349,16 @@ stop_backup:
/* /*
* We need to create the pg_xlog sub directory too. * We need to create the pg_xlog sub directory too.
*/ */
if (!create_dir(local_xlog_directory)) /* if (!create_dir(local_xlog_directory))
{ {
log_err(_("%s: couldn't create directory %s, you will need to do it manually...\n"), log_err(_("%s: couldn't create directory %s, you will need to do it manually...\n"),
progname, local_xlog_directory); progname, local_xlog_directory);
r = ERR_NEEDS_XLOG; /* continue, but eventually exit returning r = ERR_NEEDS_XLOG; */ /* continue, but eventually exit returning
* error */ * error */
} //}
/* Finally, write the recovery.conf file */ /* Finally, write the recovery.conf file */
create_recovery_file(local_data_directory); //create_recovery_file(local_data_directory);
/* /*
* We don't start the service yet because we still may want to move the * We don't start the service yet because we still may want to move the
@@ -1601,7 +1613,6 @@ do_standby_follow(void)
{ {
PQfinish(conn); PQfinish(conn);
PQfinish(master_conn); PQfinish(master_conn);
/* XXX format version numbers */
log_err(_("%s needs versions of both master (%s) and standby (%s) to match.\n"), log_err(_("%s needs versions of both master (%s) and standby (%s) to match.\n"),
progname, master_version, standby_version); progname, master_version, standby_version);
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
@@ -2000,6 +2011,7 @@ help(const char *progname)
/* /*
* Creates a recovery file for a standby. * Creates a recovery file for a standby.
* ZZZ not needed with basebackup?
*/ */
static bool static bool
create_recovery_file(const char *data_dir) create_recovery_file(const char *data_dir)
@@ -2167,6 +2179,29 @@ copy_remote_files(char *host, char *remote_user, char *remote_path,
return r; return r;
} }
static int
run_basebackup()
{
char script[MAXLEN];
int r = 0;
maxlen_snprintf(script,
"%s/pg_basebackup -h %s -p %s -D %s -l \"repmgr base backup\" --write-recovery-conf",
options.pg_bindir,
runtime_options.host,
runtime_options.masterport,
runtime_options.dest_dir
);
log_info(_("Executing: '%s'\n"), script);
r = system(script);
/* ZZZ handle return values ? */
log_debug(_("r = %i, %i\n"), r, WEXITSTATUS(r));
return r;
}
/* /*
* Tries to avoid useless or conflicting parameters * Tries to avoid useless or conflicting parameters
@@ -2306,8 +2341,6 @@ check_parameters_for_action(const int action)
return ok; return ok;
} }
static bool static bool
create_schema(PGconn *conn) create_schema(PGconn *conn)
{ {