mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2025-02-03 14:01:57 +02:00
Improve backup mode management
This commit makes mandatory the presence of a full backup when doing an incremental or archive backup on an existing timeline. In this case the process will now simply error out and not take any backup. It looks safer to use that as a default by the way, so as user will be forced to take a full backup once a recovery has been done. Database backup also contained the following condition when doing an incremental backup: prev_backup->tli != current.tli This means that an incremental backup cannot be taken if there is not already a full backup present in the same timeline. The same condition should also be used for archive backup but it didn't seem to be the case...
This commit is contained in:
parent
26b8870665
commit
1bc1f1d1b6
81
backup.c
81
backup.c
@ -82,23 +82,9 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt)
|
||||
/* repack the options */
|
||||
bool smooth_checkpoint = bkupopt.smooth_checkpoint;
|
||||
|
||||
/*
|
||||
* In archive backup mode, check if there is an already validated
|
||||
* full backup on current timeline.
|
||||
*/
|
||||
/* Leave in case od archive mode */
|
||||
if (current.backup_mode == BACKUP_MODE_ARCHIVE)
|
||||
{
|
||||
pgBackup *prev_backup;
|
||||
|
||||
prev_backup = catalog_get_last_data_backup(backup_list);
|
||||
if (prev_backup == NULL)
|
||||
{
|
||||
elog(ERROR_SYSTEM, _("Full backup detected but it is not "
|
||||
"validated so archive backup cannot be taken. "
|
||||
"backup. Validate it and retry."));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
elog(INFO, _("database backup start"));
|
||||
|
||||
@ -113,6 +99,21 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt)
|
||||
*/
|
||||
current.tli = get_current_timeline();
|
||||
|
||||
/*
|
||||
* In incremental backup mode, check if there is an already-validated
|
||||
* full backup on current timeline.
|
||||
*/
|
||||
if (current.backup_mode == BACKUP_MODE_INCREMENTAL)
|
||||
{
|
||||
pgBackup *prev_backup;
|
||||
|
||||
prev_backup = catalog_get_last_data_backup(backup_list, current.tli);
|
||||
if (prev_backup == NULL)
|
||||
elog(ERROR_SYSTEM, _("Valid full backup not found for "
|
||||
"incremental backup. Either create a full backup "
|
||||
"or validate existing one."));
|
||||
}
|
||||
|
||||
/* notify start of backup to PostgreSQL server */
|
||||
time2iso(label, lengthof(label), current.start_time);
|
||||
strncat(label, " with pg_rman", lengthof(label));
|
||||
@ -167,30 +168,22 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt)
|
||||
* To take incremental backup, the file list of the last completed database
|
||||
* backup is needed.
|
||||
*/
|
||||
if (current.backup_mode < BACKUP_MODE_FULL)
|
||||
if (current.backup_mode == BACKUP_MODE_INCREMENTAL)
|
||||
{
|
||||
pgBackup *prev_backup;
|
||||
|
||||
/* find last completed database backup */
|
||||
prev_backup = catalog_get_last_data_backup(backup_list);
|
||||
if (prev_backup == NULL || prev_backup->tli != current.tli)
|
||||
{
|
||||
elog(ERROR_SYSTEM, _("Full backup detected but it is not "
|
||||
"validated so incremental backup cannot be taken"));
|
||||
}
|
||||
else
|
||||
{
|
||||
pgBackupGetPath(prev_backup, prev_file_txt, lengthof(prev_file_txt),
|
||||
DATABASE_FILE_LIST);
|
||||
prev_files = dir_read_file_list(pgdata, prev_file_txt);
|
||||
prev_backup = catalog_get_last_data_backup(backup_list, current.tli);
|
||||
pgBackupGetPath(prev_backup, prev_file_txt, lengthof(prev_file_txt),
|
||||
DATABASE_FILE_LIST);
|
||||
prev_files = dir_read_file_list(pgdata, prev_file_txt);
|
||||
|
||||
/*
|
||||
* Do backup only pages having larger LSN than previous backup.
|
||||
*/
|
||||
lsn = &prev_backup->start_lsn;
|
||||
elog(LOG, _("backup only the page that there was of the update from LSN(%X/%08X).\n"),
|
||||
(uint32) (*lsn >> 32), (uint32) *lsn);
|
||||
}
|
||||
/*
|
||||
* Do backup only pages having larger LSN than previous backup.
|
||||
*/
|
||||
lsn = &prev_backup->start_lsn;
|
||||
elog(LOG, _("backup only the page that there was of the update from LSN(%X/%08X).\n"),
|
||||
(uint32) (*lsn >> 32), (uint32) *lsn);
|
||||
}
|
||||
|
||||
/* initialize backup list from non-snapshot */
|
||||
@ -455,15 +448,28 @@ do_backup_arclog(parray *backup_list)
|
||||
/* initialize size summary */
|
||||
current.read_arclog_bytes = 0;
|
||||
|
||||
/* switch xlog if database is not backed up */
|
||||
/*
|
||||
* 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);
|
||||
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"));
|
||||
|
||||
@ -587,7 +593,8 @@ do_backup_srvlog(parray *backup_list)
|
||||
* To take incremental backup, the file list of the last completed database
|
||||
* backup is needed.
|
||||
*/
|
||||
prev_backup = catalog_get_last_srvlog_backup(backup_list);
|
||||
prev_backup = catalog_get_last_srvlog_backup(backup_list,
|
||||
get_current_timeline());
|
||||
if (verbose && prev_backup == NULL)
|
||||
printf(_("no previous full backup, performing a full backup instead\n"));
|
||||
|
||||
|
22
catalog.c
22
catalog.c
@ -244,7 +244,7 @@ err_proc:
|
||||
* Find the last completed database backup from the backup list.
|
||||
*/
|
||||
pgBackup *
|
||||
catalog_get_last_data_backup(parray *backup_list)
|
||||
catalog_get_last_data_backup(parray *backup_list, TimeLineID tli)
|
||||
{
|
||||
int i;
|
||||
pgBackup *backup = NULL;
|
||||
@ -256,9 +256,10 @@ catalog_get_last_data_backup(parray *backup_list)
|
||||
|
||||
/*
|
||||
* We need completed database backup in the case of a full or
|
||||
* incremental backup.
|
||||
* incremental backup on current timeline.
|
||||
*/
|
||||
if (backup->status == BACKUP_STATUS_OK &&
|
||||
backup->tli == tli &&
|
||||
(backup->backup_mode == BACKUP_MODE_INCREMENTAL ||
|
||||
backup->backup_mode == BACKUP_MODE_FULL))
|
||||
return backup;
|
||||
@ -268,10 +269,11 @@ catalog_get_last_data_backup(parray *backup_list)
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the last completed archived WAL backup from the backup list.
|
||||
* Find the last completed archived WAL backup from the backup list
|
||||
* on current timeline.
|
||||
*/
|
||||
pgBackup *
|
||||
catalog_get_last_arclog_backup(parray *backup_list)
|
||||
catalog_get_last_arclog_backup(parray *backup_list, TimeLineID tli)
|
||||
{
|
||||
int i;
|
||||
pgBackup *backup = NULL;
|
||||
@ -282,7 +284,8 @@ catalog_get_last_arclog_backup(parray *backup_list)
|
||||
backup = (pgBackup *) parray_get(backup_list, i);
|
||||
|
||||
/* we need completed archived WAL backup */
|
||||
if (backup->status == BACKUP_STATUS_OK)
|
||||
if (backup->status == BACKUP_STATUS_OK &&
|
||||
backup->tli == tli)
|
||||
return backup;
|
||||
}
|
||||
|
||||
@ -290,10 +293,11 @@ catalog_get_last_arclog_backup(parray *backup_list)
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the last completed serverlog backup from the backup list.
|
||||
* Find the last completed serverlog backup from the backup list
|
||||
* on current timeline.
|
||||
*/
|
||||
pgBackup *
|
||||
catalog_get_last_srvlog_backup(parray *backup_list)
|
||||
catalog_get_last_srvlog_backup(parray *backup_list, TimeLineID tli)
|
||||
{
|
||||
int i;
|
||||
pgBackup *backup = NULL;
|
||||
@ -304,7 +308,9 @@ catalog_get_last_srvlog_backup(parray *backup_list)
|
||||
backup = (pgBackup *) parray_get(backup_list, i);
|
||||
|
||||
/* we need completed serverlog backup */
|
||||
if (backup->status == BACKUP_STATUS_OK && backup->with_serverlog)
|
||||
if (backup->status == BACKUP_STATUS_OK &&
|
||||
backup->with_serverlog &&
|
||||
backup->tli == tli)
|
||||
return backup;
|
||||
}
|
||||
|
||||
|
@ -265,9 +265,12 @@ extern void pgBackupValidate(pgBackup *backup,
|
||||
/* in catalog.c */
|
||||
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);
|
||||
extern pgBackup *catalog_get_last_arclog_backup(parray *backup_list);
|
||||
extern pgBackup *catalog_get_last_srvlog_backup(parray *backup_list);
|
||||
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 pgBackup *catalog_get_last_srvlog_backup(parray *backup_list,
|
||||
TimeLineID tli);
|
||||
|
||||
extern int catalog_lock(void);
|
||||
extern void catalog_unlock(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user