@@ -90,8 +90,10 @@ do_restore_or_validate(time_t target_backup_id,
9090 pgBackup * current_backup = NULL ;
9191 pgBackup * dest_backup = NULL ;
9292 pgBackup * base_full_backup = NULL ;
93+ pgBackup * corrupted_backup = NULL ;
9394 int dest_backup_index = 0 ;
9495 int base_full_backup_index = 0 ;
96+ int corrupted_backup_index = 0 ;
9597 char * action = is_restore ? "Restore" :"Validate" ;
9698
9799 if (is_restore )
@@ -205,7 +207,7 @@ do_restore_or_validate(time_t target_backup_id,
205207 }
206208 }
207209 else
208- /* Skip differential backups are ok */
210+ /* It`s ok to skip incremental backup */
209211 continue ;
210212 }
211213 }
@@ -220,36 +222,77 @@ do_restore_or_validate(time_t target_backup_id,
220222 if (is_restore )
221223 check_tablespace_mapping (dest_backup );
222224
225+ if (dest_backup -> backup_mode != BACKUP_MODE_FULL )
226+ elog (INFO , "Validating parents for backup %s" , base36enc (dest_backup -> start_time ));
227+
223228 /*
224229 * Validate backups from base_full_backup to dest_backup.
225230 */
226231 for (i = base_full_backup_index ; i >= dest_backup_index ; i -- )
227232 {
228233 pgBackup * backup = (pgBackup * ) parray_get (backups , i );
229234 pgBackupValidate (backup );
235+ if (backup -> status == BACKUP_STATUS_CORRUPT )
236+ {
237+ corrupted_backup = backup ;
238+ corrupted_backup_index = i ;
239+ break ;
240+ }
241+ }
242+ /* There is no point in wal validation
243+ * if there is corrupted backup between base_backup and dest_backup
244+ */
245+ if (!corrupted_backup )
246+ /*
247+ * Validate corresponding WAL files.
248+ * We pass base_full_backup timeline as last argument to this function,
249+ * because it's needed to form the name of xlog file.
250+ */
251+ validate_wal (dest_backup , arclog_path , rt -> recovery_target_time ,
252+ rt -> recovery_target_xid , base_full_backup -> tli );
253+
254+ /* Set every incremental backup between corrupted backup and nearest FULL backup as orphans */
255+ if (corrupted_backup )
256+ {
257+ for (i = corrupted_backup_index - 1 ; i >= 0 ; i -- )
258+ {
259+ pgBackup * backup = (pgBackup * ) parray_get (backups , i );
260+ /* Mark incremental OK backup as orphan */
261+ if (backup -> backup_mode == BACKUP_MODE_FULL )
262+ break ;
263+ if (backup -> status != BACKUP_STATUS_OK )
264+ continue ;
265+ else
266+ {
267+ backup -> status = BACKUP_STATUS_ORPHAN ;
268+ pgBackupWriteBackupControlFile (backup );
269+ elog (WARNING , "Backup %s is orphaned because his parent %s is corrupted" ,
270+ base36enc (backup -> start_time ), base36enc (corrupted_backup -> start_time ));
271+ }
272+ }
230273 }
231274
232275 /*
233- * Validate corresponding WAL files.
234- * We pass base_full_backup timeline as last argument to this function,
235- * because it's needed to form the name of xlog file.
276+ * If dest backup is corrupted or was orphaned in previous check
277+ * produce corresponding error message
236278 */
237- validate_wal (dest_backup , arclog_path , rt -> recovery_target_time ,
238- rt -> recovery_target_xid , base_full_backup -> tli );
239-
279+ if (dest_backup -> status == BACKUP_STATUS_OK )
280+ elog (INFO , "Backup %s is valid." , base36enc (dest_backup -> start_time ));
281+ else if (dest_backup -> status == BACKUP_STATUS_CORRUPT )
282+ elog (ERROR , "Backup %s is corrupt." , base36enc (dest_backup -> start_time ));
283+ else if (dest_backup -> status == BACKUP_STATUS_ORPHAN )
284+ elog (ERROR , "Backup %s is orphan." , base36enc (dest_backup -> start_time ));
285+ else
286+ elog (ERROR , "Backup %s has status: %s" ,
287+ base36enc (dest_backup -> start_time ), status2str (dest_backup -> status ));
240288
241289 /* We ensured that all backups are valid, now restore if required */
242290 if (is_restore )
243291 {
244- pgBackup * backup ;
245292 for (i = base_full_backup_index ; i >= dest_backup_index ; i -- )
246293 {
247- backup = (pgBackup * ) parray_get (backups , i );
248- if (backup -> status == BACKUP_STATUS_OK )
249- restore_backup (backup );
250- else
251- elog (ERROR , "backup %s is not valid" ,
252- base36enc (backup -> start_time ));
294+ pgBackup * backup = (pgBackup * ) parray_get (backups , i );
295+ restore_backup (backup );
253296 }
254297
255298 /*
0 commit comments