@@ -123,7 +123,7 @@ do_delete(time_t backup_id)
123123 * which FULL backup should be keeped for redundancy obligation(only valid do),
124124 * but if invalid backup is not guarded by retention - it is removed
125125 */
126- int do_retention (void )
126+ void do_retention (void )
127127{
128128 parray * backup_list = NULL ;
129129 parray * to_keep_list = parray_new ();
@@ -154,7 +154,7 @@ int do_retention(void)
154154 /* Retention is disabled but we still can cleanup wal */
155155 elog (WARNING , "Retention policy is not set" );
156156 if (!delete_wal )
157- return 0 ;
157+ return ;
158158 }
159159 else
160160 /* At least one retention policy is active */
@@ -196,9 +196,6 @@ int do_retention(void)
196196 parray_free (backup_list );
197197 parray_free (to_keep_list );
198198 parray_free (to_purge_list );
199-
200- return 0 ;
201-
202199}
203200
204201/* Evaluate every backup by retention policies and populate purge and keep lists.
@@ -1023,3 +1020,107 @@ do_delete_instance(void)
10231020 elog (INFO , "Instance '%s' successfully deleted" , instance_name );
10241021 return 0 ;
10251022}
1023+
1024+ /* Delete all backups of given status in instance */
1025+ void
1026+ do_delete_status (InstanceConfig * instance_config , const char * status )
1027+ {
1028+ int i ;
1029+ parray * backup_list , * delete_list ;
1030+ const char * pretty_status ;
1031+ int n_deleted = 0 , n_found = 0 ;
1032+ size_t size_to_delete = 0 ;
1033+ char size_to_delete_pretty [20 ];
1034+ pgBackup * backup ;
1035+
1036+ BackupStatus status_for_delete = str2status (status );
1037+ delete_list = parray_new ();
1038+
1039+ if (status_for_delete == BACKUP_STATUS_INVALID )
1040+ elog (ERROR , "Unknown value for '--status' option: '%s'" , status );
1041+
1042+ /*
1043+ * User may have provided status string in lower case, but
1044+ * we should print backup statuses consistently with show command,
1045+ * so convert it.
1046+ */
1047+ pretty_status = status2str (status_for_delete );
1048+
1049+ backup_list = catalog_get_backup_list (instance_config -> name , INVALID_BACKUP_ID );
1050+
1051+ if (parray_num (backup_list ) == 0 )
1052+ {
1053+ elog (WARNING , "Instance '%s' has no backups" , instance_config -> name );
1054+ return ;
1055+ }
1056+
1057+ if (dry_run )
1058+ elog (INFO , "Deleting all backups with status '%s' in dry run mode" , pretty_status );
1059+ else
1060+ elog (INFO , "Deleting all backups with status '%s'" , pretty_status );
1061+
1062+ /* Selects backups with specified status and their children into delete_list array. */
1063+ for (i = 0 ; i < parray_num (backup_list ); i ++ )
1064+ {
1065+ backup = (pgBackup * ) parray_get (backup_list , i );
1066+
1067+ if (backup -> status == status_for_delete )
1068+ {
1069+ n_found ++ ;
1070+
1071+ /* incremental backup can be already in delete_list due to append_children() */
1072+ if (parray_contains (delete_list , backup ))
1073+ continue ;
1074+ parray_append (delete_list , backup );
1075+
1076+ append_children (backup_list , backup , delete_list );
1077+ }
1078+ }
1079+
1080+ parray_qsort (delete_list , pgBackupCompareIdDesc );
1081+
1082+ /* delete and calculate free size from delete_list */
1083+ for (i = 0 ; i < parray_num (delete_list ); i ++ )
1084+ {
1085+ backup = (pgBackup * )parray_get (delete_list , i );
1086+
1087+ elog (INFO , "Backup %s with status %s %s be deleted" ,
1088+ base36enc (backup -> start_time ), status2str (backup -> status ), dry_run ? "can" : "will" );
1089+
1090+ size_to_delete += backup -> data_bytes ;
1091+ if (backup -> stream )
1092+ size_to_delete += backup -> wal_bytes ;
1093+
1094+ if (!dry_run && lock_backup (backup ))
1095+ delete_backup_files (backup );
1096+
1097+ n_deleted ++ ;
1098+ }
1099+
1100+ /* Inform about data size to free */
1101+ if (size_to_delete >= 0 )
1102+ {
1103+ pretty_size (size_to_delete , size_to_delete_pretty , lengthof (size_to_delete_pretty ));
1104+ elog (INFO , "Resident data size to free by delete of %i backups: %s" ,
1105+ n_deleted , size_to_delete_pretty );
1106+ }
1107+
1108+ /* delete selected backups */
1109+ if (!dry_run && n_deleted > 0 )
1110+ elog (INFO , "Successfully deleted %i %s from instance '%s'" ,
1111+ n_deleted , n_deleted == 1 ? "backup" : "backups" ,
1112+ instance_config -> name );
1113+
1114+
1115+ if (n_found == 0 )
1116+ elog (WARNING , "Instance '%s' has no backups with status '%s'" ,
1117+ instance_config -> name , pretty_status );
1118+
1119+ // we don`t do WAL purge here, because it is impossible to correctly handle
1120+ // dry-run case.
1121+
1122+ /* Cleanup */
1123+ parray_free (delete_list );
1124+ parray_walk (backup_list , pgBackupFree );
1125+ parray_free (backup_list );
1126+ }
0 commit comments