diff --git a/pkg/mock/mockcluster/mockcluster.go b/pkg/mock/mockcluster/mockcluster.go index 7fe5b3a6a7f3..784a382f97b7 100644 --- a/pkg/mock/mockcluster/mockcluster.go +++ b/pkg/mock/mockcluster/mockcluster.go @@ -15,6 +15,7 @@ package mockcluster import ( "fmt" + "strconv" "time" "github.com/gogo/protobuf/proto" @@ -583,7 +584,11 @@ func (mc *Cluster) CheckLabelProperty(typ string, labels []*metapb.StoreLabel) b // PutRegionStores mocks method. func (mc *Cluster) PutRegionStores(id uint64, stores ...uint64) { - meta := &metapb.Region{Id: id} + meta := &metapb.Region{ + Id: id, + StartKey: []byte(strconv.FormatUint(id, 10)), + EndKey: []byte(strconv.FormatUint(id+1, 10)), + } for _, s := range stores { meta.Peers = append(meta.Peers, &metapb.Peer{StoreId: s}) } diff --git a/server/schedulers/balance_region.go b/server/schedulers/balance_region.go index 08b05b155ca4..ba3cf31b43ae 100644 --- a/server/schedulers/balance_region.go +++ b/server/schedulers/balance_region.go @@ -57,6 +57,8 @@ func init() { const ( // balanceRegionRetryLimit is the limit to retry schedule for selected store. balanceRegionRetryLimit = 10 + // BalanceEmptyRegionThreshold is a threshold which allow balance the empty region if the region number is less than this threshold. + balanceEmptyRegionThreshold = 50 // BalanceRegionName is balance region scheduler name. BalanceRegionName = "balance-region-scheduler" // BalanceRegionType is balance region scheduler type. @@ -142,6 +144,7 @@ func (s *balanceRegionScheduler) Schedule(cluster opt.Cluster) []*operator.Opera return stores[i].RegionScore(opts.GetRegionScoreFormulaVersion(), opts.GetHighSpaceRatio(), opts.GetLowSpaceRatio(), iOp, -1) > stores[j].RegionScore(opts.GetRegionScoreFormulaVersion(), opts.GetHighSpaceRatio(), opts.GetLowSpaceRatio(), jOp, -1) }) + regionCount := cluster.GetRegionCount() for _, source := range stores { sourceID := source.GetID() @@ -168,7 +171,7 @@ func (s *balanceRegionScheduler) Schedule(cluster opt.Cluster) []*operator.Opera log.Debug("select region", zap.String("scheduler", s.GetName()), zap.Uint64("region-id", region.GetID())) // Skip the empty region - if region.GetApproximateSize() <= core.EmptyRegionApproximateSize { + if region.GetApproximateSize() <= core.EmptyRegionApproximateSize && regionCount > balanceEmptyRegionThreshold { log.Debug("region is empty", zap.String("scheduler", s.GetName()), zap.Uint64("region-id", region.GetID())) schedulerCounter.WithLabelValues(s.GetName(), "empty-region").Inc() continue diff --git a/server/schedulers/balance_test.go b/server/schedulers/balance_test.go index 49eebc0e2822..509599807608 100644 --- a/server/schedulers/balance_test.go +++ b/server/schedulers/balance_test.go @@ -960,6 +960,12 @@ func (s *testBalanceRegionSchedulerSuite) TestEmptyRegion(c *C) { ) tc.PutRegion(region) operators := sb.Schedule(tc) + c.Assert(operators, NotNil) + + for i := uint64(10); i < 60; i++ { + tc.PutRegionStores(i, 1, 3, 4) + } + operators = sb.Schedule(tc) c.Assert(operators, IsNil) }