@@ -1021,16 +1021,57 @@ do_delete_instance(void)
1021
1021
return 0 ;
1022
1022
}
1023
1023
1024
+ /* checks that backup childs has status like parent */
1025
+ bool checkChilds (parray * backup_list , time_t backup_id )
1026
+ {
1027
+ int i ;
1028
+ pgBackup * target_backup = NULL ;
1029
+ pgBackup * backup ;
1030
+ /* search target bakcup */
1031
+ for (i = 0 ; i < parray_num (backup_list ); i ++ )
1032
+ {
1033
+ backup = (pgBackup * )parray_get (backup_list , i );
1034
+ if (backup -> start_time == backup_id )
1035
+ {
1036
+ target_backup = backup ;
1037
+ break ;
1038
+ }
1039
+ }
1040
+ if (target_backup == NULL ) return false;
1041
+
1042
+ /* check childs */
1043
+ for (i = 0 ; i < parray_num (backup_list ); i ++ )
1044
+ {
1045
+ backup = (pgBackup * )parray_get (backup_list , i );
1046
+ /* check if backup is descendant of delete target */
1047
+ if (is_parent (target_backup -> start_time , backup , false))
1048
+ {
1049
+ if (backup -> status != target_backup -> status ){
1050
+ elog (INFO , "Skip deleting the backup %s because the backup has children with a different status" ,
1051
+ base36enc (target_backup -> start_time ));
1052
+ return false;
1053
+ }
1054
+ /* recursive call */
1055
+ if (!checkChilds (backup_list , backup -> start_time )) return false;
1056
+ }
1057
+ }
1058
+ return true;
1059
+ }
1060
+
1024
1061
/* Delete all backups of given status in instance */
1025
1062
void
1026
1063
do_delete_status (InstanceConfig * instance_config , const char * status )
1027
1064
{
1028
- parray * backup_list ;
1065
+ parray * backup_list , * delete_list ; ;
1029
1066
int i ;
1030
1067
const char * pretty_status ;
1031
- int n_deleted = 0 ;
1068
+ int n_deleted = 0 , n_found = 0 ;
1069
+ size_t size_to_delete = 0 ;
1070
+ char size_to_delete_pretty [20 ];
1071
+ pgBackup * backup ;
1032
1072
1033
1073
BackupStatus status_for_delete = str2status (status );
1074
+ delete_list = parray_new ();
1034
1075
1035
1076
if (status_for_delete == BACKUP_STATUS_INVALID )
1036
1077
elog (ERROR , "Unknown value for '--status' option: '%s'" , status );
@@ -1052,28 +1093,63 @@ do_delete_status(InstanceConfig *instance_config, const char *status)
1052
1093
1053
1094
elog (INFO , "Deleting all backups with status '%s'" , pretty_status );
1054
1095
1055
- /* Delete all backups with specified status */
1096
+ /* Selects backups for deleting to delete_list array. Will delete all backups with specified status */
1056
1097
for (i = 0 ; i < parray_num (backup_list ); i ++ )
1057
1098
{
1058
- pgBackup * backup = (pgBackup * ) parray_get (backup_list , i );
1099
+ backup = (pgBackup * ) parray_get (backup_list , i );
1059
1100
1060
1101
if (backup -> status == status_for_delete )
1061
1102
{
1062
- lock_backup (backup );
1063
- delete_backup_files (backup );
1103
+
1104
+ n_found ++ ;
1105
+ if (!checkChilds (backup_list , backup -> start_time )) continue ;
1106
+
1107
+ elog (dry_run ? INFO : LOG , "Backup %s %s be deleted" ,
1108
+ base36enc (backup -> start_time ), dry_run ? "can" : "will" );
1109
+ size_to_delete += backup -> data_bytes ;
1110
+ if (backup -> stream )
1111
+ size_to_delete += backup -> wal_bytes ;
1112
+ if (!dry_run ){
1113
+ parray_append (delete_list , backup );
1114
+ }
1064
1115
n_deleted ++ ;
1116
+
1065
1117
}
1066
1118
}
1067
1119
1068
- if (n_deleted > 0 )
1120
+ /* Inform about data size to free */
1121
+ if (size_to_delete >= 0 )
1122
+ {
1123
+ pretty_size (size_to_delete , size_to_delete_pretty , lengthof (size_to_delete_pretty ));
1124
+ elog (INFO , "Resident data size to free by delete of %i backups: %s" ,
1125
+ n_deleted , size_to_delete_pretty );
1126
+ }
1127
+
1128
+ /* delete selected backups */
1129
+ if (!dry_run )
1130
+ {
1131
+ for (i = 0 ; i < parray_num (delete_list ); i ++ )
1132
+ {
1133
+ backup = (pgBackup * )parray_get (delete_list , i );
1134
+ if (lock_backup (backup ))
1135
+ {
1136
+ delete_backup_files (backup );
1137
+ }
1138
+ else n_deleted -- ;
1139
+ }
1069
1140
elog (INFO , "Successfully deleted %i %s with status '%s' from instance '%s'" ,
1070
1141
n_deleted , n_deleted == 1 ? "backup" : "backups" ,
1071
1142
pretty_status , instance_config -> name );
1072
- else
1143
+
1144
+ }
1145
+
1146
+
1147
+ if (n_found == 0 )
1073
1148
elog (WARNING , "Instance '%s' has no backups with status '%s'" ,
1074
1149
instance_config -> name , pretty_status );
1075
1150
1076
1151
/* Cleanup */
1152
+ parray_free (delete_list );
1077
1153
parray_walk (backup_list , pgBackupFree );
1078
1154
parray_free (backup_list );
1079
1155
}
0 commit comments