From 514ba7a233e3f108e81f0027727046b1f9ce0cbd Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 11 May 2026 10:56:26 -0700 Subject: [PATCH] fix(master): route ec shard vids to NewEcVids on initial subscribe (#9435) * fix(master): route ec shard vids to NewEcVids on initial subscribe ToVolumeLocations appended EC shard volume IDs to NewVids, so a freshly subscribing master client registered them in the regular-volume map via addLocation instead of addEcLocation until the next heartbeat-driven delta arrived. Append to NewEcVids to match the incremental path. Fixes #9429 * fix(master): dedupe ec vids in initial subscribe snapshot dn.GetEcShards returns per-(vid, diskId) entries, so a single EC volume spread across multiple physical disks on one DataNode emitted the same vid multiple times in NewEcVids. Dedupe so the snapshot carries each vid once. --- weed/topology/topology_info.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/weed/topology/topology_info.go b/weed/topology/topology_info.go index 5749f8669..dd1f59d29 100644 --- a/weed/topology/topology_info.go +++ b/weed/topology/topology_info.go @@ -102,8 +102,17 @@ func (t *Topology) ToVolumeLocations() (volumeLocations []*master_pb.VolumeLocat for _, v := range dn.GetVolumes() { volumeLocation.NewVids = append(volumeLocation.NewVids, uint32(v.Id)) } + // A single EC volume's shards can live on multiple disks of + // one DataNode, so GetEcShards returns per-(vid,disk) entries. + // Dedupe so the snapshot carries each vid once. + seenEcVids := make(map[uint32]struct{}) for _, s := range dn.GetEcShards() { - volumeLocation.NewVids = append(volumeLocation.NewVids, uint32(s.VolumeId)) + vid := uint32(s.VolumeId) + if _, ok := seenEcVids[vid]; ok { + continue + } + seenEcVids[vid] = struct{}{} + volumeLocation.NewEcVids = append(volumeLocation.NewEcVids, vid) } volumeLocations = append(volumeLocations, volumeLocation) }