mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-11-24 02:59:13 +08:00
Fix/copy before delete replication (#6064)
* fix(shell): volume.fix.replication misplaced volumes unsatisfying replication factor * fix(shell): simplify replication check * fix(shell): add test for satisfyReplicaCurrentLocation
This commit is contained in:
parent
ae8c6d95a6
commit
f1e700ce2f
@ -99,7 +99,7 @@ func (c *commandVolumeFixReplication) Do(args []string, commandEnv *CommandEnv,
|
||||
replica := replicas[0]
|
||||
replicaPlacement, _ := super_block.NewReplicaPlacementFromByte(byte(replica.info.ReplicaPlacement))
|
||||
switch {
|
||||
case replicaPlacement.GetCopyCount() > len(replicas):
|
||||
case replicaPlacement.GetCopyCount() > len(replicas) || !satisfyReplicaCurrentLocation(replicaPlacement, replicas):
|
||||
underReplicatedVolumeIds = append(underReplicatedVolumeIds, vid)
|
||||
case isMisplaced(replicas, replicaPlacement):
|
||||
misplacedVolumeIds = append(misplacedVolumeIds, vid)
|
||||
@ -377,6 +377,27 @@ func keepDataNodesSorted(dataNodes []location, diskType types.DiskType) {
|
||||
})
|
||||
}
|
||||
|
||||
func satisfyReplicaCurrentLocation(replicaPlacement *super_block.ReplicaPlacement, replicas []*VolumeReplica) bool {
|
||||
existingDataCenters, existingRacks, _ := countReplicas(replicas)
|
||||
|
||||
if replicaPlacement.DiffDataCenterCount+1 > len(existingDataCenters) {
|
||||
return false
|
||||
}
|
||||
if replicaPlacement.DiffRackCount+1 > len(existingRacks) {
|
||||
return false
|
||||
}
|
||||
if replicaPlacement.SameRackCount > 0 {
|
||||
foundSatisfyRack := false
|
||||
for _, rackCount := range existingRacks {
|
||||
if rackCount >= replicaPlacement.SameRackCount+1 {
|
||||
foundSatisfyRack = true
|
||||
}
|
||||
}
|
||||
return foundSatisfyRack
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
if on an existing data node {
|
||||
return false
|
||||
|
@ -438,3 +438,90 @@ func TestPickingMisplacedVolumeToDelete(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestSatisfyReplicaCurrentLocation(t *testing.T) {
|
||||
|
||||
var tests = []testcase{
|
||||
{
|
||||
name: "test 001",
|
||||
replication: "001",
|
||||
replicas: []*VolumeReplica{
|
||||
{
|
||||
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn1"}},
|
||||
},
|
||||
{
|
||||
location: &location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn2"}},
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "test 010",
|
||||
replication: "010",
|
||||
replicas: []*VolumeReplica{
|
||||
{
|
||||
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn1"}},
|
||||
},
|
||||
{
|
||||
location: &location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn2"}},
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "test 011",
|
||||
replication: "011",
|
||||
replicas: []*VolumeReplica{
|
||||
{
|
||||
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn1"}},
|
||||
},
|
||||
{
|
||||
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn2"}},
|
||||
},
|
||||
{
|
||||
location: &location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn3"}},
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "test 110",
|
||||
replication: "110",
|
||||
replicas: []*VolumeReplica{
|
||||
{
|
||||
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn1"}},
|
||||
},
|
||||
{
|
||||
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn2"}},
|
||||
},
|
||||
{
|
||||
location: &location{"dc2", "r2", &master_pb.DataNodeInfo{Id: "dn3"}},
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "test 100",
|
||||
replication: "100",
|
||||
replicas: []*VolumeReplica{
|
||||
{
|
||||
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn1"}},
|
||||
},
|
||||
{
|
||||
location: &location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn2"}},
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
replicaPlacement, _ := super_block.NewReplicaPlacementFromString(tt.replication)
|
||||
if satisfyReplicaCurrentLocation(replicaPlacement, tt.replicas) != tt.expected {
|
||||
t.Errorf("%s: expect %v %v %+v",
|
||||
tt.name, tt.expected, tt.replication, tt.replicas)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user