mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2025-11-24 08:46:54 +08:00
ec volume deletion is generation-aware
This commit is contained in:
@@ -417,6 +417,7 @@ message VolumeEcShardsDeleteRequest {
|
||||
uint32 volume_id = 1;
|
||||
string collection = 2;
|
||||
repeated uint32 shard_ids = 3;
|
||||
uint32 generation = 4; // Generation support for EC vacuum cleanup
|
||||
}
|
||||
message VolumeEcShardsDeleteResponse {
|
||||
}
|
||||
|
||||
@@ -3285,6 +3285,7 @@ type VolumeEcShardsDeleteRequest struct {
|
||||
VolumeId uint32 `protobuf:"varint,1,opt,name=volume_id,json=volumeId,proto3" json:"volume_id,omitempty"`
|
||||
Collection string `protobuf:"bytes,2,opt,name=collection,proto3" json:"collection,omitempty"`
|
||||
ShardIds []uint32 `protobuf:"varint,3,rep,packed,name=shard_ids,json=shardIds,proto3" json:"shard_ids,omitempty"`
|
||||
Generation uint32 `protobuf:"varint,4,opt,name=generation,proto3" json:"generation,omitempty"` // Generation support for EC vacuum cleanup
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -3340,6 +3341,13 @@ func (x *VolumeEcShardsDeleteRequest) GetShardIds() []uint32 {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *VolumeEcShardsDeleteRequest) GetGeneration() uint32 {
|
||||
if x != nil {
|
||||
return x.Generation
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type VolumeEcShardsDeleteResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
@@ -6538,13 +6546,16 @@ const file_volume_server_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"generation\x18\t \x01(\rR\n" +
|
||||
"generation\"\x1c\n" +
|
||||
"\x1aVolumeEcShardsCopyResponse\"w\n" +
|
||||
"\x1aVolumeEcShardsCopyResponse\"\x97\x01\n" +
|
||||
"\x1bVolumeEcShardsDeleteRequest\x12\x1b\n" +
|
||||
"\tvolume_id\x18\x01 \x01(\rR\bvolumeId\x12\x1e\n" +
|
||||
"\n" +
|
||||
"collection\x18\x02 \x01(\tR\n" +
|
||||
"collection\x12\x1b\n" +
|
||||
"\tshard_ids\x18\x03 \x03(\rR\bshardIds\"\x1e\n" +
|
||||
"\tshard_ids\x18\x03 \x03(\rR\bshardIds\x12\x1e\n" +
|
||||
"\n" +
|
||||
"generation\x18\x04 \x01(\rR\n" +
|
||||
"generation\"\x1e\n" +
|
||||
"\x1cVolumeEcShardsDeleteResponse\"\x96\x01\n" +
|
||||
"\x1aVolumeEcShardsMountRequest\x12\x1b\n" +
|
||||
"\tvolume_id\x18\x01 \x01(\rR\bvolumeId\x12\x1e\n" +
|
||||
|
||||
@@ -258,9 +258,15 @@ func (vs *VolumeServer) VolumeEcShardsCopy(ctx context.Context, req *volume_serv
|
||||
// the shard should not be mounted before calling this.
|
||||
func (vs *VolumeServer) VolumeEcShardsDelete(ctx context.Context, req *volume_server_pb.VolumeEcShardsDeleteRequest) (*volume_server_pb.VolumeEcShardsDeleteResponse, error) {
|
||||
|
||||
bName := erasure_coding.EcShardBaseFileName(req.Collection, int(req.VolumeId))
|
||||
// Use generation-aware base filename if generation is specified
|
||||
var bName string
|
||||
if req.Generation > 0 {
|
||||
bName = erasure_coding.EcShardBaseFileNameWithGeneration(req.Collection, int(req.VolumeId), req.Generation)
|
||||
} else {
|
||||
bName = erasure_coding.EcShardBaseFileName(req.Collection, int(req.VolumeId))
|
||||
}
|
||||
|
||||
glog.V(0).Infof("ec volume %s shard delete %v", bName, req.ShardIds)
|
||||
glog.V(0).Infof("ec volume %s shard delete %v generation %d", bName, req.ShardIds, req.Generation)
|
||||
|
||||
for _, location := range vs.store.Locations {
|
||||
if err := deleteEcShardIdsForEachLocation(bName, location, req.ShardIds); err != nil {
|
||||
|
||||
@@ -1110,29 +1110,18 @@ func (t *EcVacuumTask) deleteGenerationFilesFromNode(client volume_server_pb.Vol
|
||||
VolumeId: t.volumeID,
|
||||
Collection: t.collection,
|
||||
ShardIds: allShardIds,
|
||||
Generation: generation, // Pass generation for proper file cleanup
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// Log warning but don't fail - the unmount should have made files safe for cleanup
|
||||
t.LogWarning("VolumeEcShardsDelete returned error - this is expected for generation > 0", map[string]interface{}{
|
||||
t.LogWarning("VolumeEcShardsDelete returned error", map[string]interface{}{
|
||||
"volume_id": t.volumeID,
|
||||
"generation": generation,
|
||||
"error": err.Error(),
|
||||
"note": "Generation > 0 files need manual cleanup or volume server extension",
|
||||
"note": "File deletion failed but files were unmounted",
|
||||
})
|
||||
|
||||
// For generation > 0, the files are unmounted but not deleted
|
||||
// This is a known limitation - the volume server would need to be extended
|
||||
// to support generation-aware file deletion in VolumeEcShardsDelete
|
||||
if generation > 0 {
|
||||
t.LogInfo("Generation > 0 file cleanup limitation", map[string]interface{}{
|
||||
"volume_id": t.volumeID,
|
||||
"generation": generation,
|
||||
"status": "unmounted_but_not_deleted",
|
||||
"note": "Files are unmounted from memory but remain on disk until manual cleanup",
|
||||
})
|
||||
}
|
||||
|
||||
// Don't return error - unmounting is the primary safety requirement
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user