mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2025-02-03 14:01:57 +02:00
Strip off archive backup mode
This mode is not actually necessary if we consider that the core of pg_rman is the obtention of differential and full backups, the server being afterwards in charge to recover necessary WAL segments from the archive. Regression tests and documentation are updated in accordance to the changes.
This commit is contained in:
parent
5988e6bd10
commit
820485d225
383
backup.c
383
backup.c
@ -35,24 +35,16 @@ static parray *cleanup_list;
|
||||
* Backup routines
|
||||
*/
|
||||
static void backup_cleanup(bool fatal, void *userdata);
|
||||
static void delete_old_files(const char *root,
|
||||
parray *files, int keep_files,
|
||||
int keep_days, bool is_arclog);
|
||||
static void backup_files(const char *from_root, const char *to_root,
|
||||
parray *files, parray *prev_files, const XLogRecPtr *lsn, bool compress, const char *prefix);
|
||||
static parray *do_backup_database(parray *backup_list, pgBackupOption bkupopt);
|
||||
static parray *do_backup_arclog(parray *backup_list);
|
||||
static void confirm_block_size(const char *name, int blcksz);
|
||||
static void pg_start_backup(const char *label, bool smooth, pgBackup *backup);
|
||||
static void pg_stop_backup(pgBackup *backup);
|
||||
static void pg_switch_xlog(pgBackup *backup);
|
||||
static bool pg_is_standby(void);
|
||||
static void get_lsn(PGresult *res, XLogRecPtr *lsn);
|
||||
static void get_xid(PGresult *res, uint32 *xid);
|
||||
|
||||
static void delete_arclog_link(void);
|
||||
static void delete_online_wal_backup(void);
|
||||
|
||||
static bool dirExists(const char *path);
|
||||
|
||||
static void add_files(parray *files, const char *root, bool add_root, bool is_pgdata);
|
||||
@ -84,10 +76,6 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt)
|
||||
/* repack the options */
|
||||
bool smooth_checkpoint = bkupopt.smooth_checkpoint;
|
||||
|
||||
/* Leave in case of archive mode */
|
||||
if (current.backup_mode == BACKUP_MODE_ARCHIVE)
|
||||
return NULL;
|
||||
|
||||
/* Block backup operations on a standby */
|
||||
if (pg_is_standby())
|
||||
elog(ERROR_SYSTEM, _("Backup cannot run on a standby."));
|
||||
@ -411,16 +399,12 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt)
|
||||
current.data_bytes += file->read_size;
|
||||
else if (current.backup_mode == BACKUP_MODE_FULL)
|
||||
current.data_bytes += file->size;
|
||||
|
||||
/* Count total amount of data for backup */
|
||||
if (file->write_size != BYTES_INVALID)
|
||||
current.backup_bytes += file->write_size;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
printf(_("database backup completed(written: " INT64_FORMAT " Backup: " INT64_FORMAT ")\n"),
|
||||
current.data_bytes, current.backup_bytes);
|
||||
printf(_("database backup completed(Backup: " INT64_FORMAT ")\n"),
|
||||
current.data_bytes);
|
||||
printf(_("========================================\n"));
|
||||
}
|
||||
|
||||
@ -428,155 +412,14 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Backup archived WAL incrementally.
|
||||
*/
|
||||
static parray *
|
||||
do_backup_arclog(parray *backup_list)
|
||||
{
|
||||
int i;
|
||||
parray *files;
|
||||
parray *prev_files = NULL; /* file list of previous database backup */
|
||||
char path[MAXPGPATH];
|
||||
char timeline_dir[MAXPGPATH];
|
||||
char prev_file_txt[MAXPGPATH];
|
||||
pgBackup *prev_backup;
|
||||
int64 arclog_write_bytes = 0;
|
||||
char last_wal[MAXFNAMELEN];
|
||||
|
||||
Assert(current.backup_mode == BACKUP_MODE_ARCHIVE ||
|
||||
current.backup_mode == BACKUP_MODE_INCREMENTAL ||
|
||||
current.backup_mode == BACKUP_MODE_FULL);
|
||||
|
||||
/* Block backup operations on a standby */
|
||||
if (pg_is_standby())
|
||||
elog(ERROR_SYSTEM, _("Backup cannot run on a standby."));
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
printf(_("========================================\n"));
|
||||
printf(_("archived WAL backup start\n"));
|
||||
}
|
||||
|
||||
/* initialize size summary */
|
||||
current.arclog_bytes = 0;
|
||||
|
||||
/*
|
||||
* Switch xlog if database is not backed up, current timeline of
|
||||
* server is obtained here.
|
||||
*/
|
||||
if ((uint32) current.stop_lsn == 0)
|
||||
pg_switch_xlog(¤t);
|
||||
|
||||
/*
|
||||
* Check if there is a full backup present on current timeline.
|
||||
* For an incremental or full backup, we are sure that there is one
|
||||
* so this error can be bypassed safely.
|
||||
*/
|
||||
if (current.backup_mode == BACKUP_MODE_ARCHIVE &&
|
||||
catalog_get_last_data_backup(backup_list, current.tli) == NULL)
|
||||
elog(ERROR_SYSTEM, _("No valid full or incremental backup detected "
|
||||
"on current timeline "));
|
||||
|
||||
/*
|
||||
* To take incremental backup, the file list of the last completed
|
||||
* database backup is needed.
|
||||
*/
|
||||
prev_backup = catalog_get_last_arclog_backup(backup_list, current.tli);
|
||||
if (verbose && prev_backup == NULL)
|
||||
printf(_("no previous full backup, performing a full backup instead\n"));
|
||||
|
||||
if (prev_backup)
|
||||
{
|
||||
pgBackupGetPath(prev_backup, prev_file_txt, lengthof(prev_file_txt),
|
||||
ARCLOG_FILE_LIST);
|
||||
prev_files = dir_read_file_list(arclog_path, prev_file_txt);
|
||||
}
|
||||
|
||||
/* list files with the logical path. omit ARCLOG_PATH */
|
||||
files = parray_new();
|
||||
dir_list_file(files, arclog_path, NULL, true, false);
|
||||
|
||||
/* remove WALs archived after pg_stop_backup()/pg_switch_xlog() */
|
||||
xlog_fname(last_wal, current.tli, current.stop_lsn);
|
||||
for (i = 0; i < parray_num(files); i++)
|
||||
{
|
||||
pgFile *file = (pgFile *) parray_get(files, i);
|
||||
char *fname;
|
||||
if ((fname = last_dir_separator(file->path)))
|
||||
fname++;
|
||||
else
|
||||
fname = file->path;
|
||||
|
||||
/* to backup backup history files, compare tli/lsn portion only */
|
||||
if (strncmp(fname, last_wal, 24) > 0)
|
||||
{
|
||||
parray_remove(files, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
pgBackupGetPath(¤t, path, lengthof(path), ARCLOG_DIR);
|
||||
backup_files(arclog_path, path, files, prev_files, NULL,
|
||||
current.compress_data, NULL);
|
||||
|
||||
/* Create file list */
|
||||
create_file_list(files, arclog_path, ARCLOG_FILE_LIST, NULL, false);
|
||||
|
||||
/* Print summary of size of backup files */
|
||||
for (i = 0; i < parray_num(files); i++)
|
||||
{
|
||||
pgFile *file = (pgFile *) parray_get(files, i);
|
||||
if (!S_ISREG(file->mode))
|
||||
continue;
|
||||
current.arclog_bytes += file->read_size;
|
||||
if (file->write_size != BYTES_INVALID)
|
||||
{
|
||||
current.backup_bytes += file->write_size;
|
||||
arclog_write_bytes += file->write_size;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Backup timeline history files to special directory.
|
||||
* We do this after create file list, because copy_file() update
|
||||
* pgFile->write_size to actual size.
|
||||
*/
|
||||
join_path_components(timeline_dir, backup_path, TIMELINE_HISTORY_DIR);
|
||||
for (i = 0; i < parray_num(files); i++)
|
||||
{
|
||||
pgFile *file = (pgFile *) parray_get(files, i);
|
||||
if (!S_ISREG(file->mode))
|
||||
continue;
|
||||
if (strstr(file->path, ".history") ==
|
||||
file->path + strlen(file->path) - strlen(".history"))
|
||||
{
|
||||
elog(LOG, _("(timeline history) %s"), file->path);
|
||||
copy_file(arclog_path, timeline_dir, file, NO_COMPRESSION);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
printf(_("archived WAL backup completed(read: " INT64_FORMAT " write: " INT64_FORMAT ")\n"),
|
||||
current.arclog_bytes, arclog_write_bytes);
|
||||
printf(_("========================================\n"));
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
int
|
||||
do_backup(pgBackupOption bkupopt)
|
||||
{
|
||||
parray *backup_list;
|
||||
parray *files_database;
|
||||
parray *files_arclog;
|
||||
int ret;
|
||||
|
||||
/* repack the necesary options */
|
||||
int keep_arclog_files = bkupopt.keep_arclog_files;
|
||||
int keep_arclog_days = bkupopt.keep_arclog_days;
|
||||
/* repack the necessary options */
|
||||
int keep_data_generations = bkupopt.keep_data_generations;
|
||||
int keep_data_days = bkupopt.keep_data_days;
|
||||
|
||||
@ -590,12 +433,6 @@ do_backup(pgBackupOption bkupopt)
|
||||
elog(ERROR_ARGS, _("Required parameter not specified: BACKUP_MODE "
|
||||
"(-b, --backup-mode)"));
|
||||
|
||||
/* ARCLOG_PATH is required for all the modes */
|
||||
if (arclog_path == NULL)
|
||||
elog(ERROR_ARGS,
|
||||
_("Required parameter not specified: ARCLOG_PATH "
|
||||
"(-A, --arclog-path)"));
|
||||
|
||||
#ifndef HAVE_LIBZ
|
||||
if (current.compress_data)
|
||||
{
|
||||
@ -637,8 +474,6 @@ do_backup(pgBackupOption bkupopt)
|
||||
current.start_time = time(NULL);
|
||||
current.end_time = (time_t) 0;
|
||||
current.data_bytes = BYTES_INVALID;
|
||||
current.arclog_bytes = BYTES_INVALID;
|
||||
current.backup_bytes = 0;
|
||||
current.block_size = BLCKSZ;
|
||||
current.wal_block_size = XLOG_BLCKSZ;
|
||||
current.recovery_xid = 0;
|
||||
@ -664,9 +499,6 @@ do_backup(pgBackupOption bkupopt)
|
||||
|
||||
/* backup data */
|
||||
files_database = do_backup_database(backup_list, bkupopt);
|
||||
|
||||
/* backup archived WAL */
|
||||
files_arclog = do_backup_arclog(backup_list);
|
||||
pgut_atexit_pop(backup_cleanup, NULL);
|
||||
|
||||
/* update backup status to DONE */
|
||||
@ -680,28 +512,20 @@ do_backup(pgBackupOption bkupopt)
|
||||
{
|
||||
int64 total_read = 0;
|
||||
|
||||
/* WAL archives */
|
||||
total_read += current.arclog_bytes;
|
||||
|
||||
/* Database data */
|
||||
if (current.backup_mode == BACKUP_MODE_FULL ||
|
||||
current.backup_mode == BACKUP_MODE_INCREMENTAL)
|
||||
total_read += current.arclog_bytes;
|
||||
total_read += current.data_bytes;
|
||||
|
||||
if (total_read == 0)
|
||||
printf(_("nothing to backup\n"));
|
||||
else
|
||||
printf(_("all backup completed(read: " INT64_FORMAT " write: "
|
||||
INT64_FORMAT ")\n"),
|
||||
total_read, current.backup_bytes);
|
||||
total_read, current.data_bytes);
|
||||
printf(_("========================================\n"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete old files (archived WAL) after update of status.
|
||||
*/
|
||||
delete_old_files(arclog_path, files_arclog, keep_arclog_files,
|
||||
keep_arclog_days, true);
|
||||
|
||||
/* Delete old backup files after all backup operation. */
|
||||
pgBackupDelete(keep_data_generations, keep_data_days);
|
||||
@ -710,21 +534,6 @@ do_backup(pgBackupOption bkupopt)
|
||||
if (files_database)
|
||||
parray_walk(files_database, pgFileFree);
|
||||
parray_free(files_database);
|
||||
if (files_arclog)
|
||||
parray_walk(files_arclog, pgFileFree);
|
||||
parray_free(files_arclog);
|
||||
|
||||
/*
|
||||
* If this backup is full backup, delete backup of online WAL.
|
||||
* Note that sereverlog files which were backed up during first restoration
|
||||
* don't be delete.
|
||||
* Also delete symbolic link in the archive directory.
|
||||
*/
|
||||
if (current.backup_mode == BACKUP_MODE_FULL)
|
||||
{
|
||||
delete_online_wal_backup();
|
||||
delete_arclog_link();
|
||||
}
|
||||
|
||||
/* release catalog lock */
|
||||
catalog_unlock();
|
||||
@ -885,15 +694,6 @@ pg_stop_backup(pgBackup *backup)
|
||||
"SELECT * FROM pg_stop_backup()");
|
||||
}
|
||||
|
||||
/*
|
||||
* Force switch to a new transaction log file
|
||||
*/
|
||||
static void
|
||||
pg_switch_xlog(pgBackup *backup)
|
||||
{
|
||||
wait_for_archive(backup,
|
||||
"SELECT * FROM pg_switch_xlog()");
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if node is a standby by looking at the presence of
|
||||
@ -1202,179 +1002,6 @@ backup_files(const char *from_root,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete files modified before than KEEP_xxx_DAYS or more than KEEP_xxx_FILES
|
||||
* of newer files exist.
|
||||
*/
|
||||
static void
|
||||
delete_old_files(const char *root,
|
||||
parray *files,
|
||||
int keep_files,
|
||||
int keep_days,
|
||||
bool is_arclog)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int file_num = 0;
|
||||
time_t days_threshold = current.start_time - (keep_days * 60 * 60 * 24);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
char files_str[100];
|
||||
char days_str[100];
|
||||
|
||||
if (keep_files == KEEP_INFINITE)
|
||||
strncpy(files_str, "INFINITE", lengthof(files_str));
|
||||
else
|
||||
snprintf(files_str, lengthof(files_str), "%d", keep_files);
|
||||
|
||||
if (keep_days == KEEP_INFINITE)
|
||||
strncpy(days_str, "INFINITE", lengthof(days_str));
|
||||
else
|
||||
snprintf(days_str, lengthof(days_str), "%d", keep_days);
|
||||
|
||||
printf(_("delete old files from \"%s\" (files=%s, days=%s)\n"),
|
||||
root, files_str, days_str);
|
||||
}
|
||||
|
||||
/* Leave if both settings are set to infinite, there is nothing to do */
|
||||
if (keep_files == KEEP_INFINITE && keep_days == KEEP_INFINITE)
|
||||
{
|
||||
elog(LOG, "%s() infinite", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
parray_qsort(files, pgFileCompareMtime);
|
||||
for (i = parray_num(files) - 1; i >= 0; i--)
|
||||
{
|
||||
pgFile *file = (pgFile *) parray_get(files, i);
|
||||
|
||||
elog(LOG, "%s() %s", __FUNCTION__, file->path);
|
||||
|
||||
/* Delete completed WALs only. */
|
||||
if (is_arclog && !xlog_is_complete_wal(file))
|
||||
{
|
||||
elog(LOG, "%s() not complete WAL", __FUNCTION__);
|
||||
continue;
|
||||
}
|
||||
|
||||
file_num++;
|
||||
|
||||
/*
|
||||
* If the mtime of the file is older than the threshold and there are
|
||||
* enough number of files newer than the files, delete the file.
|
||||
*/
|
||||
if (file->mtime >= days_threshold &&
|
||||
keep_days != KEEP_INFINITE)
|
||||
{
|
||||
elog(LOG, "%s() %lu is not older than %lu", __FUNCTION__,
|
||||
file->mtime, days_threshold);
|
||||
continue;
|
||||
}
|
||||
else if (file_num <= keep_files &&
|
||||
keep_files != KEEP_INFINITE)
|
||||
{
|
||||
elog(LOG, "%s() newer files are only %d", __FUNCTION__, file_num);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Now we found a file should be deleted. */
|
||||
if (verbose)
|
||||
printf(_("delete \"%s\"\n"), file->path + strlen(root) + 1);
|
||||
|
||||
/* delete corresponding backup history file if exists */
|
||||
file = (pgFile *) parray_remove(files, i);
|
||||
for (j = parray_num(files) - 1; j >= 0; j--)
|
||||
{
|
||||
pgFile *file2 = (pgFile *)parray_get(files, j);
|
||||
if (strstr(file2->path, file->path) == file2->path)
|
||||
{
|
||||
file2 = (pgFile *)parray_remove(files, j);
|
||||
if (verbose)
|
||||
printf(_("delete \"%s\"\n"),
|
||||
file2->path + strlen(root) + 1);
|
||||
if (!check)
|
||||
pgFileDelete(file2);
|
||||
pgFileFree(file2);
|
||||
}
|
||||
}
|
||||
if (!check)
|
||||
pgFileDelete(file);
|
||||
pgFileFree(file);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
delete_online_wal_backup(void)
|
||||
{
|
||||
int i;
|
||||
parray *files = parray_new();
|
||||
char work_path[MAXPGPATH];
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
printf(_("========================================\n"));
|
||||
printf(_("delete online WAL backup\n"));
|
||||
}
|
||||
|
||||
snprintf(work_path, lengthof(work_path), "%s/%s/%s", backup_path,
|
||||
RESTORE_WORK_DIR, PG_XLOG_DIR);
|
||||
/* don't delete root dir */
|
||||
dir_list_file(files, work_path, NULL, true, false);
|
||||
if (parray_num(files) == 0)
|
||||
{
|
||||
parray_free(files);
|
||||
return;
|
||||
}
|
||||
|
||||
parray_qsort(files, pgFileComparePathDesc); /* delete from leaf */
|
||||
for (i = 0; i < parray_num(files); i++)
|
||||
{
|
||||
pgFile *file = (pgFile *) parray_get(files, i);
|
||||
if (verbose)
|
||||
printf(_("delete \"%s\"\n"), file->path);
|
||||
if (!check)
|
||||
pgFileDelete(file);
|
||||
}
|
||||
|
||||
parray_walk(files, pgFileFree);
|
||||
parray_free(files);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove symbolic links point archived WAL in backup catalog.
|
||||
*/
|
||||
static void
|
||||
delete_arclog_link(void)
|
||||
{
|
||||
int i;
|
||||
parray *files = parray_new();
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
printf(_("========================================\n"));
|
||||
printf(_("delete symbolic link in archive directory\n"));
|
||||
}
|
||||
|
||||
dir_list_file(files, arclog_path, NULL, false, false);
|
||||
for (i = 0; i < parray_num(files); i++)
|
||||
{
|
||||
pgFile *file = (pgFile *) parray_get(files, i);
|
||||
|
||||
if (!S_ISLNK(file->mode))
|
||||
continue;
|
||||
|
||||
if (verbose)
|
||||
printf(_("delete \"%s\"\n"), file->path);
|
||||
|
||||
if (!check && remove(file->path) == -1)
|
||||
elog(ERROR_SYSTEM, _("can't remove link \"%s\": %s"), file->path,
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
parray_walk(files, pgFileFree);
|
||||
parray_free(files);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append files to the backup list array.
|
||||
|
43
catalog.c
43
catalog.c
@ -268,37 +268,13 @@ catalog_get_last_data_backup(parray *backup_list, TimeLineID tli)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the last completed archived WAL backup from the backup list
|
||||
* on current timeline.
|
||||
*/
|
||||
pgBackup *
|
||||
catalog_get_last_arclog_backup(parray *backup_list, TimeLineID tli)
|
||||
{
|
||||
int i;
|
||||
pgBackup *backup = NULL;
|
||||
|
||||
/* backup_list is sorted in order of descending ID */
|
||||
for (i = 0; i < parray_num(backup_list); i++)
|
||||
{
|
||||
backup = (pgBackup *) parray_get(backup_list, i);
|
||||
|
||||
/* we need completed archived WAL backup */
|
||||
if (backup->status == BACKUP_STATUS_OK &&
|
||||
backup->tli == tli)
|
||||
return backup;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create backup directory in $BACKUP_PATH */
|
||||
int
|
||||
pgBackupCreateDir(pgBackup *backup)
|
||||
{
|
||||
int i;
|
||||
char path[MAXPGPATH];
|
||||
char *subdirs[] = { DATABASE_DIR, ARCLOG_DIR, NULL };
|
||||
char *subdirs[] = { DATABASE_DIR, NULL };
|
||||
|
||||
pgBackupGetPath(backup, path, lengthof(path), NULL);
|
||||
dir_create_dir(path, DIR_PERMISSION);
|
||||
@ -319,7 +295,7 @@ pgBackupCreateDir(pgBackup *backup)
|
||||
void
|
||||
pgBackupWriteConfigSection(FILE *out, pgBackup *backup)
|
||||
{
|
||||
static const char *modes[] = { "", "ARCHIVE", "INCREMENTAL", "FULL"};
|
||||
static const char *modes[] = { "", "INCREMENTAL", "FULL"};
|
||||
|
||||
fprintf(out, "# configuration\n");
|
||||
|
||||
@ -361,13 +337,6 @@ pgBackupWriteResultSection(FILE *out, pgBackup *backup)
|
||||
if (backup->data_bytes != BYTES_INVALID)
|
||||
fprintf(out, "DATA_BYTES=" INT64_FORMAT "\n",
|
||||
backup->data_bytes);
|
||||
if (backup->arclog_bytes != BYTES_INVALID)
|
||||
fprintf(out, "ARCLOG_BYTES=" INT64_FORMAT "\n",
|
||||
backup->arclog_bytes);
|
||||
if (backup->backup_bytes != BYTES_INVALID)
|
||||
fprintf(out, "BACKUP_BYTES=" INT64_FORMAT "\n",
|
||||
backup->backup_bytes);
|
||||
|
||||
fprintf(out, "BLOCK_SIZE=%u\n", backup->block_size);
|
||||
fprintf(out, "XLOG_BLOCK_SIZE=%u\n", backup->wal_block_size);
|
||||
|
||||
@ -423,8 +392,6 @@ catalog_read_ini(const char *path)
|
||||
{ 'u', 0, "recovery-xid" , NULL, SOURCE_ENV },
|
||||
{ 't', 0, "recovery-time" , NULL, SOURCE_ENV },
|
||||
{ 'I', 0, "data-bytes" , NULL, SOURCE_ENV },
|
||||
{ 'I', 0, "arclog-bytes" , NULL, SOURCE_ENV },
|
||||
{ 'I', 0, "backup-bytes" , NULL, SOURCE_ENV },
|
||||
{ 'u', 0, "block-size" , NULL, SOURCE_ENV },
|
||||
{ 'u', 0, "xlog-block-size" , NULL, SOURCE_ENV },
|
||||
{ 's', 0, "status" , NULL, SOURCE_ENV },
|
||||
@ -449,8 +416,6 @@ catalog_read_ini(const char *path)
|
||||
options[i++].var = &backup->recovery_xid;
|
||||
options[i++].var = &backup->recovery_time;
|
||||
options[i++].var = &backup->data_bytes;
|
||||
options[i++].var = &backup->arclog_bytes;
|
||||
options[i++].var = &backup->backup_bytes;
|
||||
options[i++].var = &backup->block_size;
|
||||
options[i++].var = &backup->wal_block_size;
|
||||
options[i++].var = &status;
|
||||
@ -527,8 +492,6 @@ parse_backup_mode(const char *value)
|
||||
return BACKUP_MODE_FULL;
|
||||
else if (len > 0 && pg_strncasecmp("incremental", v, len) == 0)
|
||||
return BACKUP_MODE_INCREMENTAL;
|
||||
else if (len > 0 && pg_strncasecmp("archive", v, len) == 0)
|
||||
return BACKUP_MODE_ARCHIVE;
|
||||
|
||||
/* Backup mode is invalid, so leave with an error */
|
||||
elog(ERROR_ARGS, _("invalid backup-mode \"%s\""), value);
|
||||
@ -597,6 +560,4 @@ catalog_init_config(pgBackup *backup)
|
||||
backup->recovery_xid = 0;
|
||||
backup->recovery_time = (time_t) 0;
|
||||
backup->data_bytes = BYTES_INVALID;
|
||||
backup->arclog_bytes = BYTES_INVALID;
|
||||
backup->backup_bytes = BYTES_INVALID;
|
||||
}
|
||||
|
@ -8,8 +8,6 @@ STOP_LSN=0/0b4c8020
|
||||
START_TIME='2009-05-31 17:05:53'
|
||||
END_TIME='2009-05-31 17:09:13'
|
||||
DATA_BYTES=1242102558
|
||||
ARCLOG_BYTES=9223372036854775807
|
||||
BACKUP_BYTES=242102558
|
||||
BLOCK_SIZE=8192
|
||||
XLOG_BLOCK_SIZE=8192
|
||||
STATUS=DONE
|
||||
|
@ -8,8 +8,6 @@ STOP_LSN=0/0b4c8020
|
||||
START_TIME='2009-06-01 17:05:53'
|
||||
END_TIME='2009-06-01 17:09:13'
|
||||
DATA_BYTES=9223372036854775807
|
||||
ARCLOG_BYTES=16777216
|
||||
BACKUP_BYTES=162372983
|
||||
BLOCK_SIZE=8192
|
||||
XLOG_BLOCK_SIZE=8192
|
||||
STATUS=DONE
|
||||
|
@ -1,5 +1,5 @@
|
||||
# configuration
|
||||
BACKUP_MODE=ARCHIVE
|
||||
BACKUP_MODE=FULL
|
||||
COMPRESS_DATA=NO
|
||||
# result
|
||||
TIMELINEID=1
|
||||
@ -8,8 +8,6 @@ STOP_LSN=0/0b4c8020
|
||||
START_TIME='2009-06-02 17:05:03'
|
||||
END_TIME='2009-06-02 17:05:03'
|
||||
DATA_BYTES=-1
|
||||
ARCLOG_BYTES=-1
|
||||
BACKUP_BYTES=162372983
|
||||
BLOCK_SIZE=8192
|
||||
XLOG_BLOCK_SIZE=8192
|
||||
STATUS=DELETED
|
||||
|
@ -8,8 +8,6 @@ STOP_LSN=0/0b4c8020
|
||||
START_TIME='2009-06-03 17:05:53'
|
||||
END_TIME='2009-06-03 17:05:53'
|
||||
DATA_BYTES=-1
|
||||
ARCLOG_BYTES=-1
|
||||
BACKUP_BYTES=-1
|
||||
BLOCK_SIZE=8192
|
||||
XLOG_BLOCK_SIZE=8192
|
||||
STATUS=RUNNING
|
||||
|
2
delete.c
2
delete.c
@ -197,8 +197,6 @@ pgBackupDeleteFiles(pgBackup *backup)
|
||||
files = parray_new();
|
||||
pgBackupGetPath(backup, path, lengthof(path), DATABASE_DIR);
|
||||
dir_list_file(files, path, NULL, true, true);
|
||||
pgBackupGetPath(backup, path, lengthof(path), ARCLOG_DIR);
|
||||
dir_list_file(files, path, NULL, true, true);
|
||||
|
||||
/* delete leaf node first */
|
||||
parray_qsort(files, pgFileComparePathDesc);
|
||||
|
@ -21,8 +21,6 @@ files.
|
||||
== DESCRIPTION ==
|
||||
|
||||
pg_rman is a utility program to backup and restore PostgreSQL database.
|
||||
It takes a physical online backup of whole database cluster and archive
|
||||
WALs.
|
||||
|
||||
It proposes the following features:
|
||||
|
||||
@ -30,7 +28,7 @@ It proposes the following features:
|
||||
command
|
||||
- Recovery from backup with just one command, with customized targets
|
||||
to facilitate the use of PITR.
|
||||
- Support for full, incremental and archive backup
|
||||
- Support for full and incremental
|
||||
- Compression of backup files
|
||||
- Management of backups with integrated catalog
|
||||
|
||||
@ -76,7 +74,6 @@ Backup target can be one of the following types:
|
||||
- Full backup, backup a whole database cluster.
|
||||
- Incremental backup, backup only files or pages modified after the last
|
||||
verified backup.
|
||||
- Archive WAL backup, Backup only archive WAL files.
|
||||
|
||||
It is recommended to verify backup files as soon as possible after backup.
|
||||
Unverified backup cannot be used in restore and in incremental backup.
|
||||
@ -143,12 +140,11 @@ Here are some commands to restore from a backup:
|
||||
The fields are:
|
||||
|
||||
* Start: start time of backup
|
||||
* Mode: Mode of backup: FULL (full), INCR (incremental) or ARCH (archive)
|
||||
* Mode: Mode of backup: FULL (full) or INCR (incremental)
|
||||
* Current TLI: current timeline of backup
|
||||
* Parent TLI: parent timeline of backup
|
||||
* Time: total time necessary to take this backup
|
||||
* Data: size of data files
|
||||
* WAL: size of read WAL archive files
|
||||
* Log: size of read server log files
|
||||
* Backup: size of backup (= written size)
|
||||
* Status: status of backup. Possible values are:
|
||||
@ -175,8 +171,6 @@ When a date is specified, more details about a backup is retrieved:
|
||||
RECOVERY_XID=1759
|
||||
RECOVERY_TIME='2011-11-27 19:15:53'
|
||||
DATA_BYTES=25420184
|
||||
ARCLOG_BYTES=32218912
|
||||
BACKUP_BYTES=242919520
|
||||
BLOCK_SIZE=8192
|
||||
XLOG_BLOCK_SIZE=8192
|
||||
STATUS=OK
|
||||
@ -202,8 +196,8 @@ absolute paths; relative paths are not allowed.
|
||||
restore.
|
||||
|
||||
*-A* _PATH_ / *--arclog-path*=_PATH_::
|
||||
The absolute path of archive WAL directory. Required on backup
|
||||
and restore.
|
||||
The absolute path of archive WAL directory. Required for restore
|
||||
and show command.
|
||||
|
||||
*-B* _PATH_ / *--backup-path*=_PATH_::
|
||||
The absolute path of backup catalog. This option is mandatory.
|
||||
@ -220,9 +214,8 @@ absolute paths; relative paths are not allowed.
|
||||
|
||||
*-b* _BACKUPMODE_ / *--backup-mode*=_BACKUPMODE_::
|
||||
Specify backup target files. Available options are: "full",
|
||||
"incremental" and "archive".
|
||||
Abbreviated forms (prefix match) are also available. For example,
|
||||
-b f means "full" backup.
|
||||
"incremental". Abbreviated forms (prefix match) are also available.
|
||||
For example, -b f means "full" backup.
|
||||
|
||||
*-Z* / *--compress-data*::
|
||||
Compress backup files with zlib if specified.
|
||||
@ -242,12 +235,6 @@ absolute paths; relative paths are not allowed.
|
||||
--keep-data-days means days to be kept.
|
||||
Only files exceeded one of those settings are deleted.
|
||||
|
||||
*--keep-arclog-files*=_NUMBER_ / *--keep-arclog-days*=_DAYS_::
|
||||
Specify how long backuped archive WAL files will be kept.
|
||||
--keep-arclog-files means number of backup files.
|
||||
--keep-arclog-days means days to be kept. When backup is run, only
|
||||
files exceeded one of those settings are deleted from archive storage.
|
||||
|
||||
=== RESTORE OPTIONS ===
|
||||
|
||||
The parameters whose name start are started with --recovery refer to
|
||||
@ -268,11 +255,6 @@ the same parameters as the ones in recovery.confin recovery.conf.
|
||||
*--recovery-target-inclusive*::
|
||||
Specifies whether server pauses when recovery target is reached.
|
||||
|
||||
*--hard-copy*::
|
||||
Archived WAL files are copied to archive WAL storage area. If you
|
||||
do not specify --hard-copy, pg_rman makes symlink to archive WAL
|
||||
where are in the backup catalog directory.
|
||||
|
||||
=== CATALOG OPTIONS ===
|
||||
|
||||
*-a* / *--show-all*::
|
||||
@ -350,7 +332,6 @@ variables or in configuration file as follows:
|
||||
--recovery-target-xid RECOVERY_TARGET_XID Yes
|
||||
--recovery-target-time RECOVERY_TARGET_TIME Yes
|
||||
--recovery-target-inclusive RECOVERY_TARGET_INCLUSIVE Yes
|
||||
--hard-copy HARD_COPY Yes
|
||||
|
||||
Variable names in configuration file are the same as long names or names
|
||||
of environment variables. The password can not be specified in command
|
||||
@ -403,7 +384,7 @@ pg_rman returns exit codes for each error status.
|
||||
13 ERROR_INTERRUPTED Interrupted by user (Ctrl+C etc.)
|
||||
14 ERROR_PG_COMMAND SQL error
|
||||
15 ERROR_PG_CONNECT Cannot connect to PostgreSQL server
|
||||
20 ERROR_ARCHIVE_FAILED Cannot archive WAL files
|
||||
20 ERROR_ARCHIVE_FAILED Cannot archive WAL file
|
||||
21 ERROR_NO_BACKUP Backup file not found
|
||||
22 ERROR_CORRUPTED Backup file is broken
|
||||
23 ERROR_ALREADY_RUNNING Cannot start because another pg_rman
|
||||
|
@ -8,18 +8,11 @@ CHECKPOINT
|
||||
incremental database backup
|
||||
CHECKPOINT
|
||||
CHECKPOINT
|
||||
archived WAL backup
|
||||
stop DB during running pgbench
|
||||
diff files in BACKUP_PATH/backup/pg_xlog
|
||||
diff files in BACKUP_PATH/backup/pg_xlog
|
||||
full database backup after recovery
|
||||
CHECKPOINT
|
||||
# of files in BACKUP_PATH/backup/pg_xlog
|
||||
0
|
||||
# of symbolic links in ARCLOG_PATH
|
||||
0
|
||||
# of files in BACKUP_PATH/timeline_history
|
||||
2
|
||||
# of recovery target option in recovery.conf
|
||||
3
|
||||
# of deleted backups (show all)
|
||||
@ -30,4 +23,4 @@ delete backup
|
||||
# of deleted backups
|
||||
4
|
||||
# of deleted backups
|
||||
9
|
||||
8
|
||||
|
@ -6,7 +6,6 @@ results/init_test/
|
||||
results/init_test/backup/
|
||||
results/init_test/backup/pg_xlog/
|
||||
results/init_test/pg_rman.ini
|
||||
results/init_test/timeline_history/
|
||||
\! pg_rman init -B ${PWD}/results/init_test --quiet;echo $?
|
||||
ERROR: backup catalog already exist. and it's not empty.
|
||||
2
|
||||
|
@ -17,21 +17,18 @@ Common Options:
|
||||
-v, --verbose output process information
|
||||
|
||||
Backup options:
|
||||
-b, --backup-mode=MODE full, incremental, or archive
|
||||
-b, --backup-mode=MODE full or incremental
|
||||
-Z, --compress-data compress data backup with zlib
|
||||
-C, --smooth-checkpoint do smooth checkpoint before backup
|
||||
--validate validate backup after taking it
|
||||
--keep-data-generations=N keep GENERATION of full data backup
|
||||
--keep-data-days=DAY keep enough data backup to recover to DAY days age
|
||||
--keep-arclog-files=NUM keep NUM of archived WAL
|
||||
--keep-arclog-days=DAY keep archived WAL modified in DAY days
|
||||
|
||||
Restore options:
|
||||
--recovery-target-time time stamp up to which recovery will proceed
|
||||
--recovery-target-xid transaction ID up to which recovery will proceed
|
||||
--recovery-target-inclusive whether we stop just after the recovery target
|
||||
--recovery-target-timeline recovering into a particular timeline
|
||||
--hard-copy copying archivelog not symbolic link
|
||||
|
||||
Catalog options:
|
||||
-a, --show-all show deleted backup too
|
||||
@ -54,10 +51,9 @@ Read the website for details. <https://github.com/michaelpq/pg_rman>
|
||||
Report bugs to <https://github.com/michaelpq/pg_rman/issues>.
|
||||
pg_rman 1.3dev
|
||||
ERROR: required parameter not specified: BACKUP_PATH (-B, --backup-path)
|
||||
ERROR: required parameter not specified: ARCLOG_PATH (-A, --arclog-path)
|
||||
ERROR: required parameter not specified: BACKUP_PATH (-B, --backup-path)
|
||||
ERROR: Required parameter not specified: BACKUP_MODE (-b, --backup-mode)
|
||||
ERROR: Required parameter not specified: ARCLOG_PATH (-A, --arclog-path)
|
||||
ERROR: Required parameter not specified: ARCLOG_PATH (-A, --arclog-path)
|
||||
ERROR: Required parameter not specified: ARCLOG_PATH (-A, --arclog-path)
|
||||
ERROR: invalid backup-mode "bad"
|
||||
ERROR: required delete range option not specified: delete DATE
|
||||
INFO: validate: 2009-05-31 17:05:53 backup and archive log files by CRC
|
||||
@ -67,11 +63,8 @@ WARNING: backup 2009-06-01 17:05:53 is corrupted
|
||||
WARNING: syntax error in " = INFINITE"
|
||||
ERROR: Required parameter not specified: BACKUP_MODE (-b, --backup-mode)
|
||||
ERROR: invalid backup-mode ""
|
||||
ERROR: Required parameter not specified: ARCLOG_PATH (-A, --arclog-path)
|
||||
ERROR: Required parameter not specified: ARCLOG_PATH (-A, --arclog-path)
|
||||
ERROR: invalid backup-mode "B"
|
||||
ERROR: option -Z, --compress-data should be a boolean: 'FOO'
|
||||
ERROR: option --keep-arclog-files should be a 32bit signed integer: 'YES'
|
||||
ERROR: invalid option "TIMELINEID"
|
||||
ERROR: invalid option "BACKUP_TARGETS"
|
||||
ERROR: invalid backup-mode "ENV_PATH"
|
||||
|
@ -1,35 +1,33 @@
|
||||
-- test show command
|
||||
\! rm -rf ${PWD}/results/sample_backup
|
||||
\! cp -rp data/sample_backup ${PWD}/results/sample_backup
|
||||
\! pg_rman show -B ${PWD}/results/sample_backup
|
||||
===========================================================================================
|
||||
Start Mode Current TLI Parent TLI Time Data WAL Backup Status
|
||||
===========================================================================================
|
||||
2009-06-03 17:05:53 FULL 1 0 0m ---- ---- ---- RUNNING
|
||||
2009-06-01 17:05:53 INCR 1 0 3m 9223PB 16MB 162MB DONE
|
||||
2009-05-31 17:05:53 FULL 1 0 3m 1242MB 9223PB 242MB DONE
|
||||
\! pg_rman show -A ${PWD}/results/arclog -B ${PWD}/results/sample_backup
|
||||
==========================================================================
|
||||
Start Mode Current TLI Parent TLI Time Data Status
|
||||
==========================================================================
|
||||
2009-06-03 17:05:53 FULL 1 0 0m ---- RUNNING
|
||||
2009-06-01 17:05:53 INCR 1 0 3m 9223PB DONE
|
||||
2009-05-31 17:05:53 FULL 1 0 3m 1242MB DONE
|
||||
\! pg_rman validate -B ${PWD}/results/sample_backup 2009-05-31 17:05:53 --debug
|
||||
INFO: validate: 2009-05-31 17:05:53 backup and archive log files by CRC
|
||||
LOG: database files...
|
||||
LOG: (1/1) PG_VERSION
|
||||
LOG: archive WAL files...
|
||||
LOG: backup 2009-05-31 17:05:53 is valid
|
||||
\! pg_rman validate -B ${PWD}/results/sample_backup 2009-06-01 17:05:53 --debug
|
||||
INFO: validate: 2009-06-01 17:05:53 backup and archive log files by CRC
|
||||
LOG: database files...
|
||||
LOG: (1/1) PG_VERSION
|
||||
WARNING: CRC of backup file "PG_VERSION" must be 0 but FEF71BC1
|
||||
LOG: archive WAL files...
|
||||
WARNING: backup 2009-06-01 17:05:53 is corrupted
|
||||
\! pg_rman show -a -B ${PWD}/results/sample_backup
|
||||
===========================================================================================
|
||||
Start Mode Current TLI Parent TLI Time Data WAL Backup Status
|
||||
===========================================================================================
|
||||
2009-06-03 17:05:53 FULL 1 0 0m ---- ---- ---- RUNNING
|
||||
2009-06-02 17:05:03 ARCH 1 0 0m ---- ---- 162MB DELETED
|
||||
2009-06-01 17:05:53 INCR 1 0 3m 9223PB 16MB 162MB CORRUPT
|
||||
2009-05-31 17:05:53 FULL 1 0 3m 1242MB 9223PB 242MB OK
|
||||
\! pg_rman show 2009-06-01 17:05:53 -B ${PWD}/results/sample_backup
|
||||
\! pg_rman show -a -A ${PWD}/results/arclog -B ${PWD}/results/sample_backup
|
||||
==========================================================================
|
||||
Start Mode Current TLI Parent TLI Time Data Status
|
||||
==========================================================================
|
||||
2009-06-03 17:05:53 FULL 1 0 0m ---- RUNNING
|
||||
2009-06-02 17:05:03 FULL 1 0 0m ---- DELETED
|
||||
2009-06-01 17:05:53 INCR 1 0 3m 9223PB CORRUPT
|
||||
2009-05-31 17:05:53 FULL 1 0 3m 1242MB OK
|
||||
\! pg_rman show 2009-06-01 17:05:53 -A ${PWD}/results/arclog -B ${PWD}/results/sample_backup
|
||||
# configuration
|
||||
BACKUP_MODE=INCREMENTAL
|
||||
COMPRESS_DATA=false
|
||||
@ -41,8 +39,6 @@ START_TIME='2009-06-01 17:05:53'
|
||||
END_TIME='2009-06-01 17:09:13'
|
||||
RECOVERY_XID=0
|
||||
DATA_BYTES=9223372036854775807
|
||||
ARCLOG_BYTES=16777216
|
||||
BACKUP_BYTES=162372983
|
||||
BLOCK_SIZE=8192
|
||||
XLOG_BLOCK_SIZE=8192
|
||||
STATUS=CORRUPT
|
||||
|
4
init.c
4
init.c
@ -53,10 +53,6 @@ do_init(void)
|
||||
PG_XLOG_DIR);
|
||||
dir_create_dir(path, DIR_PERMISSION);
|
||||
|
||||
/* create directory for timeline history files */
|
||||
join_path_components(path, backup_path, TIMELINE_HISTORY_DIR);
|
||||
dir_create_dir(path, DIR_PERMISSION);
|
||||
|
||||
/* read postgresql.conf */
|
||||
if (pgdata)
|
||||
{
|
||||
|
25
pg_rman.c
25
pg_rman.c
@ -32,8 +32,6 @@ pgBackup current;
|
||||
|
||||
/* backup configuration */
|
||||
static bool smooth_checkpoint;
|
||||
static int keep_arclog_files = KEEP_INFINITE;
|
||||
static int keep_arclog_days = KEEP_INFINITE;
|
||||
static int keep_data_generations = KEEP_INFINITE;
|
||||
static int keep_data_days = KEEP_INFINITE;
|
||||
static bool backup_validate = false;
|
||||
@ -43,7 +41,6 @@ static char *target_time;
|
||||
static char *target_xid;
|
||||
static char *target_inclusive;
|
||||
static TimeLineID target_tli;
|
||||
static bool is_hard_copy = false;
|
||||
|
||||
/* show configuration */
|
||||
static bool show_all = false;
|
||||
@ -67,15 +64,12 @@ static pgut_option options[] =
|
||||
/* options with only long name (keep-xxx) */
|
||||
{ 'i', 1, "keep-data-generations", &keep_data_generations, SOURCE_ENV },
|
||||
{ 'i', 2, "keep-data-days", &keep_data_days, SOURCE_ENV },
|
||||
{ 'i', 3, "keep-arclog-files", &keep_arclog_files, SOURCE_ENV },
|
||||
{ 'i', 4, "keep-arclog-days", &keep_arclog_days, SOURCE_ENV },
|
||||
/* restore options */
|
||||
{ 's', 7, "recovery-target-time", &target_time, SOURCE_ENV },
|
||||
{ 's', 8, "recovery-target-xid", &target_xid, SOURCE_ENV },
|
||||
{ 's', 9, "recovery-target-inclusive", &target_inclusive, SOURCE_ENV },
|
||||
{ 'u', 10, "recovery-target-timeline", &target_tli, SOURCE_ENV },
|
||||
{ 'b', 11, "hard-copy", &is_hard_copy, SOURCE_ENV },
|
||||
{ 'b', 12, "validate", &backup_validate, SOURCE_ENV },
|
||||
{ 's', 3, "recovery-target-time", &target_time, SOURCE_ENV },
|
||||
{ 's', 4, "recovery-target-xid", &target_xid, SOURCE_ENV },
|
||||
{ 's', 5, "recovery-target-inclusive", &target_inclusive, SOURCE_ENV },
|
||||
{ 'u', 6, "recovery-target-timeline", &target_tli, SOURCE_ENV },
|
||||
{ 'b', 7, "validate", &backup_validate, SOURCE_ENV },
|
||||
/* catalog options */
|
||||
{ 'b', 'a', "show-all", &show_all },
|
||||
{ 0 }
|
||||
@ -171,8 +165,6 @@ main(int argc, char *argv[])
|
||||
pgBackupOption bkupopt;
|
||||
int res;
|
||||
bkupopt.smooth_checkpoint = smooth_checkpoint;
|
||||
bkupopt.keep_arclog_files = keep_arclog_files;
|
||||
bkupopt.keep_arclog_days = keep_arclog_days;
|
||||
bkupopt.keep_data_generations = keep_data_generations;
|
||||
bkupopt.keep_data_days = keep_data_days;
|
||||
|
||||
@ -189,7 +181,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
else if (pg_strcasecmp(cmd, "restore") == 0){
|
||||
return do_restore(target_time, target_xid,
|
||||
target_inclusive, target_tli, is_hard_copy);
|
||||
target_inclusive, target_tli);
|
||||
}
|
||||
else if (pg_strcasecmp(cmd, "show") == 0)
|
||||
return do_show(&range, show_all);
|
||||
@ -225,20 +217,17 @@ pgut_help(bool details)
|
||||
printf(_(" -c, --check show what would have been done\n"));
|
||||
printf(_(" -v, --verbose output process information\n"));
|
||||
printf(_("\nBackup options:\n"));
|
||||
printf(_(" -b, --backup-mode=MODE full, incremental, or archive\n"));
|
||||
printf(_(" -b, --backup-mode=MODE full or incremental\n"));
|
||||
printf(_(" -Z, --compress-data compress data backup with zlib\n"));
|
||||
printf(_(" -C, --smooth-checkpoint do smooth checkpoint before backup\n"));
|
||||
printf(_(" --validate validate backup after taking it\n"));
|
||||
printf(_(" --keep-data-generations=N keep GENERATION of full data backup\n"));
|
||||
printf(_(" --keep-data-days=DAY keep enough data backup to recover to DAY days age\n"));
|
||||
printf(_(" --keep-arclog-files=NUM keep NUM of archived WAL\n"));
|
||||
printf(_(" --keep-arclog-days=DAY keep archived WAL modified in DAY days\n"));
|
||||
printf(_("\nRestore options:\n"));
|
||||
printf(_(" --recovery-target-time time stamp up to which recovery will proceed\n"));
|
||||
printf(_(" --recovery-target-xid transaction ID up to which recovery will proceed\n"));
|
||||
printf(_(" --recovery-target-inclusive whether we stop just after the recovery target\n"));
|
||||
printf(_(" --recovery-target-timeline recovering into a particular timeline\n"));
|
||||
printf(_(" --hard-copy copying archivelog not symbolic link\n"));
|
||||
printf(_("\nCatalog options:\n"));
|
||||
printf(_(" -a, --show-all show deleted backup too\n"));
|
||||
}
|
||||
|
15
pg_rman.h
15
pg_rman.h
@ -25,16 +25,13 @@
|
||||
|
||||
/* Directory/File names */
|
||||
#define DATABASE_DIR "database"
|
||||
#define ARCLOG_DIR "arclog"
|
||||
#define RESTORE_WORK_DIR "backup"
|
||||
#define PG_XLOG_DIR "pg_xlog"
|
||||
#define PG_TBLSPC_DIR "pg_tblspc"
|
||||
#define TIMELINE_HISTORY_DIR "timeline_history"
|
||||
#define BACKUP_INI_FILE "backup.ini"
|
||||
#define PG_RMAN_INI_FILE "pg_rman.ini"
|
||||
#define MKDIRS_SH_FILE "mkdirs.sh"
|
||||
#define DATABASE_FILE_LIST "file_database.txt"
|
||||
#define ARCLOG_FILE_LIST "file_arclog.txt"
|
||||
#define SNAPSHOT_SCRIPT_FILE "snapshot_script"
|
||||
#define PG_BACKUP_LABEL_FILE "backup_label"
|
||||
#define PG_BLACK_LIST "black_list"
|
||||
@ -113,7 +110,6 @@ typedef enum BackupStatus
|
||||
typedef enum BackupMode
|
||||
{
|
||||
BACKUP_MODE_INVALID,
|
||||
BACKUP_MODE_ARCHIVE, /* archive only */
|
||||
BACKUP_MODE_INCREMENTAL, /* incremental backup */
|
||||
BACKUP_MODE_FULL /* full backup */
|
||||
} BackupMode;
|
||||
@ -148,10 +144,6 @@ typedef struct pgBackup
|
||||
* of data taken.
|
||||
*/
|
||||
int64 data_bytes;
|
||||
/* Amount of data for WAL archives */
|
||||
int64 arclog_bytes;
|
||||
/* Total size of backup */
|
||||
int64 backup_bytes;
|
||||
|
||||
/* data/wal block size for compatibility check */
|
||||
uint32 block_size;
|
||||
@ -161,8 +153,6 @@ typedef struct pgBackup
|
||||
typedef struct pgBackupOption
|
||||
{
|
||||
bool smooth_checkpoint;
|
||||
int keep_arclog_files;
|
||||
int keep_arclog_days;
|
||||
int keep_data_generations;
|
||||
int keep_data_days;
|
||||
} pgBackupOption;
|
||||
@ -233,8 +223,7 @@ extern bool fileExists(const char *path);
|
||||
extern int do_restore(const char *target_time,
|
||||
const char *target_xid,
|
||||
const char *target_inclusive,
|
||||
TimeLineID target_tli,
|
||||
bool is_hard_copy);
|
||||
TimeLineID target_tli);
|
||||
|
||||
/* in init.c */
|
||||
extern int do_init(void);
|
||||
@ -262,8 +251,6 @@ extern pgBackup *catalog_get_backup(time_t timestamp);
|
||||
extern parray *catalog_get_backup_list(const pgBackupRange *range);
|
||||
extern pgBackup *catalog_get_last_data_backup(parray *backup_list,
|
||||
TimeLineID tli);
|
||||
extern pgBackup *catalog_get_last_arclog_backup(parray *backup_list,
|
||||
TimeLineID tli);
|
||||
|
||||
extern int catalog_lock(void);
|
||||
extern void catalog_unlock(void);
|
||||
|
214
restore.c
214
restore.c
@ -17,9 +17,7 @@
|
||||
#include "catalog/pg_control.h"
|
||||
|
||||
static void backup_online_files(bool re_recovery);
|
||||
static void restore_online_files(void);
|
||||
static void restore_database(pgBackup *backup);
|
||||
static void restore_archive_logs(pgBackup *backup, bool is_hard_copy);
|
||||
static void create_recovery_conf(const char *target_time,
|
||||
const char *target_xid,
|
||||
const char *target_inclusive,
|
||||
@ -43,8 +41,7 @@ int
|
||||
do_restore(const char *target_time,
|
||||
const char *target_xid,
|
||||
const char *target_inclusive,
|
||||
TimeLineID target_tli,
|
||||
bool is_hard_copy)
|
||||
TimeLineID target_tli)
|
||||
{
|
||||
int i;
|
||||
int base_index; /* index of base (full) backup */
|
||||
@ -56,7 +53,6 @@ do_restore(const char *target_time,
|
||||
pgBackup *base_backup = NULL;
|
||||
parray *files;
|
||||
parray *timelines;
|
||||
char timeline_dir[MAXPGPATH];
|
||||
pgRecoveryTarget *rt = NULL;
|
||||
XLogRecPtr need_lsn;
|
||||
|
||||
@ -138,14 +134,7 @@ do_restore(const char *target_time,
|
||||
parray_free(files);
|
||||
}
|
||||
|
||||
/*
|
||||
* restore timeline history files and get timeline branches can reach
|
||||
* recovery target point.
|
||||
*/
|
||||
join_path_components(timeline_dir, backup_path, TIMELINE_HISTORY_DIR);
|
||||
if (verbose && !check)
|
||||
printf(_("restoring timeline history files\n"));
|
||||
dir_copy_files(timeline_dir, arclog_path);
|
||||
/* Read timeline history files from archives */
|
||||
timelines = readTimeLineHistory(target_tli);
|
||||
|
||||
/* find last full backup which can be used as base backup. */
|
||||
@ -213,47 +202,7 @@ base_backup_found:
|
||||
last_restored_index = i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore archived WAL which backed up with or after last restored backup.
|
||||
* We don't check the backup->tli because a backup of arhived WAL
|
||||
* can contain WALs which were archived in multiple timeline.
|
||||
*/
|
||||
if (verbose)
|
||||
printf(_("searching backed-up WAL...\n"));
|
||||
|
||||
if (check)
|
||||
{
|
||||
pgBackup *backup = (pgBackup *) parray_get(backups, last_restored_index);
|
||||
need_lsn = backup->start_lsn;
|
||||
}
|
||||
|
||||
for (i = last_restored_index; i >= 0; i--)
|
||||
{
|
||||
pgBackup *backup = (pgBackup *) parray_get(backups, i);
|
||||
|
||||
/* don't use incomplete backup */
|
||||
if (backup->status != BACKUP_STATUS_OK)
|
||||
continue;
|
||||
|
||||
/* care timeline junction */
|
||||
if (!satisfy_timeline(timelines, backup))
|
||||
continue;
|
||||
|
||||
restore_archive_logs(backup, is_hard_copy);
|
||||
|
||||
if (check)
|
||||
{
|
||||
char xlogpath[MAXPGPATH];
|
||||
|
||||
pgBackupGetPath(backup, xlogpath, lengthof(xlogpath), ARCLOG_DIR);
|
||||
search_next_wal(xlogpath, &need_lsn, timelines);
|
||||
}
|
||||
}
|
||||
|
||||
/* copy online WAL backup to $PGDATA/pg_xlog */
|
||||
restore_online_files();
|
||||
|
||||
if (check)
|
||||
{
|
||||
char xlogpath[MAXPGPATH];
|
||||
if (verbose)
|
||||
@ -466,113 +415,6 @@ restore_database(pgBackup *backup)
|
||||
printf(_("restore backup completed\n"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore archived WAL by creating symbolic link which linked to backup WAL in
|
||||
* archive directory.
|
||||
*/
|
||||
void
|
||||
restore_archive_logs(pgBackup *backup, bool is_hard_copy)
|
||||
{
|
||||
int i;
|
||||
char timestamp[100];
|
||||
parray *files;
|
||||
char path[MAXPGPATH];
|
||||
char list_path[MAXPGPATH];
|
||||
char base_path[MAXPGPATH];
|
||||
|
||||
time2iso(timestamp, lengthof(timestamp), backup->start_time);
|
||||
if (verbose && !check)
|
||||
{
|
||||
printf(_("----------------------------------------\n"));
|
||||
printf(_("restoring WAL from backup %s.\n"), timestamp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate backup files with its size, because load of CRC calculation is
|
||||
* not light.
|
||||
*/
|
||||
pgBackupValidate(backup, true, false);
|
||||
|
||||
pgBackupGetPath(backup, list_path, lengthof(list_path), ARCLOG_FILE_LIST);
|
||||
pgBackupGetPath(backup, base_path, lengthof(list_path), ARCLOG_DIR);
|
||||
files = dir_read_file_list(base_path, list_path);
|
||||
for (i = 0; i < parray_num(files); i++)
|
||||
{
|
||||
pgFile *file = (pgFile *) parray_get(files, i);
|
||||
|
||||
/* check for interrupt */
|
||||
if (interrupted)
|
||||
elog(ERROR_INTERRUPTED, _("interrupted during restore WAL"));
|
||||
|
||||
/* print progress */
|
||||
join_path_components(path, arclog_path, file->path + strlen(base_path) + 1);
|
||||
if (verbose && !check)
|
||||
printf(_("(%d/%lu) %s "), i + 1, (unsigned long) parray_num(files),
|
||||
file->path + strlen(base_path) + 1);
|
||||
|
||||
/* skip files which are not in backup */
|
||||
if (file->write_size == BYTES_INVALID)
|
||||
{
|
||||
if (verbose && !check)
|
||||
printf(_("skip(not backed up)\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* skip timeline history files because timeline history files will be
|
||||
* restored from $BACKUP_PATH/timeline_history.
|
||||
*/
|
||||
if (strstr(file->path, ".history") ==
|
||||
file->path + strlen(file->path) - strlen(".history"))
|
||||
{
|
||||
if (verbose && !check)
|
||||
printf(_("skip(timeline history)\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!check)
|
||||
{
|
||||
if (backup->compress_data)
|
||||
{
|
||||
copy_file(base_path, arclog_path, file, DECOMPRESSION);
|
||||
if (verbose)
|
||||
printf(_("decompressed\n"));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* even same file exist, use backup file */
|
||||
if ((remove(path) == -1) && errno != ENOENT)
|
||||
elog(ERROR_SYSTEM, _("can't remove file \"%s\": %s"), path,
|
||||
strerror(errno));
|
||||
|
||||
if (!is_hard_copy)
|
||||
{
|
||||
/* create symlink */
|
||||
if ((symlink(file->path, path) == -1))
|
||||
elog(ERROR_SYSTEM, _("can't create link to \"%s\": %s"),
|
||||
file->path, strerror(errno));
|
||||
|
||||
if (verbose)
|
||||
printf(_("linked\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create hard-copy */
|
||||
if (!copy_file(base_path, arclog_path, file, NO_COMPRESSION))
|
||||
elog(ERROR_SYSTEM, _("can't copy to \"%s\": %s"),
|
||||
file->path, strerror(errno));
|
||||
|
||||
if (verbose)
|
||||
printf(_("copied\n"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
parray_walk(files, pgFileFree);
|
||||
parray_free(files);
|
||||
}
|
||||
|
||||
static void
|
||||
create_recovery_conf(const char *target_time,
|
||||
@ -654,58 +496,6 @@ backup_online_files(bool re_recovery)
|
||||
dir_copy_files(pg_xlog_path, work_path);
|
||||
}
|
||||
|
||||
static void
|
||||
restore_online_files(void)
|
||||
{
|
||||
int i;
|
||||
char root_backup[MAXPGPATH];
|
||||
parray *files_backup;
|
||||
|
||||
/* get list of files in $BACKUP_PATH/backup/pg_xlog */
|
||||
files_backup = parray_new();
|
||||
snprintf(root_backup, lengthof(root_backup), "%s/%s/%s", backup_path,
|
||||
RESTORE_WORK_DIR, PG_XLOG_DIR);
|
||||
dir_list_file(files_backup, root_backup, NULL, true, false);
|
||||
|
||||
if (verbose && !check)
|
||||
{
|
||||
printf(_("----------------------------------------\n"));
|
||||
printf(_("restoring online WAL\n"));
|
||||
}
|
||||
|
||||
/* restore online WAL */
|
||||
for (i = 0; i < parray_num(files_backup); i++)
|
||||
{
|
||||
pgFile *file = (pgFile *) parray_get(files_backup, i);
|
||||
|
||||
if (S_ISDIR(file->mode))
|
||||
{
|
||||
char to_path[MAXPGPATH];
|
||||
snprintf(to_path, lengthof(to_path), "%s/%s/%s", pgdata,
|
||||
PG_XLOG_DIR, file->path + strlen(root_backup) + 1);
|
||||
if (verbose && !check)
|
||||
printf(_("create directory \"%s\"\n"),
|
||||
file->path + strlen(root_backup) + 1);
|
||||
if (!check)
|
||||
dir_create_dir(to_path, DIR_PERMISSION);
|
||||
continue;
|
||||
}
|
||||
else if(S_ISREG(file->mode))
|
||||
{
|
||||
char to_root[MAXPGPATH];
|
||||
join_path_components(to_root, pgdata, PG_XLOG_DIR);
|
||||
if (verbose && !check)
|
||||
printf(_("restore \"%s\"\n"),
|
||||
file->path + strlen(root_backup) + 1);
|
||||
if (!check)
|
||||
copy_file(root_backup, to_root, file, NO_COMPRESSION);
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
parray_walk(files_backup, pgFileFree);
|
||||
parray_free(files_backup);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to read a timeline's history file.
|
||||
|
39
show.c
39
show.c
@ -20,6 +20,15 @@ static void show_backup_detail(FILE *out, pgBackup *backup);
|
||||
int
|
||||
do_show(pgBackupRange *range, bool show_all)
|
||||
{
|
||||
/*
|
||||
* Safety check for archive folder, this is necessary to fetch
|
||||
* the parent TLI from history field generated by server after
|
||||
* child timeline is chosen.
|
||||
*/
|
||||
if (arclog_path == NULL)
|
||||
elog(ERROR_ARGS,
|
||||
_("required parameter not specified: ARCLOG_PATH (-A, --arclog-path)"));
|
||||
|
||||
if (pgBackupRangeIsSingle(range))
|
||||
{
|
||||
pgBackup *backup;
|
||||
@ -29,7 +38,7 @@ do_show(pgBackupRange *range, bool show_all)
|
||||
{
|
||||
char timestamp[100];
|
||||
time2iso(timestamp, lengthof(timestamp), range->begin);
|
||||
elog(INFO, _("backup taken at \"%s\" doesn not exist."),
|
||||
elog(INFO, _("backup taken at \"%s\" does not exist."),
|
||||
timestamp);
|
||||
/* This is not error case */
|
||||
return 0;
|
||||
@ -111,9 +120,9 @@ get_parent_tli(TimeLineID child_tli)
|
||||
char fline[MAXPGPATH];
|
||||
FILE *fd;
|
||||
|
||||
/* search from timeline history dir */
|
||||
snprintf(path, lengthof(path), "%s/%s/%08X.history", backup_path,
|
||||
TIMELINE_HISTORY_DIR, child_tli);
|
||||
/* Search history file in archives */
|
||||
snprintf(path, lengthof(path), "%s/%08X.history", arclog_path,
|
||||
child_tli);
|
||||
fd = fopen(path, "rt");
|
||||
if (fd == NULL)
|
||||
{
|
||||
@ -161,20 +170,18 @@ show_backup_list(FILE *out, parray *backup_list, bool show_all)
|
||||
int i;
|
||||
|
||||
/* show header */
|
||||
fputs("===========================================================================================\n", out);
|
||||
fputs("Start Mode Current TLI Parent TLI Time Data WAL Backup Status \n", out);
|
||||
fputs("===========================================================================================\n", out);
|
||||
fputs("==========================================================================\n", out);
|
||||
fputs("Start Mode Current TLI Parent TLI Time Data Status \n", out);
|
||||
fputs("==========================================================================\n", out);
|
||||
|
||||
for (i = 0; i < parray_num(backup_list); i++)
|
||||
{
|
||||
pgBackup *backup;
|
||||
const char *modes[] = { "", "ARCH", "INCR", "FULL"};
|
||||
const char *modes[] = { "", "INCR", "FULL"};
|
||||
TimeLineID parent_tli;
|
||||
char timestamp[20];
|
||||
char duration[20] = "----";
|
||||
char data_bytes_str[10] = "----";
|
||||
char arclog_bytes_str[10] = "----";
|
||||
char backup_bytes_str[10];
|
||||
|
||||
backup = parray_get(backup_list, i);
|
||||
|
||||
@ -195,26 +202,16 @@ show_backup_list(FILE *out, parray *backup_list, bool show_all)
|
||||
pretty_size(backup->data_bytes, data_bytes_str,
|
||||
lengthof(data_bytes_str));
|
||||
|
||||
/* Calculate amount of data for archive files */
|
||||
pretty_size(backup->arclog_bytes, arclog_bytes_str,
|
||||
lengthof(arclog_bytes_str));
|
||||
|
||||
/* Calculate amount of data for total backup */
|
||||
pretty_size(backup->backup_bytes, backup_bytes_str,
|
||||
lengthof(backup_bytes_str));
|
||||
|
||||
/* Get parent timeline before printing */
|
||||
parent_tli = get_parent_tli(backup->tli);
|
||||
|
||||
fprintf(out, "%-19s %-4s %10d %10d %5s %6s %6s %6s %s\n",
|
||||
fprintf(out, "%-19s %-4s %10d %10d %5s %6s %s \n",
|
||||
timestamp,
|
||||
modes[backup->backup_mode],
|
||||
backup->tli,
|
||||
parent_tli,
|
||||
duration,
|
||||
data_bytes_str,
|
||||
arclog_bytes_str,
|
||||
backup_bytes_str,
|
||||
status2str(backup->status));
|
||||
}
|
||||
}
|
||||
|
@ -127,9 +127,6 @@ psql --no-psqlrc -p $TEST_PGPORT postgres -c "checkpoint"
|
||||
pg_rman -w -p $TEST_PGPORT backup -b i --verbose -d postgres > $BASE_PATH/results/log_incr2 2>&1
|
||||
|
||||
pgbench -p $TEST_PGPORT -T $DURATION -c 10 pgbench >> $BASE_PATH/results/pgbench.log 2>&1
|
||||
echo "archived WAL backup"
|
||||
#pg_rman -p $TEST_PGPORT backup -b a --verbose -d postgres > $BASE_PATH/results/log_arclog 2>&1
|
||||
pg_rman -w -p $TEST_PGPORT backup -b a --verbose -d postgres > $BASE_PATH/results/log_arclog 2>&1
|
||||
|
||||
# stop PG during transaction and get commited info for verifing
|
||||
echo "stop DB during running pgbench"
|
||||
@ -160,10 +157,6 @@ if [ "$CUR_TLI" != "$CUR_TLI_R" ]; then
|
||||
echo "failed: bad timeline ID" CUR_TLI=$CUR_TLI CUR_TLI_R=$CUR_TLI_R
|
||||
fi
|
||||
|
||||
# Backup of online-WAL
|
||||
echo "diff files in BACKUP_PATH/backup/pg_xlog"
|
||||
diff -r $PGDATA/pg_xlog $BACKUP_PATH/backup/pg_xlog
|
||||
|
||||
# recovery database
|
||||
pg_ctl start -w -t 3600 > /dev/null 2>&1
|
||||
|
||||
@ -181,10 +174,6 @@ if [ "$CUR_TLI" != "$CUR_TLI_R" ]; then
|
||||
echo "failed: bad timeline ID" CUR_TLI=$CUR_TLI CUR_TLI_R=$CUR_TLI_R
|
||||
fi
|
||||
|
||||
# Backup of online-WAL
|
||||
echo "diff files in BACKUP_PATH/backup/pg_xlog"
|
||||
diff -r $PGDATA/pg_xlog $BACKUP_PATH/backup/pg_xlog
|
||||
|
||||
# re-recovery database
|
||||
pg_ctl start -w -t 3600 > /dev/null 2>&1
|
||||
|
||||
@ -199,18 +188,10 @@ psql --no-psqlrc -p $TEST_PGPORT postgres -c "checkpoint"
|
||||
#pg_rman -p $TEST_PGPORT backup -b f --verbose -d postgres > $BASE_PATH/results/log_full2 2>&1
|
||||
pg_rman -w -p $TEST_PGPORT backup -b f --verbose -d postgres > $BASE_PATH/results/log_full2 2>&1
|
||||
|
||||
# Backup of online-WAL should been deleted
|
||||
echo "# of files in BACKUP_PATH/backup/pg_xlog"
|
||||
find $BACKUP_PATH/backup/pg_xlog -type f | wc -l | tr -d ' '
|
||||
|
||||
# Symbolic links in $ARCLOG_PATH should be deleted.
|
||||
echo "# of symbolic links in ARCLOG_PATH"
|
||||
find $ARCLOG_PATH -type l | wc -l | tr -d ' '
|
||||
|
||||
# timeline history files are backed up.
|
||||
echo "# of files in BACKUP_PATH/timeline_history"
|
||||
find $BACKUP_PATH/timeline_history -type f | wc -l | tr -d ' '
|
||||
|
||||
# restore with pg_rman
|
||||
pg_ctl stop -m immediate > /dev/null 2>&1
|
||||
|
||||
|
@ -12,7 +12,6 @@ unset BACKUP_PATH
|
||||
unset ARCLOG_PATH
|
||||
unset BACKUP_MODE
|
||||
unset COMPRESS_DATA
|
||||
unset KEEP_ARCLOG_DAYS
|
||||
unset KEEP_DATA_GENERATIONS
|
||||
unset KEEP_DATA_DAYS
|
||||
|
||||
@ -29,13 +28,15 @@ cp -rp data/sample_backup $BACKUP_PATH
|
||||
pg_rman --help
|
||||
pg_rman --version
|
||||
|
||||
# show option
|
||||
# required argument check
|
||||
pg_rman show
|
||||
pg_rman show -B $BACKUP_PATH
|
||||
|
||||
# backup option
|
||||
# required arguments check
|
||||
pg_rman backup --verbose
|
||||
pg_rman backup --verbose -B $BACKUP_PATH
|
||||
pg_rman backup --verbose -B $BACKUP_PATH -b f
|
||||
pg_rman backup --verbose -B $BACKUP_PATH -b i
|
||||
pg_rman backup --verbose -B $BACKUP_PATH -b a
|
||||
|
||||
# bad arguments check
|
||||
pg_rman backup --verbose -B $BACKUP_PATH -b bad
|
||||
@ -49,16 +50,10 @@ echo " = INFINITE" > $BACKUP_PATH/pg_rman.ini
|
||||
pg_rman backup --verbose -B $BACKUP_PATH
|
||||
echo "BACKUP_MODE= " > $BACKUP_PATH/pg_rman.ini
|
||||
pg_rman backup --verbose -B $BACKUP_PATH
|
||||
echo "BACKUP_MODE = F#S" > $BACKUP_PATH/pg_rman.ini
|
||||
pg_rman backup --verbose -B $BACKUP_PATH
|
||||
echo "BACKUP_MODE = F #comment A" > $BACKUP_PATH/pg_rman.ini
|
||||
pg_rman backup --verbose -B $BACKUP_PATH
|
||||
echo "BACKUP_MODE=B" > $BACKUP_PATH/pg_rman.ini
|
||||
pg_rman backup --verbose -B $BACKUP_PATH
|
||||
echo "COMPRESS_DATA=FOO" > $BACKUP_PATH/pg_rman.ini
|
||||
pg_rman backup --verbose -B $BACKUP_PATH
|
||||
echo "KEEP_ARCLOG_FILES=YES" > $BACKUP_PATH/pg_rman.ini
|
||||
pg_rman backup --verbose -B $BACKUP_PATH
|
||||
echo "TIMELINEID=-1" > $BACKUP_PATH/pg_rman.ini
|
||||
pg_rman backup --verbose -B $BACKUP_PATH
|
||||
echo "BACKUP_TARGETS=F" > $BACKUP_PATH/pg_rman.ini
|
||||
|
@ -1,8 +1,8 @@
|
||||
-- test show command
|
||||
\! rm -rf ${PWD}/results/sample_backup
|
||||
\! cp -rp data/sample_backup ${PWD}/results/sample_backup
|
||||
\! pg_rman show -B ${PWD}/results/sample_backup
|
||||
\! pg_rman show -A ${PWD}/results/arclog -B ${PWD}/results/sample_backup
|
||||
\! pg_rman validate -B ${PWD}/results/sample_backup 2009-05-31 17:05:53 --debug
|
||||
\! pg_rman validate -B ${PWD}/results/sample_backup 2009-06-01 17:05:53 --debug
|
||||
\! pg_rman show -a -B ${PWD}/results/sample_backup
|
||||
\! pg_rman show 2009-06-01 17:05:53 -B ${PWD}/results/sample_backup
|
||||
\! pg_rman show -a -A ${PWD}/results/arclog -B ${PWD}/results/sample_backup
|
||||
\! pg_rman show 2009-06-01 17:05:53 -A ${PWD}/results/arclog -B ${PWD}/results/sample_backup
|
||||
|
16
validate.c
16
validate.c
@ -84,12 +84,6 @@ pgBackupValidate(pgBackup *backup,
|
||||
backup->backup_mode == BACKUP_MODE_INCREMENTAL)
|
||||
elog(INFO, "validate: %s backup and archive log files by %s",
|
||||
timestamp, (size_only ? "SIZE" : "CRC"));
|
||||
else
|
||||
{
|
||||
if (backup->backup_mode == BACKUP_MODE_ARCHIVE)
|
||||
elog(INFO, "validate: %s archive log files by %s",
|
||||
timestamp, (size_only ? "SIZE" : "CRC"));
|
||||
}
|
||||
}
|
||||
|
||||
if (!check)
|
||||
@ -108,16 +102,6 @@ pgBackupValidate(pgBackup *backup,
|
||||
parray_free(files);
|
||||
}
|
||||
|
||||
/* WAL archives are present for all modes */
|
||||
elog(LOG, "archive WAL files...");
|
||||
pgBackupGetPath(backup, base_path, lengthof(base_path), ARCLOG_DIR);
|
||||
pgBackupGetPath(backup, path, lengthof(path), ARCLOG_FILE_LIST);
|
||||
files = dir_read_file_list(base_path, path);
|
||||
if (!pgBackupValidateFiles(files, base_path, size_only))
|
||||
corrupted = true;
|
||||
parray_walk(files, pgFileFree);
|
||||
parray_free(files);
|
||||
|
||||
/* update status to OK */
|
||||
if (corrupted)
|
||||
backup->status = BACKUP_STATUS_CORRUPT;
|
||||
|
Loading…
x
Reference in New Issue
Block a user