Move configuration files and global/pg_control separately from data_directory

This commit is contained in:
Jaime Casanova
2010-09-30 14:07:01 -05:00
parent 4660c4ea13
commit dcc7c4492c

119
repmgr.c
View File

@@ -28,6 +28,7 @@
static void help(const char *progname); static void help(const char *progname);
static bool create_recovery_file(const char *data_dir); static bool create_recovery_file(const char *data_dir);
static int copy_remote_files(char *host, char *remote_path, char *local_path, bool is_directory);
static void do_standby_clone(void); static void do_standby_clone(void);
static void do_standby_promote(void); static void do_standby_promote(void);
@@ -231,10 +232,15 @@ do_standby_clone(void)
PGconn *conn; PGconn *conn;
PGresult *res; PGresult *res;
char sqlquery[8192]; char sqlquery[8192];
char script[8192];
int r, i; int r, i;
char data_dir_full_path[MAXLEN]; char master_data_directory[MAXLEN];
char master_config_file[MAXLEN];
char master_hba_file[MAXLEN];
char master_ident_file[MAXLEN];
char master_control_file[MAXLEN];
char local_control_file[MAXLEN];
const char *first_wal_segment = NULL; const char *first_wal_segment = NULL;
const char *last_wal_segment = NULL; const char *last_wal_segment = NULL;
@@ -404,18 +410,31 @@ do_standby_clone(void)
fprintf(stderr, "Starting backup...\n"); fprintf(stderr, "Starting backup...\n");
/* Get the data directory full path and the last subdirectory */ /* Get the data directory full path and the configuration files location */
sprintf(sqlquery, "SELECT setting " sprintf(sqlquery, "SELECT name, setting "
" FROM pg_settings WHERE name = 'data_directory'"); " FROM pg_settings "
" WHERE name IN ('data_directory', 'config_file', 'hba_file', 'ident_file')");
res = PQexec(conn, sqlquery); res = PQexec(conn, sqlquery);
if (PQresultStatus(res) != PGRES_TUPLES_OK) if (PQresultStatus(res) != PGRES_TUPLES_OK)
{ {
fprintf(stderr, "Can't get info about data directory: %s\n", PQerrorMessage(conn)); fprintf(stderr, "Can't get info about data directory and configuration files: %s\n", PQerrorMessage(conn));
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
return; return;
} }
strcpy(data_dir_full_path, PQgetvalue(res, 0, 0)); for (i = 0; i < PQntuples(res); i++)
{
if (strcmp(PQgetvalue(res, i, 0), "data_directory") == 0)
strcpy(master_data_directory, PQgetvalue(res, i, 1));
else if (strcmp(PQgetvalue(res, i, 0), "config_file") == 0)
strcpy(master_config_file, PQgetvalue(res, i, 1));
else if (strcmp(PQgetvalue(res, i, 0), "hba_file") == 0)
strcpy(master_hba_file, PQgetvalue(res, i, 1));
else if (strcmp(PQgetvalue(res, i, 0), "ident_file") == 0)
strcpy(master_ident_file, PQgetvalue(res, i, 1));
else
fprintf(stderr, _("uknown parameter: %s"), PQgetvalue(res, i, 0));
}
PQclear(res); PQclear(res);
/* /*
@@ -435,19 +454,42 @@ do_standby_clone(void)
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
/* rsync data directory to dest_dir */ /*
sprintf(script, "rsync --checksum --keep-dirlinks --compress --progress -r %s:%s/* %s", * 1) first move global/pg_control
host, data_dir_full_path, dest_dir); *
r = system(script); * 2) then move data_directory ommiting the files we have already moved and pg_xlog
if (r != 0) * content
{ *
fprintf(stderr, "Can't rsync data directory\n"); * 3) finally We need to backup configuration files (that could be on other directories, debian
/* * like systems likes to do that), so look at config_file, hba_file and ident_file but we
* we need to return but before that i will let the pg_stop_backup() * can omit external_pid_file ;)
* happen *
*/ * On error we need to return but before that execute pg_stop_backup()
} */
sprintf(master_control_file, "%s/global/pg_control", master_data_directory);
sprintf(local_control_file, "%s/global", dest_dir);
r = copy_remote_files(host, master_control_file, local_control_file, false);
if (r != 0)
goto stop_backup;
r = copy_remote_files(host, master_data_directory, dest_dir, true);
if (r != 0)
goto stop_backup;
r = copy_remote_files(host, master_config_file, dest_dir, false);
if (r != 0)
goto stop_backup;
r = copy_remote_files(host, master_hba_file, dest_dir, false);
if (r != 0)
goto stop_backup;
r = copy_remote_files(host, master_ident_file, dest_dir, false);
if (r != 0)
goto stop_backup;
stop_backup:
/* inform the master that we have finished the backup */ /* inform the master that we have finished the backup */
conn = PQconnectdbParams(keywords, values, true); conn = PQconnectdbParams(keywords, values, true);
if (!conn) if (!conn)
@@ -472,14 +514,14 @@ do_standby_clone(void)
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
if (verbose)
printf(_("%s requires primary to keep WAL files %s until at least %s"),
progname, first_wal_segment, last_wal_segment);
/* Now, if the rsync failed then exit */ /* Now, if the rsync failed then exit */
if (r != 0) if (r != 0)
return; return;
if (verbose)
printf(_("%s requires primary to keep WAL files %s until at least %s"),
progname, first_wal_segment, last_wal_segment);
/* Finally, write the recovery.conf file */ /* Finally, write the recovery.conf file */
create_recovery_file(dest_dir); create_recovery_file(dest_dir);
@@ -715,3 +757,34 @@ create_recovery_file(const char *data_dir)
return true; return true;
} }
static int
copy_remote_files(char *host, char *remote_path, char *local_path, bool is_directory)
{
char script[8192];
char options[8192];
int r;
sprintf(options, "--checksum --compress --progress --rsh=ssh");
if (is_directory)
{
strcat(options, " --archive --hard-links --exclude=pg_xlog* --exclude=pg_control");
sprintf(script, "rsync %s %s:%s/* %s",
options, host, remote_path, local_path);
}
else
{
sprintf(script, "rsync %s %s:%s %s/.",
options, host, remote_path, local_path);
}
r = system(script);
if (r != 0)
fprintf(stderr, _("Can't rsync from remote file or directory (%s:%s)\n"),
host, remote_path);
return r;
}