mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-12-12 00:19:14 +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]
|
replica := replicas[0]
|
||||||
replicaPlacement, _ := super_block.NewReplicaPlacementFromByte(byte(replica.info.ReplicaPlacement))
|
replicaPlacement, _ := super_block.NewReplicaPlacementFromByte(byte(replica.info.ReplicaPlacement))
|
||||||
switch {
|
switch {
|
||||||
case replicaPlacement.GetCopyCount() > len(replicas):
|
case replicaPlacement.GetCopyCount() > len(replicas) || !satisfyReplicaCurrentLocation(replicaPlacement, replicas):
|
||||||
underReplicatedVolumeIds = append(underReplicatedVolumeIds, vid)
|
underReplicatedVolumeIds = append(underReplicatedVolumeIds, vid)
|
||||||
case isMisplaced(replicas, replicaPlacement):
|
case isMisplaced(replicas, replicaPlacement):
|
||||||
misplacedVolumeIds = append(misplacedVolumeIds, vid)
|
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 {
|
if on an existing data node {
|
||||||
return false
|
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