1
0
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:
Michael Paquier 2014-01-24 22:36:31 +09:00
parent 5988e6bd10
commit 820485d225
21 changed files with 71 additions and 812 deletions

383
backup.c
View File

@ -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(&current);
/*
* 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(&current, 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.

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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
View File

@ -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)
{

View File

@ -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"));
}

View File

@ -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
View File

@ -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
View File

@ -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));
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;