aboutsummaryrefslogtreecommitdiff
path: root/weed/shell/command_volume_balance.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/shell/command_volume_balance.go')
-rw-r--r--weed/shell/command_volume_balance.go41
1 files changed, 33 insertions, 8 deletions
diff --git a/weed/shell/command_volume_balance.go b/weed/shell/command_volume_balance.go
index 6ba376d2c..bc0adfc5f 100644
--- a/weed/shell/command_volume_balance.go
+++ b/weed/shell/command_volume_balance.go
@@ -64,7 +64,7 @@ func (c *commandVolumeBalance) Help() string {
func (c *commandVolumeBalance) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) {
balanceCommand := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
- collection := balanceCommand.String("collection", "EACH_COLLECTION", "collection name, or use \"ALL_COLLECTIONS\" across collections, \"EACH_COLLECTION\" for each collection")
+ collection := balanceCommand.String("collection", "ALL_COLLECTIONS", "collection name, or use \"ALL_COLLECTIONS\" across collections, \"EACH_COLLECTION\" for each collection")
dc := balanceCommand.String("dataCenter", "", "only apply the balancing for this dataCenter")
applyBalancing := balanceCommand.Bool("force", false, "apply the balancing plan.")
if err = balanceCommand.Parse(args); err != nil {
@@ -213,6 +213,18 @@ func (n *Node) localVolumeNextRatio(capacityFunc CapacityFunc) float64 {
return divide(len(n.selectedVolumes)+1, capacityFunc(n.info))
}
+func (n *Node) isOneVolumeOnly() bool {
+ if len(n.selectedVolumes) != 1 {
+ return false
+ }
+ for _, disk := range n.info.DiskInfos {
+ if disk.VolumeCount == 1 && disk.MaxVolumeCount == 1 {
+ return true
+ }
+ }
+ return false
+}
+
func (n *Node) selectVolumes(fn func(v *master_pb.VolumeInformationMessage) bool) {
n.selectedVolumes = make(map[uint32]*master_pb.VolumeInformationMessage)
for _, diskInfo := range n.info.DiskInfos {
@@ -230,12 +242,6 @@ func sortWritableVolumes(volumes []*master_pb.VolumeInformationMessage) {
})
}
-func sortReadOnlyVolumes(volumes []*master_pb.VolumeInformationMessage) {
- slices.SortFunc(volumes, func(a, b *master_pb.VolumeInformationMessage) bool {
- return a.Id < b.Id
- })
-}
-
func balanceSelectedVolume(commandEnv *CommandEnv, diskType types.DiskType, volumeReplicas map[uint32][]*VolumeReplica, nodes []*Node, capacityFunc CapacityFunc, sortCandidatesFn func(volumes []*master_pb.VolumeInformationMessage), applyBalancing bool) (err error) {
selectedVolumeCount, volumeMaxCount := 0, 0
var nodesWithCapacity []*Node
@@ -263,7 +269,14 @@ func balanceSelectedVolume(commandEnv *CommandEnv, diskType types.DiskType, volu
fmt.Printf("no volume server found with capacity for %s", diskType.ReadableString())
return nil
}
- fullNode := nodesWithCapacity[len(nodesWithCapacity)-1]
+
+ var fullNode *Node
+ for fullNodeIndex := len(nodesWithCapacity) - 1; fullNodeIndex >= 0; fullNodeIndex-- {
+ fullNode = nodesWithCapacity[fullNodeIndex]
+ if !fullNode.isOneVolumeOnly() {
+ break
+ }
+ }
var candidateVolumes []*master_pb.VolumeInformationMessage
for _, v := range fullNode.selectedVolumes {
candidateVolumes = append(candidateVolumes, v)
@@ -389,6 +402,18 @@ func adjustAfterMove(v *master_pb.VolumeInformationMessage, volumeReplicas map[u
replica.location.dc == fullNode.dc {
loc := newLocation(emptyNode.dc, emptyNode.rack, emptyNode.info)
replica.location = &loc
+ for diskType, diskInfo := range fullNode.info.DiskInfos {
+ if diskType == v.DiskType {
+ diskInfo.VolumeCount--
+ diskInfo.FreeVolumeCount++
+ }
+ }
+ for diskType, diskInfo := range emptyNode.info.DiskInfos {
+ if diskType == v.DiskType {
+ diskInfo.VolumeCount++
+ diskInfo.FreeVolumeCount--
+ }
+ }
return
}
}