mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2025-01-19 11:30:07 +02:00
Merge pull request #53 from postgrespro/issue_52
Issue 52: --no-validate flag for backup
This commit is contained in:
commit
0a1d887847
@ -931,7 +931,7 @@ do_backup_instance(void)
|
||||
* Entry point of pg_probackup BACKUP subcommand.
|
||||
*/
|
||||
int
|
||||
do_backup(time_t start_time)
|
||||
do_backup(time_t start_time, bool no_validate)
|
||||
{
|
||||
/* PGDATA and BACKUP_MODE are always required */
|
||||
if (instance_config.pgdata == NULL)
|
||||
@ -1069,7 +1069,8 @@ do_backup(time_t start_time)
|
||||
//elog(LOG, "Backup completed. Total bytes : " INT64_FORMAT "",
|
||||
// current.data_bytes);
|
||||
|
||||
pgBackupValidate(¤t);
|
||||
if (!no_validate)
|
||||
pgBackupValidate(¤t);
|
||||
|
||||
elog(INFO, "Backup %s completed", base36enc(current.start_time));
|
||||
|
||||
|
@ -453,7 +453,8 @@ catalog_get_last_data_backup(parray *backup_list, TimeLineID tli)
|
||||
{
|
||||
backup = (pgBackup *) parray_get(backup_list, (size_t) i);
|
||||
|
||||
if (backup->status == BACKUP_STATUS_OK && backup->tli == tli)
|
||||
if ((backup->status == BACKUP_STATUS_OK ||
|
||||
backup->status == BACKUP_STATUS_DONE) && backup->tli == tli)
|
||||
return backup;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ do_delete(time_t backup_id)
|
||||
{
|
||||
pgBackup *backup = (pgBackup *) parray_get(backup_list, (size_t) i);
|
||||
|
||||
if (backup->status == BACKUP_STATUS_OK)
|
||||
if (backup->status == BACKUP_STATUS_OK || backup->status == BACKUP_STATUS_DONE)
|
||||
{
|
||||
oldest_lsn = backup->start_lsn;
|
||||
oldest_tli = backup->tli;
|
||||
|
@ -118,7 +118,7 @@ help_pg_probackup(void)
|
||||
printf(_(" [--master-db=db_name] [--master-host=host_name]\n"));
|
||||
printf(_(" [--master-port=port] [--master-user=user_name]\n"));
|
||||
printf(_(" [--replica-timeout=timeout]\n"));
|
||||
printf(_(" [--skip-block-validation]\n"));
|
||||
printf(_(" [--no-validate] [--skip-block-validation]\n"));
|
||||
printf(_(" [--external-dirs=external-directory-path]\n"));
|
||||
|
||||
printf(_("\n %s restore -B backup-path --instance=instance_name\n"), PROGRAM_NAME);
|
||||
@ -212,7 +212,7 @@ help_backup(void)
|
||||
printf(_(" [--master-db=db_name] [--master-host=host_name]\n"));
|
||||
printf(_(" [--master-port=port] [--master-user=user_name]\n"));
|
||||
printf(_(" [--replica-timeout=timeout]\n"));
|
||||
printf(_(" [--skip-block-validation]\n"));
|
||||
printf(_(" [--no-validate] [--skip-block-validation]\n"));
|
||||
printf(_(" [-E external-dirs=external-directory-path]\n\n"));
|
||||
|
||||
printf(_(" -B, --backup-path=backup-path location of the backup storage area\n"));
|
||||
@ -226,6 +226,7 @@ help_backup(void)
|
||||
printf(_(" -j, --threads=NUM number of parallel threads\n"));
|
||||
printf(_(" --archive-timeout=timeout wait timeout for WAL segment archiving (default: 5min)\n"));
|
||||
printf(_(" --progress show progress\n"));
|
||||
printf(_(" --no-validate disable validation after backup\n"));
|
||||
printf(_(" --skip-block-validation set to validate only file-level checksum\n"));
|
||||
printf(_(" -E --external-dirs=external-directory-path\n"));
|
||||
printf(_(" backup some directories not from pgdata \n"));
|
||||
|
@ -78,6 +78,7 @@ do_merge(time_t backup_id)
|
||||
{
|
||||
/* sanity */
|
||||
if (backup->status != BACKUP_STATUS_OK &&
|
||||
backup->status != BACKUP_STATUS_DONE &&
|
||||
/* It is possible that previous merging was interrupted */
|
||||
backup->status != BACKUP_STATUS_MERGING &&
|
||||
backup->status != BACKUP_STATUS_DELETING)
|
||||
@ -107,6 +108,7 @@ do_merge(time_t backup_id)
|
||||
|
||||
/* sanity */
|
||||
if (full_backup->status != BACKUP_STATUS_OK &&
|
||||
full_backup->status != BACKUP_STATUS_DONE &&
|
||||
/* It is possible that previous merging was interrupted */
|
||||
full_backup->status != BACKUP_STATUS_MERGING)
|
||||
elog(ERROR, "Backup %s has status: %s",
|
||||
@ -117,6 +119,7 @@ do_merge(time_t backup_id)
|
||||
{
|
||||
/* sanity */
|
||||
if (dest_backup->status != BACKUP_STATUS_OK &&
|
||||
dest_backup->status != BACKUP_STATUS_DONE &&
|
||||
/* It is possible that previous merging was interrupted */
|
||||
dest_backup->status != BACKUP_STATUS_MERGING &&
|
||||
dest_backup->status != BACKUP_STATUS_DELETING)
|
||||
@ -191,7 +194,8 @@ merge_backups(pgBackup *to_backup, pgBackup *from_backup)
|
||||
* BACKUP_STATUS_MERGING status then it isn't valid backup until merging
|
||||
* finished.
|
||||
*/
|
||||
if (to_backup->status == BACKUP_STATUS_OK)
|
||||
if (to_backup->status == BACKUP_STATUS_OK ||
|
||||
to_backup->status == BACKUP_STATUS_DONE)
|
||||
{
|
||||
pgBackupValidate(to_backup);
|
||||
if (to_backup->status == BACKUP_STATUS_CORRUPT)
|
||||
@ -203,6 +207,7 @@ merge_backups(pgBackup *to_backup, pgBackup *from_backup)
|
||||
* BACKUP_STATUS_MERGING status.
|
||||
*/
|
||||
Assert(from_backup->status == BACKUP_STATUS_OK ||
|
||||
from_backup->status == BACKUP_STATUS_DONE ||
|
||||
from_backup->status == BACKUP_STATUS_MERGING ||
|
||||
from_backup->status == BACKUP_STATUS_DELETING);
|
||||
pgBackupValidate(from_backup);
|
||||
|
@ -85,7 +85,7 @@ static char *target_action = NULL;
|
||||
static pgRecoveryTarget *recovery_target_options = NULL;
|
||||
|
||||
bool restore_as_replica = false;
|
||||
bool restore_no_validate = false;
|
||||
bool no_validate = false;
|
||||
|
||||
bool skip_block_validation = false;
|
||||
bool skip_external_dirs = false;
|
||||
@ -158,7 +158,7 @@ static ConfigOption cmd_options[] =
|
||||
{ 's', 141, "recovery-target-name", &target_name, SOURCE_CMD_STRICT },
|
||||
{ 's', 142, "recovery-target-action", &target_action, SOURCE_CMD_STRICT },
|
||||
{ 'b', 'R', "restore-as-replica", &restore_as_replica, SOURCE_CMD_STRICT },
|
||||
{ 'b', 143, "no-validate", &restore_no_validate, SOURCE_CMD_STRICT },
|
||||
{ 'b', 143, "no-validate", &no_validate, SOURCE_CMD_STRICT },
|
||||
{ 's', 144, "lsn", &target_lsn, SOURCE_CMD_STRICT },
|
||||
{ 'b', 154, "skip-block-validation", &skip_block_validation, SOURCE_CMD_STRICT },
|
||||
{ 'b', 156, "skip-external-dirs", &skip_external_dirs, SOURCE_CMD_STRICT },
|
||||
@ -474,7 +474,7 @@ main(int argc, char *argv[])
|
||||
/* parse all recovery target options into recovery_target_options structure */
|
||||
recovery_target_options = parseRecoveryTargetOptions(target_time, target_xid,
|
||||
target_inclusive, target_tli, target_lsn, target_immediate,
|
||||
target_name, target_action, restore_no_validate);
|
||||
target_name, target_action, no_validate);
|
||||
}
|
||||
|
||||
if (num_threads < 1)
|
||||
@ -508,7 +508,7 @@ main(int argc, char *argv[])
|
||||
PROGRAM_VERSION, base36enc(start_time), backup_mode, instance_name,
|
||||
stream_wal ? "true" : "false", is_remote_backup ? "true" : "false");
|
||||
|
||||
return do_backup(start_time);
|
||||
return do_backup(start_time, no_validate);
|
||||
}
|
||||
case RESTORE_CMD:
|
||||
return do_restore_or_validate(current.backup_id,
|
||||
|
@ -291,7 +291,7 @@ typedef struct pgRecoveryTarget
|
||||
bool recovery_target_immediate;
|
||||
const char *recovery_target_name;
|
||||
const char *recovery_target_action;
|
||||
bool restore_no_validate;
|
||||
bool no_validate;
|
||||
} pgRecoveryTarget;
|
||||
|
||||
typedef struct
|
||||
@ -406,7 +406,7 @@ extern pgBackup current;
|
||||
extern const char *pgdata_exclude_dir[];
|
||||
|
||||
/* in backup.c */
|
||||
extern int do_backup(time_t start_time);
|
||||
extern int do_backup(time_t start_time, bool no_validate);
|
||||
extern BackupMode parse_backup_mode(const char *value);
|
||||
extern const char *deparse_backup_mode(BackupMode mode);
|
||||
extern void process_block_change(ForkNumber forknum, RelFileNode rnode,
|
||||
@ -427,7 +427,7 @@ extern pgRecoveryTarget *parseRecoveryTargetOptions(
|
||||
const char *target_time, const char *target_xid,
|
||||
const char *target_inclusive, TimeLineID target_tli, const char* target_lsn,
|
||||
bool target_immediate, const char *target_name,
|
||||
const char *target_action, bool restore_no_validate);
|
||||
const char *target_action, bool no_validate);
|
||||
|
||||
/* in merge.c */
|
||||
extern void do_merge(time_t backup_id);
|
||||
|
@ -94,7 +94,8 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt,
|
||||
|
||||
if (is_restore &&
|
||||
target_backup_id == INVALID_BACKUP_ID &&
|
||||
current_backup->status != BACKUP_STATUS_OK)
|
||||
(current_backup->status != BACKUP_STATUS_OK &&
|
||||
current_backup->status != BACKUP_STATUS_DONE))
|
||||
{
|
||||
elog(WARNING, "Skipping backup %s, because it has non-valid status: %s",
|
||||
base36enc(current_backup->start_time), status2str(current_backup->status));
|
||||
@ -110,7 +111,7 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt,
|
||||
{
|
||||
|
||||
/* backup is not ok,
|
||||
* but in case of CORRUPT, ORPHAN or DONE revalidation is possible
|
||||
* but in case of CORRUPT or ORPHAN revalidation is possible
|
||||
* unless --no-validate is used,
|
||||
* in other cases throw an error.
|
||||
*/
|
||||
@ -119,13 +120,13 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt,
|
||||
// 3. restore -i INVALID_ID <- allowed revalidate and restore
|
||||
// 4. restore <- impossible
|
||||
// 5. restore --no-validate <- forbidden
|
||||
if (current_backup->status != BACKUP_STATUS_OK)
|
||||
if (current_backup->status != BACKUP_STATUS_OK &&
|
||||
current_backup->status != BACKUP_STATUS_DONE)
|
||||
{
|
||||
if ((current_backup->status == BACKUP_STATUS_DONE ||
|
||||
current_backup->status == BACKUP_STATUS_ORPHAN ||
|
||||
if ((current_backup->status == BACKUP_STATUS_ORPHAN ||
|
||||
current_backup->status == BACKUP_STATUS_CORRUPT ||
|
||||
current_backup->status == BACKUP_STATUS_RUNNING)
|
||||
&& !rt->restore_no_validate)
|
||||
&& !rt->no_validate)
|
||||
elog(WARNING, "Backup %s has status: %s",
|
||||
base36enc(current_backup->start_time), status2str(current_backup->status));
|
||||
else
|
||||
@ -205,7 +206,8 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt,
|
||||
*/
|
||||
if (is_parent(missing_backup_start_time, backup, false))
|
||||
{
|
||||
if (backup->status == BACKUP_STATUS_OK)
|
||||
if (backup->status == BACKUP_STATUS_OK ||
|
||||
backup->status == BACKUP_STATUS_DONE)
|
||||
{
|
||||
write_backup_status(backup, BACKUP_STATUS_ORPHAN);
|
||||
|
||||
@ -238,7 +240,8 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt,
|
||||
|
||||
if (is_parent(tmp_backup->start_time, backup, false))
|
||||
{
|
||||
if (backup->status == BACKUP_STATUS_OK)
|
||||
if (backup->status == BACKUP_STATUS_OK ||
|
||||
backup->status == BACKUP_STATUS_DONE)
|
||||
{
|
||||
write_backup_status(backup, BACKUP_STATUS_ORPHAN);
|
||||
|
||||
@ -308,7 +311,7 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt,
|
||||
parray_append(parent_chain, base_full_backup);
|
||||
|
||||
/* for validation or restore with enabled validation */
|
||||
if (!is_restore || !rt->restore_no_validate)
|
||||
if (!is_restore || !rt->no_validate)
|
||||
{
|
||||
if (dest_backup->backup_mode != BACKUP_MODE_FULL)
|
||||
elog(INFO, "Validating parents for backup %s", base36enc(dest_backup->start_time));
|
||||
@ -374,7 +377,8 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt,
|
||||
|
||||
if (is_parent(corrupted_backup->start_time, backup, false))
|
||||
{
|
||||
if (backup->status == BACKUP_STATUS_OK)
|
||||
if (backup->status == BACKUP_STATUS_OK ||
|
||||
backup->status == BACKUP_STATUS_DONE)
|
||||
{
|
||||
write_backup_status(backup, BACKUP_STATUS_ORPHAN);
|
||||
|
||||
@ -393,9 +397,10 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt,
|
||||
* If dest backup is corrupted or was orphaned in previous check
|
||||
* produce corresponding error message
|
||||
*/
|
||||
if (dest_backup->status == BACKUP_STATUS_OK)
|
||||
if (dest_backup->status == BACKUP_STATUS_OK ||
|
||||
dest_backup->status == BACKUP_STATUS_DONE)
|
||||
{
|
||||
if (rt->restore_no_validate)
|
||||
if (rt->no_validate)
|
||||
elog(INFO, "Backup %s is used without validation.", base36enc(dest_backup->start_time));
|
||||
else
|
||||
elog(INFO, "Backup %s is valid.", base36enc(dest_backup->start_time));
|
||||
@ -425,7 +430,7 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt,
|
||||
* Backup was locked during validation if no-validate wasn't
|
||||
* specified.
|
||||
*/
|
||||
if (rt->restore_no_validate && !lock_backup(backup))
|
||||
if (rt->no_validate && !lock_backup(backup))
|
||||
elog(ERROR, "Cannot lock backup directory");
|
||||
|
||||
restore_backup(backup, dest_backup->external_dir_str);
|
||||
@ -473,7 +478,8 @@ restore_backup(pgBackup *backup, const char *external_dir_str)
|
||||
bool restore_isok = true;
|
||||
|
||||
|
||||
if (backup->status != BACKUP_STATUS_OK)
|
||||
if (backup->status != BACKUP_STATUS_OK &&
|
||||
backup->status != BACKUP_STATUS_DONE)
|
||||
elog(ERROR, "Backup %s cannot be restored because it is not valid",
|
||||
base36enc(backup->start_time));
|
||||
|
||||
@ -993,7 +999,7 @@ parseRecoveryTargetOptions(const char *target_time,
|
||||
bool target_immediate,
|
||||
const char *target_name,
|
||||
const char *target_action,
|
||||
bool restore_no_validate)
|
||||
bool no_validate)
|
||||
{
|
||||
time_t dummy_time;
|
||||
TransactionId dummy_xid;
|
||||
@ -1022,7 +1028,7 @@ parseRecoveryTargetOptions(const char *target_time,
|
||||
rt->recovery_target_immediate = false;
|
||||
rt->recovery_target_name = NULL;
|
||||
rt->recovery_target_action = NULL;
|
||||
rt->restore_no_validate = false;
|
||||
rt->no_validate = false;
|
||||
|
||||
/* parse given options */
|
||||
if (target_time)
|
||||
@ -1080,9 +1086,9 @@ parseRecoveryTargetOptions(const char *target_time,
|
||||
rt->recovery_target_immediate = target_immediate;
|
||||
}
|
||||
|
||||
if (restore_no_validate)
|
||||
if (no_validate)
|
||||
{
|
||||
rt->restore_no_validate = restore_no_validate;
|
||||
rt->no_validate = no_validate;
|
||||
}
|
||||
|
||||
if (target_name)
|
||||
|
@ -417,7 +417,8 @@ do_validate_instance(void)
|
||||
corrupted_backup_found = true;
|
||||
|
||||
/* orphanize current_backup */
|
||||
if (current_backup->status == BACKUP_STATUS_OK)
|
||||
if (current_backup->status == BACKUP_STATUS_OK ||
|
||||
current_backup->status == BACKUP_STATUS_DONE)
|
||||
{
|
||||
write_backup_status(current_backup, BACKUP_STATUS_ORPHAN);
|
||||
elog(WARNING, "Backup %s is orphaned because his parent %s is missing",
|
||||
@ -440,7 +441,8 @@ do_validate_instance(void)
|
||||
{
|
||||
char *backup_id = base36enc_dup(tmp_backup->start_time);
|
||||
/* orphanize current_backup */
|
||||
if (current_backup->status == BACKUP_STATUS_OK)
|
||||
if (current_backup->status == BACKUP_STATUS_OK ||
|
||||
current_backup->status == BACKUP_STATUS_DONE)
|
||||
{
|
||||
write_backup_status(current_backup, BACKUP_STATUS_ORPHAN);
|
||||
elog(WARNING, "Backup %s is orphaned because his parent %s has status: %s",
|
||||
@ -512,7 +514,8 @@ do_validate_instance(void)
|
||||
|
||||
if (is_parent(current_backup->start_time, backup, false))
|
||||
{
|
||||
if (backup->status == BACKUP_STATUS_OK)
|
||||
if (backup->status == BACKUP_STATUS_OK ||
|
||||
backup->status == BACKUP_STATUS_DONE)
|
||||
{
|
||||
write_backup_status(backup, BACKUP_STATUS_ORPHAN);
|
||||
|
||||
|
@ -50,7 +50,7 @@ pg_probackup - utility to manage backup/recovery of PostgreSQL database.
|
||||
[--master-db=db_name] [--master-host=host_name]
|
||||
[--master-port=port] [--master-user=user_name]
|
||||
[--replica-timeout=timeout]
|
||||
[--skip-block-validation]
|
||||
[--no-validate] [--skip-block-validation]
|
||||
[--external-dirs=external-directory-path]
|
||||
|
||||
pg_probackup restore -B backup-path --instance=instance_name
|
||||
|
Loading…
x
Reference in New Issue
Block a user