Skip to content

Commit 32b5017

Browse files
committed
PGPRO-1504: during validation attemp to revalidate CORRUPT and ORPHAN backups
1 parent 59b5145 commit 32b5017

File tree

6 files changed

+314
-51
lines changed

6 files changed

+314
-51
lines changed

src/pg_probackup.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ typedef enum ProbackupSubcmd
148148

149149

150150
/* special values of pgBackup fields */
151-
#define INVALID_BACKUP_ID 0
151+
#define INVALID_BACKUP_ID 0 /* backup ID is not provided by user */
152152
#define BYTES_INVALID (-1)
153153

154154
typedef struct pgBackupConfig

src/restore.c

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,10 @@ do_restore_or_validate(time_t target_backup_id,
141141
* we must find the first valid(!) backup.
142142
*/
143143

144-
if (is_restore && target_backup_id == 0 && current_backup->status != BACKUP_STATUS_OK)
144+
if (is_restore &&
145+
!dest_backup &&
146+
target_backup_id == INVALID_BACKUP_ID &&
147+
current_backup->status != BACKUP_STATUS_OK)
145148
{
146149
elog(WARNING, "Skipping backup %s, because it has non-valid status: %s",
147150
base36enc(current_backup->start_time), status2str(current_backup->status));
@@ -156,9 +159,19 @@ do_restore_or_validate(time_t target_backup_id,
156159
|| target_backup_id == INVALID_BACKUP_ID)
157160
&& !dest_backup)
158161
{
162+
163+
/* backup is not ok, but in case of CORRUPT, ORPHAN or DONE revalidation can be done */
159164
if (current_backup->status != BACKUP_STATUS_OK)
160-
elog(ERROR, "Backup %s has status: %s",
161-
base36enc(current_backup->start_time), status2str(current_backup->status));
165+
{
166+
if (current_backup->status == BACKUP_STATUS_DONE ||
167+
current_backup->status == BACKUP_STATUS_ORPHAN ||
168+
current_backup->status == BACKUP_STATUS_CORRUPT)
169+
elog(WARNING, "Backup %s has status: %s",
170+
base36enc(current_backup->start_time), status2str(current_backup->status));
171+
else
172+
elog(ERROR, "Backup %s has status: %s",
173+
base36enc(current_backup->start_time), status2str(current_backup->status));
174+
}
162175

163176
if (target_tli)
164177
{
@@ -197,17 +210,24 @@ do_restore_or_validate(time_t target_backup_id,
197210
if (current_backup->backup_mode == BACKUP_MODE_FULL)
198211
{
199212
if (current_backup->status != BACKUP_STATUS_OK)
200-
elog(ERROR, "base backup %s for given backup %s is in %s status",
201-
base36enc_dup(current_backup->start_time),
202-
base36enc_dup(dest_backup->start_time),
203-
status2str(current_backup->status));
204-
else
205213
{
206-
/* We found both dest and base backups. */
207-
base_full_backup = current_backup;
208-
base_full_backup_index = i;
209-
break;
214+
/* Full backup revalidation can be done only for DONE and CORRUPT */
215+
if (current_backup->status == BACKUP_STATUS_DONE ||
216+
current_backup->status == BACKUP_STATUS_CORRUPT)
217+
elog(WARNING, "base backup %s for given backup %s is in %s status, trying to revalidate",
218+
base36enc_dup(current_backup->start_time),
219+
base36enc_dup(dest_backup->start_time),
220+
status2str(current_backup->status));
221+
else
222+
elog(ERROR, "base backup %s for given backup %s is in %s status",
223+
base36enc_dup(current_backup->start_time),
224+
base36enc_dup(dest_backup->start_time),
225+
status2str(current_backup->status));
210226
}
227+
/* We found both dest and base backups. */
228+
base_full_backup = current_backup;
229+
base_full_backup_index = i;
230+
break;
211231
}
212232
else
213233
/* It`s ok to skip incremental backup */
@@ -235,6 +255,7 @@ do_restore_or_validate(time_t target_backup_id,
235255
{
236256
pgBackup *backup = (pgBackup *) parray_get(backups, i);
237257
pgBackupValidate(backup);
258+
/* Maybe we should be more paranoid and check for !BACKUP_STATUS_OK? */
238259
if (backup->status == BACKUP_STATUS_CORRUPT)
239260
{
240261
corrupted_backup = backup;

src/validate.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,27 @@ pgBackupValidate(pgBackup *backup)
3939
validate_files_args *validate_threads_args[num_threads];
4040
int i;
4141

42+
/* Revalidation is attempted for DONE, ORPHAN and CORRUPT backups */
4243
if (backup->status != BACKUP_STATUS_OK &&
43-
backup->status != BACKUP_STATUS_DONE)
44+
backup->status != BACKUP_STATUS_DONE &&
45+
backup->status != BACKUP_STATUS_ORPHAN &&
46+
backup->status != BACKUP_STATUS_CORRUPT)
4447
{
45-
elog(INFO, "Backup %s has status %s. Skip validation.",
48+
elog(WARNING, "Backup %s has status %s. Skip validation.",
4649
base36enc(backup->start_time), status2str(backup->status));
50+
corrupted_backup_found = true;
4751
return;
4852
}
4953

50-
elog(INFO, "Validating backup %s", base36enc(backup->start_time));
54+
if (backup->status == BACKUP_STATUS_OK || backup->status == BACKUP_STATUS_DONE)
55+
elog(INFO, "Validating backup %s", base36enc(backup->start_time));
56+
else
57+
elog(INFO, "Revalidating backup %s", base36enc(backup->start_time));
5158

5259
if (backup->backup_mode != BACKUP_MODE_FULL &&
5360
backup->backup_mode != BACKUP_MODE_DIFF_PAGE &&
5461
backup->backup_mode != BACKUP_MODE_DIFF_PTRACK)
55-
elog(INFO, "Invalid backup_mode of backup %s", base36enc(backup->start_time));
62+
elog(WARNING, "Invalid backup_mode of backup %s", base36enc(backup->start_time));
5663

5764
pgBackupGetPath(backup, base_path, lengthof(base_path), DATABASE_DIR);
5865
pgBackupGetPath(backup, path, lengthof(path), DATABASE_FILE_LIST);
@@ -226,7 +233,7 @@ do_validate_all(void)
226233

227234
if (corrupted_backup_found)
228235
{
229-
elog(INFO, "Some backups are not valid");
236+
elog(WARNING, "Some backups are not valid");
230237
return 1;
231238
}
232239
else
@@ -308,7 +315,6 @@ do_validate_instance(void)
308315
continue;
309316
else
310317
{
311-
312318
backup->status = BACKUP_STATUS_ORPHAN;
313319
pgBackupWriteBackupControlFile(backup);
314320

tests/backup_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def test_incremental_backup_corrupt_full(self):
204204
file) in e.message and
205205
"WARNING: Backup {0} data files are corrupted\n".format(
206206
backup_id) in e.message and
207-
"INFO: Some backups are not valid\n" in e.message,
207+
"WARNING: Some backups are not valid\n" in e.message,
208208
"\n Unexpected Error Message: {0}\n CMD: {1}".format(
209209
repr(e.message), self.cmd))
210210

tests/helpers/ptrack_helpers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ def show_pb(
636636
header_element.rstrip() for header_element in header_split
637637
]
638638
for backup_record in body:
639+
backup_record = backup_record.rstrip()
639640
# split list with str for every backup record element
640641
backup_record_split = re.split(" +", backup_record)
641642
# Remove empty items

0 commit comments

Comments
 (0)