Skip to content

Commit c1f1627

Browse files
committed
Rewrite delete backup logic.
1 parent ed3e7a5 commit c1f1627

File tree

8 files changed

+72
-67
lines changed

8 files changed

+72
-67
lines changed

delete.c

Lines changed: 58 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ int
1818
do_delete(time_t backup_id)
1919
{
2020
int i;
21+
int b_index;
2122
int ret;
2223
parray *backup_list;
23-
bool do_delete = false;
2424
XLogRecPtr oldest_lsn = InvalidXLogRecPtr;
2525
TimeLineID oldest_tli;
26+
pgBackup *last_backup;
2627

2728
/* DATE are always required */
2829
if (backup_id == 0)
@@ -41,31 +42,38 @@ do_delete(time_t backup_id)
4142
if (!backup_list)
4243
elog(ERROR, "No backup list found, can't process any more.");
4344

44-
/* Find backups to be deleted */
45+
/* Find backup to be deleted */
4546
for (i = 0; i < parray_num(backup_list); i++)
4647
{
47-
pgBackup *backup = (pgBackup *) parray_get(backup_list, i);
48+
last_backup = (pgBackup *) parray_get(backup_list, i);
49+
if (last_backup->status == BACKUP_STATUS_OK &&
50+
last_backup->start_time == backup_id
51+
)
52+
goto found_backup;
53+
}
4854

49-
/* delete backup and update status to DELETED */
50-
if (do_delete)
51-
{
52-
/* check for interrupt */
53-
if (interrupted)
54-
elog(ERROR, "interrupted during delete backup");
55+
elog(ERROR, "no backup found, cannot delete.");
5556

56-
pgBackupDeleteFiles(backup);
57-
continue;
58-
}
57+
found_backup:
58+
b_index = i;
59+
/* check for interrupt */
60+
if (interrupted)
61+
elog(ERROR, "interrupted during delete backup");
5962

60-
/* Found the latest full backup */
61-
if (backup->backup_mode >= BACKUP_MODE_FULL &&
62-
backup->status == BACKUP_STATUS_OK &&
63-
backup->start_time <= backup_id)
64-
{
65-
do_delete = true;
66-
oldest_lsn = backup->start_lsn;
67-
oldest_tli = backup->tli;
68-
}
63+
/* just do it */
64+
pgBackupDeleteFiles(last_backup);
65+
66+
/* remove all increments after removed backup */
67+
for (i = b_index - 1; i >= 0; i--)
68+
{
69+
pgBackup *backup = (pgBackup *) parray_get(backup_list, i);
70+
if (backup->backup_mode >= BACKUP_MODE_FULL)
71+
break;
72+
if (backup->status == BACKUP_STATUS_OK ||
73+
backup->backup_mode == BACKUP_MODE_DIFF_PAGE ||
74+
backup->backup_mode == BACKUP_MODE_DIFF_PTRACK
75+
)
76+
pgBackupDeleteFiles(backup);
6977
}
7078

7179
/* release catalog lock */
@@ -74,13 +82,37 @@ do_delete(time_t backup_id)
7482
/* cleanup */
7583
parray_walk(backup_list, pgBackupFree);
7684
parray_free(backup_list);
77-
7885
/*
7986
* Delete in archive WAL segments that are not needed anymore. The oldest
8087
* segment to be kept is the first segment that the oldest full backup
8188
* found around needs to keep.
8289
*/
83-
if (!XLogRecPtrIsInvalid(oldest_lsn))
90+
if (delete_wal)
91+
{
92+
/* Lock backup catalog */
93+
ret = catalog_lock();
94+
if (ret == -1)
95+
elog(ERROR, "can't lock backup catalog.");
96+
else if (ret == 1)
97+
elog(ERROR,
98+
"another pg_arman is running, stop delete.");
99+
100+
backup_list = catalog_get_backup_list(0);
101+
for (i = 0; i < parray_num(backup_list); i++)
102+
{
103+
last_backup = (pgBackup *) parray_get(backup_list, i);
104+
if (last_backup->status == BACKUP_STATUS_OK)
105+
{
106+
oldest_lsn = last_backup->start_lsn;
107+
oldest_tli = last_backup->tli;
108+
}
109+
}
110+
catalog_unlock();
111+
parray_walk(backup_list, pgBackupFree);
112+
parray_free(backup_list);
113+
}
114+
115+
if (delete_wal && !XLogRecPtrIsInvalid(oldest_lsn))
84116
{
85117
XLogSegNo targetSegNo;
86118
char oldestSegmentNeeded[MAXFNAMELEN];
@@ -263,7 +295,8 @@ pgBackupDeleteFiles(pgBackup *backup)
263295

264296
time2iso(timestamp, lengthof(timestamp), backup->start_time);
265297

266-
elog(INFO, "delete: %s", timestamp);
298+
elog(INFO, "delete: %s %s", base36enc(backup->start_time), timestamp);
299+
267300

268301
/*
269302
* Update STATUS to BACKUP_STATUS_DELETING in preparation for the case which
@@ -277,7 +310,7 @@ pgBackupDeleteFiles(pgBackup *backup)
277310

278311
/* list files to be deleted */
279312
files = parray_new();
280-
pgBackupGetPath(backup, path, lengthof(path), DATABASE_DIR);
313+
pgBackupGetPath(backup, path, lengthof(path), NULL);
281314
dir_list_file(files, path, NULL, true, true);
282315

283316
/* delete leaf node first */
@@ -304,16 +337,6 @@ pgBackupDeleteFiles(pgBackup *backup)
304337
}
305338
}
306339

307-
/*
308-
* After deleting all of the backup files, update STATUS to
309-
* BACKUP_STATUS_DELETED.
310-
*/
311-
if (!check)
312-
{
313-
backup->status = BACKUP_STATUS_DELETED;
314-
pgBackupWriteIni(backup);
315-
}
316-
317340
parray_walk(files, pgFileFree);
318341
parray_free(files);
319342

expected/backup.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ OK. Let's try to test --keep-data-generations=1.
2424
9
2525
0
2626
Number of remaining full backups validated: 2
27-
Number of deleted backups : 2
27+
Number of deleted backups : 0
2828
6
2929
###### BACKUP COMMAND TEST-0005 ######
3030
###### switch backup mode from page to full ######

expected/delete.out

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
###### delete full backups ######
44
try to delete the oldest backup
55
2
6-
1
7-
Number of deleted backups should be 1, is it so?: 1
6+
0
7+
Number of deleted backups should be 1, is it so?: 0
88
###### DELETE COMMAND TEST-0002 ######
99
###### keep backups which are necessary for recovery ######
1010
try to delete before third backup
1111
3
12-
1
13-
Number of deleted backups should be 1, is it so?: 1
12+
0
13+
Number of deleted backups should be 1, is it so?: 0

expected/option.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ Restore options:
3636
Catalog options:
3737
-a, --show-all show deleted backup too
3838

39+
Delete options:
40+
--wal remove unnecessary wal archives also
41+
3942
Connection options:
4043
-d, --dbname=DBNAME database to connect
4144
-h, --host=HOSTNAME database server host or socket directory

expected/show.out

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,3 @@ remove a file from backup intentionally
1717
0
1818
NG: CORRUPT status is not shown.
1919

20-
###### SHOW COMMAND TEST-0004 ######
21-
###### Status DELETED ######
22-
0
23-
0
24-
0
25-
0
26-
0
27-
OK: DELETED status is shown properly.
28-

pg_arman.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ bool stream_wal = false;
3939
bool from_replica = false;
4040
static bool backup_logs = false;
4141
bool progress = false;
42+
bool delete_wal = false;
4243

4344
/* restore configuration */
4445
static char *target_time;
@@ -76,6 +77,8 @@ static pgut_option options[] =
7677
{ 'u', 6, "recovery-target-timeline", &target_tli, SOURCE_ENV },
7778
/* catalog options */
7879
{ 'b', 'a', "show-all", &show_all },
80+
/* delete options */
81+
{ 'b', 12, "wal", &delete_wal },
7982
{ 0 }
8083
};
8184

@@ -248,6 +251,8 @@ pgut_help(bool details)
248251
printf(_(" --recovery-target-timeline recovering into a particular timeline\n"));
249252
printf(_("\nCatalog options:\n"));
250253
printf(_(" -a, --show-all show deleted backup too\n"));
254+
printf(_("\nDelete options:\n"));
255+
printf(_(" --wal remove unnecessary wal archives also\n"));
251256
}
252257

253258
static void

pg_arman.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ extern int num_threads;
204204
extern bool stream_wal;
205205
extern bool from_replica;
206206
extern bool progress;
207+
extern bool delete_wal;
207208

208209
/* in backup.c */
209210
extern int do_backup(pgBackupOption bkupopt);

sql/show.sh

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,6 @@ else
6565
fi
6666
echo ''
6767

68-
echo '###### SHOW COMMAND TEST-0004 ######'
69-
echo '###### Status DELETED ######'
70-
init_catalog
71-
pg_arman backup -B ${BACKUP_PATH} -b full -p ${TEST_PGPORT} -d postgres --quiet;echo $?
72-
pg_arman validate -B ${BACKUP_PATH} --quiet > /dev/null 2>&1;echo $?
73-
pg_arman backup -B ${BACKUP_PATH} -b full -p ${TEST_PGPORT} -d postgres --quiet;echo $?
74-
DELETE_DATE=$(get_time_last_backup)
75-
pg_arman validate -B ${BACKUP_PATH} --quiet > /dev/null 2>&1;echo $?
76-
pg_arman delete ${DELETE_DATE} -B ${BACKUP_PATH} > /dev/null 2>&1;echo $?
77-
pg_arman show -B ${BACKUP_PATH} > ${TEST_BASE}/TEST-0004-show.out 2>&1
78-
pg_arman show -a -B ${BACKUP_PATH} > ${TEST_BASE}/TEST-0004-show-all.out 2>&1
79-
if ! grep "DELETED" ${TEST_BASE}/TEST-0004-show.out > /dev/null && grep "DELETED" ${TEST_BASE}/TEST-0004-show-all.out > /dev/null ; then
80-
echo 'OK: DELETED status is shown properly.'
81-
else
82-
echo 'NG: DELETED status is not shown.'
83-
fi
84-
echo ''
85-
8668
# clean up the temporal test data
8769
pg_ctl stop -D ${PGDATA_PATH} -m immediate > /dev/null 2>&1
8870
rm -fr ${PGDATA_PATH}

0 commit comments

Comments
 (0)