mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-24 15:00:43 +02:00
fix(ec): pass per-volume data-shard count to the parity-shard split (#9781)
* fix(ec): pass per-volume data-shard count to the parity-shard split ShardsInfo.DeleteParityShards/MinusParityShards looped ids 10..13, assuming the fixed 10+4 layout. For a non-default ratio this splits data vs parity wrong — a wide ratio (12+4, 16+6) drops real data ids >= 10, which breaks ec.decode. They now take a dataShards argument (<= 0 falls back to DataShardsCount) and clear ids dataShards..MaxShardCount. ec.decode threads the data-shard count from collectEcNodeShardsInfo to both split call sites, and admin LogicalSize passes DataShardsCount. Also: EC cleanup now sets an explicit per-disk storage impact (-len(ShardIds)) instead of falling back to the TotalShardsCount constant, so freed-capacity accounting matches the shards actually removed. OSS is always 10+4, so behavior is unchanged here; this keeps the split ratio-correct and the API aligned with the enterprise per-volume override. Adds parity-split ratio tests. * ec: clear parity shards in one locked pass Address review: DeleteParityShards looped si.Delete, taking the lock once per id. shards is sorted by Id and shardBits is a bitmap, so mask off the high bits and truncate the sorted slice at the first parity id (binary search) under a single lock. Preserves the dataShards<=0 -> DataShardsCount default.
This commit is contained in:
1 parent
f410d975c7
commit
ca81c0c525
8 files changed
+100
-24
No files matched your search
@@ -115,7 +115,7 @@ func doEcDecode(commandEnv *CommandEnv, topoInfo *master_pb.TopologyInfo, collec
|
||||
}
|
||||
|
||||
// find volume location
|
||||
nodeToEcShardsInfo := collectEcNodeShardsInfo(topoInfo, vid, diskType)
|
||||
nodeToEcShardsInfo, dataShards := collectEcNodeShardsInfo(topoInfo, vid, diskType)
|
||||
|
||||
fmt.Printf("ec volume %d shard locations: %+v\n", vid, nodeToEcShardsInfo)
|
||||
|
||||
@@ -148,7 +148,7 @@ func doEcDecode(commandEnv *CommandEnv, topoInfo *master_pb.TopologyInfo, collec
|
||||
}
|
||||
|
||||
// collect ec shards to the server with most space
|
||||
targetNodeLocation, err := collectEcShards(commandEnv, nodeToEcShardsInfo, collection, vid, eligibleTargets)
|
||||
targetNodeLocation, err := collectEcShards(commandEnv, nodeToEcShardsInfo, collection, vid, eligibleTargets, dataShards)
|
||||
if err != nil {
|
||||
return fmt.Errorf("collectEcShards for volume %d: %v", vid, err)
|
||||
}
|
||||
@@ -281,7 +281,7 @@ func generateNormalVolume(grpcDialOption grpc.DialOption, vid needle.VolumeId, c
|
||||
|
||||
}
|
||||
|
||||
func collectEcShards(commandEnv *CommandEnv, nodeToShardsInfo map[pb.ServerAddress]*erasure_coding.ShardsInfo, collection string, vid needle.VolumeId, eligibleTargets map[pb.ServerAddress]struct{}) (targetNodeLocation pb.ServerAddress, err error) {
|
||||
func collectEcShards(commandEnv *CommandEnv, nodeToShardsInfo map[pb.ServerAddress]*erasure_coding.ShardsInfo, collection string, vid needle.VolumeId, eligibleTargets map[pb.ServerAddress]struct{}, dataShards int) (targetNodeLocation pb.ServerAddress, err error) {
|
||||
|
||||
maxShardCount := -1
|
||||
existingShardsInfo := erasure_coding.NewShardsInfo()
|
||||
@@ -291,7 +291,7 @@ func collectEcShards(commandEnv *CommandEnv, nodeToShardsInfo map[pb.ServerAddre
|
||||
continue
|
||||
}
|
||||
}
|
||||
toBeCopiedShardCount := si.MinusParityShards().Count()
|
||||
toBeCopiedShardCount := si.MinusParityShards(dataShards).Count()
|
||||
if toBeCopiedShardCount > maxShardCount {
|
||||
maxShardCount = toBeCopiedShardCount
|
||||
targetNodeLocation = loc
|
||||
@@ -310,7 +310,7 @@ func collectEcShards(commandEnv *CommandEnv, nodeToShardsInfo map[pb.ServerAddre
|
||||
continue
|
||||
}
|
||||
|
||||
needToCopyShardsInfo := si.Minus(existingShardsInfo).MinusParityShards()
|
||||
needToCopyShardsInfo := si.Minus(existingShardsInfo).MinusParityShards(dataShards)
|
||||
|
||||
err = operation.WithVolumeServerClient(false, targetNodeLocation, commandEnv.option.GrpcDialOption, func(volumeServerClient volume_server_pb.VolumeServerClient) error {
|
||||
|
||||
@@ -401,7 +401,7 @@ func collectEcShardIds(topoInfo *master_pb.TopologyInfo, collectionPattern strin
|
||||
return
|
||||
}
|
||||
|
||||
func collectEcNodeShardsInfo(topoInfo *master_pb.TopologyInfo, vid needle.VolumeId, diskType types.DiskType) map[pb.ServerAddress]*erasure_coding.ShardsInfo {
|
||||
func collectEcNodeShardsInfo(topoInfo *master_pb.TopologyInfo, vid needle.VolumeId, diskType types.DiskType) (map[pb.ServerAddress]*erasure_coding.ShardsInfo, int) {
|
||||
res := make(map[pb.ServerAddress]*erasure_coding.ShardsInfo)
|
||||
eachDataNode(topoInfo, func(dc DataCenterId, rack RackId, dn *master_pb.DataNodeInfo) {
|
||||
if diskInfo, found := dn.DiskInfos[string(diskType)]; found {
|
||||
@@ -423,7 +423,8 @@ func collectEcNodeShardsInfo(topoInfo *master_pb.TopologyInfo, vid needle.Volume
|
||||
}
|
||||
})
|
||||
|
||||
return res
|
||||
// OSS is always 10+4; the per-volume ratio override lives in the enterprise build.
|
||||
return res, erasure_coding.DataShardsCount
|
||||
}
|
||||
|
||||
type decodeDiskUsageState struct {
|
||||
|
||||
Reference in new issue
Block a user