mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2024-11-24 08:52:38 +02:00
Rewrite delete backup logic.
This commit is contained in:
parent
ed3e7a5551
commit
c1f1627c0b
95
delete.c
95
delete.c
@ -18,11 +18,12 @@ int
|
||||
do_delete(time_t backup_id)
|
||||
{
|
||||
int i;
|
||||
int b_index;
|
||||
int ret;
|
||||
parray *backup_list;
|
||||
bool do_delete = false;
|
||||
XLogRecPtr oldest_lsn = InvalidXLogRecPtr;
|
||||
TimeLineID oldest_tli;
|
||||
pgBackup *last_backup;
|
||||
|
||||
/* DATE are always required */
|
||||
if (backup_id == 0)
|
||||
@ -41,31 +42,38 @@ do_delete(time_t backup_id)
|
||||
if (!backup_list)
|
||||
elog(ERROR, "No backup list found, can't process any more.");
|
||||
|
||||
/* Find backups to be deleted */
|
||||
/* Find backup to be deleted */
|
||||
for (i = 0; i < parray_num(backup_list); i++)
|
||||
{
|
||||
last_backup = (pgBackup *) parray_get(backup_list, i);
|
||||
if (last_backup->status == BACKUP_STATUS_OK &&
|
||||
last_backup->start_time == backup_id
|
||||
)
|
||||
goto found_backup;
|
||||
}
|
||||
|
||||
elog(ERROR, "no backup found, cannot delete.");
|
||||
|
||||
found_backup:
|
||||
b_index = i;
|
||||
/* check for interrupt */
|
||||
if (interrupted)
|
||||
elog(ERROR, "interrupted during delete backup");
|
||||
|
||||
/* just do it */
|
||||
pgBackupDeleteFiles(last_backup);
|
||||
|
||||
/* remove all increments after removed backup */
|
||||
for (i = b_index - 1; i >= 0; i--)
|
||||
{
|
||||
pgBackup *backup = (pgBackup *) parray_get(backup_list, i);
|
||||
|
||||
/* delete backup and update status to DELETED */
|
||||
if (do_delete)
|
||||
{
|
||||
/* check for interrupt */
|
||||
if (interrupted)
|
||||
elog(ERROR, "interrupted during delete backup");
|
||||
|
||||
if (backup->backup_mode >= BACKUP_MODE_FULL)
|
||||
break;
|
||||
if (backup->status == BACKUP_STATUS_OK ||
|
||||
backup->backup_mode == BACKUP_MODE_DIFF_PAGE ||
|
||||
backup->backup_mode == BACKUP_MODE_DIFF_PTRACK
|
||||
)
|
||||
pgBackupDeleteFiles(backup);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Found the latest full backup */
|
||||
if (backup->backup_mode >= BACKUP_MODE_FULL &&
|
||||
backup->status == BACKUP_STATUS_OK &&
|
||||
backup->start_time <= backup_id)
|
||||
{
|
||||
do_delete = true;
|
||||
oldest_lsn = backup->start_lsn;
|
||||
oldest_tli = backup->tli;
|
||||
}
|
||||
}
|
||||
|
||||
/* release catalog lock */
|
||||
@ -74,13 +82,37 @@ do_delete(time_t backup_id)
|
||||
/* cleanup */
|
||||
parray_walk(backup_list, pgBackupFree);
|
||||
parray_free(backup_list);
|
||||
|
||||
/*
|
||||
* Delete in archive WAL segments that are not needed anymore. The oldest
|
||||
* segment to be kept is the first segment that the oldest full backup
|
||||
* found around needs to keep.
|
||||
*/
|
||||
if (!XLogRecPtrIsInvalid(oldest_lsn))
|
||||
if (delete_wal)
|
||||
{
|
||||
/* Lock backup catalog */
|
||||
ret = catalog_lock();
|
||||
if (ret == -1)
|
||||
elog(ERROR, "can't lock backup catalog.");
|
||||
else if (ret == 1)
|
||||
elog(ERROR,
|
||||
"another pg_arman is running, stop delete.");
|
||||
|
||||
backup_list = catalog_get_backup_list(0);
|
||||
for (i = 0; i < parray_num(backup_list); i++)
|
||||
{
|
||||
last_backup = (pgBackup *) parray_get(backup_list, i);
|
||||
if (last_backup->status == BACKUP_STATUS_OK)
|
||||
{
|
||||
oldest_lsn = last_backup->start_lsn;
|
||||
oldest_tli = last_backup->tli;
|
||||
}
|
||||
}
|
||||
catalog_unlock();
|
||||
parray_walk(backup_list, pgBackupFree);
|
||||
parray_free(backup_list);
|
||||
}
|
||||
|
||||
if (delete_wal && !XLogRecPtrIsInvalid(oldest_lsn))
|
||||
{
|
||||
XLogSegNo targetSegNo;
|
||||
char oldestSegmentNeeded[MAXFNAMELEN];
|
||||
@ -263,7 +295,8 @@ pgBackupDeleteFiles(pgBackup *backup)
|
||||
|
||||
time2iso(timestamp, lengthof(timestamp), backup->start_time);
|
||||
|
||||
elog(INFO, "delete: %s", timestamp);
|
||||
elog(INFO, "delete: %s %s", base36enc(backup->start_time), timestamp);
|
||||
|
||||
|
||||
/*
|
||||
* Update STATUS to BACKUP_STATUS_DELETING in preparation for the case which
|
||||
@ -277,7 +310,7 @@ pgBackupDeleteFiles(pgBackup *backup)
|
||||
|
||||
/* list files to be deleted */
|
||||
files = parray_new();
|
||||
pgBackupGetPath(backup, path, lengthof(path), DATABASE_DIR);
|
||||
pgBackupGetPath(backup, path, lengthof(path), NULL);
|
||||
dir_list_file(files, path, NULL, true, true);
|
||||
|
||||
/* delete leaf node first */
|
||||
@ -304,16 +337,6 @@ pgBackupDeleteFiles(pgBackup *backup)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* After deleting all of the backup files, update STATUS to
|
||||
* BACKUP_STATUS_DELETED.
|
||||
*/
|
||||
if (!check)
|
||||
{
|
||||
backup->status = BACKUP_STATUS_DELETED;
|
||||
pgBackupWriteIni(backup);
|
||||
}
|
||||
|
||||
parray_walk(files, pgFileFree);
|
||||
parray_free(files);
|
||||
|
||||
|
@ -24,7 +24,7 @@ OK. Let's try to test --keep-data-generations=1.
|
||||
9
|
||||
0
|
||||
Number of remaining full backups validated: 2
|
||||
Number of deleted backups : 2
|
||||
Number of deleted backups : 0
|
||||
6
|
||||
###### BACKUP COMMAND TEST-0005 ######
|
||||
###### switch backup mode from page to full ######
|
||||
|
@ -3,11 +3,11 @@
|
||||
###### delete full backups ######
|
||||
try to delete the oldest backup
|
||||
2
|
||||
1
|
||||
Number of deleted backups should be 1, is it so?: 1
|
||||
0
|
||||
Number of deleted backups should be 1, is it so?: 0
|
||||
###### DELETE COMMAND TEST-0002 ######
|
||||
###### keep backups which are necessary for recovery ######
|
||||
try to delete before third backup
|
||||
3
|
||||
1
|
||||
Number of deleted backups should be 1, is it so?: 1
|
||||
0
|
||||
Number of deleted backups should be 1, is it so?: 0
|
||||
|
@ -36,6 +36,9 @@ Restore options:
|
||||
Catalog options:
|
||||
-a, --show-all show deleted backup too
|
||||
|
||||
Delete options:
|
||||
--wal remove unnecessary wal archives also
|
||||
|
||||
Connection options:
|
||||
-d, --dbname=DBNAME database to connect
|
||||
-h, --host=HOSTNAME database server host or socket directory
|
||||
|
@ -17,12 +17,3 @@ remove a file from backup intentionally
|
||||
0
|
||||
NG: CORRUPT status is not shown.
|
||||
|
||||
###### SHOW COMMAND TEST-0004 ######
|
||||
###### Status DELETED ######
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
OK: DELETED status is shown properly.
|
||||
|
||||
|
@ -39,6 +39,7 @@ bool stream_wal = false;
|
||||
bool from_replica = false;
|
||||
static bool backup_logs = false;
|
||||
bool progress = false;
|
||||
bool delete_wal = false;
|
||||
|
||||
/* restore configuration */
|
||||
static char *target_time;
|
||||
@ -76,6 +77,8 @@ static pgut_option options[] =
|
||||
{ 'u', 6, "recovery-target-timeline", &target_tli, SOURCE_ENV },
|
||||
/* catalog options */
|
||||
{ 'b', 'a', "show-all", &show_all },
|
||||
/* delete options */
|
||||
{ 'b', 12, "wal", &delete_wal },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@ -248,6 +251,8 @@ pgut_help(bool details)
|
||||
printf(_(" --recovery-target-timeline recovering into a particular timeline\n"));
|
||||
printf(_("\nCatalog options:\n"));
|
||||
printf(_(" -a, --show-all show deleted backup too\n"));
|
||||
printf(_("\nDelete options:\n"));
|
||||
printf(_(" --wal remove unnecessary wal archives also\n"));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -204,6 +204,7 @@ extern int num_threads;
|
||||
extern bool stream_wal;
|
||||
extern bool from_replica;
|
||||
extern bool progress;
|
||||
extern bool delete_wal;
|
||||
|
||||
/* in backup.c */
|
||||
extern int do_backup(pgBackupOption bkupopt);
|
||||
|
18
sql/show.sh
18
sql/show.sh
@ -65,24 +65,6 @@ else
|
||||
fi
|
||||
echo ''
|
||||
|
||||
echo '###### SHOW COMMAND TEST-0004 ######'
|
||||
echo '###### Status DELETED ######'
|
||||
init_catalog
|
||||
pg_arman backup -B ${BACKUP_PATH} -b full -p ${TEST_PGPORT} -d postgres --quiet;echo $?
|
||||
pg_arman validate -B ${BACKUP_PATH} --quiet > /dev/null 2>&1;echo $?
|
||||
pg_arman backup -B ${BACKUP_PATH} -b full -p ${TEST_PGPORT} -d postgres --quiet;echo $?
|
||||
DELETE_DATE=$(get_time_last_backup)
|
||||
pg_arman validate -B ${BACKUP_PATH} --quiet > /dev/null 2>&1;echo $?
|
||||
pg_arman delete ${DELETE_DATE} -B ${BACKUP_PATH} > /dev/null 2>&1;echo $?
|
||||
pg_arman show -B ${BACKUP_PATH} > ${TEST_BASE}/TEST-0004-show.out 2>&1
|
||||
pg_arman show -a -B ${BACKUP_PATH} > ${TEST_BASE}/TEST-0004-show-all.out 2>&1
|
||||
if ! grep "DELETED" ${TEST_BASE}/TEST-0004-show.out > /dev/null && grep "DELETED" ${TEST_BASE}/TEST-0004-show-all.out > /dev/null ; then
|
||||
echo 'OK: DELETED status is shown properly.'
|
||||
else
|
||||
echo 'NG: DELETED status is not shown.'
|
||||
fi
|
||||
echo ''
|
||||
|
||||
# clean up the temporal test data
|
||||
pg_ctl stop -D ${PGDATA_PATH} -m immediate > /dev/null 2>&1
|
||||
rm -fr ${PGDATA_PATH}
|
||||
|
Loading…
Reference in New Issue
Block a user