From 1dcf721ce31c4f534783d877608b1a490afbc1b9 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 2 Nov 2026 12:09:47 -0800 Subject: [PATCH] shell: name the copies a partial empty-volume delete leaves behind Once some copies of a volume are deleted, a rerun of volume.deleteEmpty skips the rest as under-replicated, and the shell keeps no state to finish them. Log each copy whose delete failed with the volume.delete command that removes it once it is empty. Co-Authored-By: Claude Opus 5.5 --- weed/shell/command_volume_delete_empty.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/weed/shell/command_volume_delete_empty.go b/weed/shell/command_volume_delete_empty.go index f2c04f59aa..68f6f7e09f 100644 --- a/weed/shell/command_volume_delete_empty.go +++ b/weed/shell/command_volume_delete_empty.go @@ -86,6 +86,7 @@ func (c *commandVolumeDeleteEmpty) Do(args []string, commandEnv *CommandEnv, wri if !isEmptyVolumeCopiesDeleteCandidate(replicas, quietSeconds, nowUnixSeconds, collectionMatcher) { continue } + var kept []pb.ServerAddress for _, r := range replicas { dn := r.location.dataNode if !*applyBalancing { @@ -96,9 +97,17 @@ func (c *commandVolumeDeleteEmpty) Do(args []string, commandEnv *CommandEnv, wri onlyGarbage := r.info.FileCount > 0 && r.info.FileCount <= r.info.DeleteCount // onlyEmpty stays set so a pre-upgrade server checks // emptiness and refuses instead of deleting unseen. + server := pb.NewServerAddressFromDataNode(dn) if deleteErr := deleteVolume(context.Background(), commandEnv.option.GrpcDialOption, needle.VolumeId(vid), - pb.NewServerAddressFromDataNode(dn), true, onlyGarbage, false); deleteErr != nil { + server, true, onlyGarbage, false); deleteErr != nil { err = deleteErr + kept = append(kept, server) + } + } + // a rerun skips the survivors as under-replicated + if len(kept) < len(replicas) { + for _, server := range kept { + log.Printf("volume %d stays on %s after its other copies were deleted; once it is empty, remove it with volume.delete -node %s -volumeId %d", vid, server, server, vid) } } }