From 1e0d64c04883a8d7b09677e9721f9e189743e2f3 Mon Sep 17 00:00:00 2001 From: chrislu Date: Wed, 26 Oct 2022 12:32:24 -0700 Subject: [PATCH] master: delete partially created replicated volumes during volume growth fix https://github.com/seaweedfs/seaweedfs/discussions/3792#discussioncomment-3973120 --- weed/topology/allocate_volume.go | 12 +++++++++++ weed/topology/volume_growth.go | 34 ++++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/weed/topology/allocate_volume.go b/weed/topology/allocate_volume.go index 41c071f9f..0254eb7e6 100644 --- a/weed/topology/allocate_volume.go +++ b/weed/topology/allocate_volume.go @@ -30,3 +30,15 @@ func AllocateVolume(dn *DataNode, grpcDialOption grpc.DialOption, vid needle.Vol }) } + +func DeleteVolume(dn *DataNode, grpcDialOption grpc.DialOption, vid needle.VolumeId) error { + + return operation.WithVolumeServerClient(false, dn.ServerAddress(), grpcDialOption, func(client volume_server_pb.VolumeServerClient) error { + + _, allocateErr := client.VolumeDelete(context.Background(), &volume_server_pb.VolumeDeleteRequest{ + VolumeId: uint32(vid), + }) + return allocateErr + }) + +} diff --git a/weed/topology/volume_growth.go b/weed/topology/volume_growth.go index 0f9ed2812..71610730f 100644 --- a/weed/topology/volume_growth.go +++ b/weed/topology/volume_growth.go @@ -228,10 +228,11 @@ func (vg *VolumeGrowth) findEmptySlotsForOneVolume(topo *Topology, option *Volum return } -func (vg *VolumeGrowth) grow(grpcDialOption grpc.DialOption, topo *Topology, vid needle.VolumeId, option *VolumeGrowOption, servers ...*DataNode) error { +func (vg *VolumeGrowth) grow(grpcDialOption grpc.DialOption, topo *Topology, vid needle.VolumeId, option *VolumeGrowOption, servers ...*DataNode) (growErr error) { + var createdVolumes []storage.VolumeInfo for _, server := range servers { if err := AllocateVolume(server, grpcDialOption, vid, option); err == nil { - vi := storage.VolumeInfo{ + createdVolumes = append(createdVolumes, storage.VolumeInfo{ Id: vid, Size: 0, Collection: option.Collection, @@ -239,14 +240,31 @@ func (vg *VolumeGrowth) grow(grpcDialOption grpc.DialOption, topo *Topology, vid Ttl: option.Ttl, Version: needle.CurrentVersion, DiskType: option.DiskType.String(), - } + }) + glog.V(0).Infof("Created Volume %d on %s", vid, server.NodeImpl.String()) + } else { + glog.Warningf("Failed to assign volume %d on %s: %v", vid, server.NodeImpl.String(), err) + growErr = fmt.Errorf("failed to assign volume %d on %s: %v", vid, server.NodeImpl.String(), err) + break + } + } + + if growErr == nil { + for i, vi := range createdVolumes { + server := servers[i] server.AddOrUpdateVolume(vi) topo.RegisterVolumeLayout(vi, server) - glog.V(0).Infoln("Created Volume", vid, "on", server.NodeImpl.String()) - } else { - glog.V(0).Infoln("Failed to assign volume", vid, "to", servers, "error", err) - return fmt.Errorf("Failed to assign %d: %v", vid, err) + glog.V(0).Infof("Registered Volume %d on %s", vid, server.NodeImpl.String()) + } + } else { + // cleaning up created volume replicas + for i, vi := range createdVolumes { + server := servers[i] + if err := DeleteVolume(server, grpcDialOption, vi.Id); err != nil { + glog.Warningf("Failed to clean up volume %d on %s", vid, server.NodeImpl.String()) + } } } - return nil + + return growErr }