From b4a9e50cff0dbb398ff80663e47e91b89f5bf148 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Fri, 18 Sep 2020 17:07:08 +0800 Subject: [PATCH 1/3] cherry pick #2966 to release-4.0 Signed-off-by: ti-srebot --- pkg/mock/mockcluster/mockcluster.go | 8 ++++++-- server/schedule/filter/filters.go | 5 +++++ server/schedulers/balance_region.go | 6 ++++++ server/schedulers/balance_test.go | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/pkg/mock/mockcluster/mockcluster.go b/pkg/mock/mockcluster/mockcluster.go index ea91168ea8e..4f073ef9df1 100644 --- a/pkg/mock/mockcluster/mockcluster.go +++ b/pkg/mock/mockcluster/mockcluster.go @@ -595,6 +595,7 @@ func (mc *Cluster) RemoveScheduler(name string) error { } // MockRegionInfo returns a mock region +// If leaderStoreID is zero, the regions would have no leader func (mc *Cluster) MockRegionInfo(regionID uint64, leaderStoreID uint64, followerStoreIDs, learnerStoreIDs []uint64, epoch *metapb.RegionEpoch) *core.RegionInfo { @@ -604,8 +605,11 @@ func (mc *Cluster) MockRegionInfo(regionID uint64, leaderStoreID uint64, EndKey: []byte(fmt.Sprintf("%20d", regionID+1)), RegionEpoch: epoch, } - leader, _ := mc.AllocPeer(leaderStoreID) - region.Peers = []*metapb.Peer{leader} + var leader *metapb.Peer + if leaderStoreID != 0 { + leader, _ = mc.AllocPeer(leaderStoreID) + region.Peers = append(region.Peers, leader) + } for _, storeID := range followerStoreIDs { peer, _ := mc.AllocPeer(storeID) region.Peers = append(region.Peers, peer) diff --git a/server/schedule/filter/filters.go b/server/schedule/filter/filters.go index 962b698ca9f..28ba8c9b179 100644 --- a/server/schedule/filter/filters.go +++ b/server/schedule/filter/filters.go @@ -16,6 +16,7 @@ package filter import ( "fmt" + "github.com/golang/protobuf/proto" "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/log" "github.com/tikv/pd/pkg/slice" @@ -722,11 +723,15 @@ var allSpeicalEngines = []string{EngineTiFlash} // FitRegion in filter func createRegionForRuleFit(startKey, endKey []byte, peers []*metapb.Peer, leader *metapb.Peer, opts ...core.RegionCreateOption) *core.RegionInfo { +<<<<<<< HEAD copyLeader := &metapb.Peer{ Id: leader.Id, StoreId: leader.StoreId, IsLearner: leader.IsLearner, } +======= + copyLeader := proto.Clone(leader).(*metapb.Peer) +>>>>>>> 4a95bca... scheduler: add leader verify in balance-region scheduler (#2966) copyPeers := make([]*metapb.Peer, 0, len(peers)) for _, p := range peers { peer := &metapb.Peer{ diff --git a/server/schedulers/balance_region.go b/server/schedulers/balance_region.go index 77b21af247c..0a773c7b0f4 100644 --- a/server/schedulers/balance_region.go +++ b/server/schedulers/balance_region.go @@ -173,6 +173,12 @@ func (s *balanceRegionScheduler) Schedule(cluster opt.Cluster) []*operator.Opera schedulerCounter.WithLabelValues(s.GetName(), "region-hot").Inc() continue } + // Check region whether have leader + if region.GetLeader() == nil { + log.Warn("region have no leader", zap.String("scheduler", s.GetName()), zap.Uint64("region-id", region.GetID())) + schedulerCounter.WithLabelValues(s.GetName(), "no-leader").Inc() + continue + } oldPeer := region.GetStorePeer(sourceID) if op := s.transferPeer(cluster, region, oldPeer); op != nil { diff --git a/server/schedulers/balance_test.go b/server/schedulers/balance_test.go index 19be8e2625c..1ebac02b7ae 100644 --- a/server/schedulers/balance_test.go +++ b/server/schedulers/balance_test.go @@ -1125,6 +1125,23 @@ func (s *testReplicaCheckerSuite) TestOpts(c *C) { c.Assert(rc.Check(region), IsNil) } +func (s *testBalanceRegionSchedulerSuite) TestShouldNotBalance(c *C) { + opt := config.NewTestOptions() + tc := mockcluster.NewCluster(opt) + tc.DisableFeature(versioninfo.JointConsensus) + oc := schedule.NewOperatorController(s.ctx, nil, nil) + sb, err := schedule.CreateScheduler(BalanceRegionType, oc, core.NewStorage(kv.NewMemoryKV()), schedule.ConfigSliceDecoder(BalanceRegionType, []string{"", ""})) + c.Assert(err, IsNil) + region := tc.MockRegionInfo(1, 0, []uint64{2, 3, 4}, nil, nil) + tc.PutRegion(region) + operators := sb.Schedule(tc) + if operators != nil { + c.Assert(len(operators), Equals, 0) + } else { + c.Assert(operators, IsNil) + } +} + var _ = Suite(&testRandomMergeSchedulerSuite{}) type testRandomMergeSchedulerSuite struct{} From bd763730a86308376d56b80d6a5951b89d83fa64 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Mon, 21 Sep 2020 14:04:04 +0800 Subject: [PATCH 2/3] fix conflict Signed-off-by: Song Gao --- server/schedule/filter/filters.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/server/schedule/filter/filters.go b/server/schedule/filter/filters.go index 28ba8c9b179..0cea7c925fc 100644 --- a/server/schedule/filter/filters.go +++ b/server/schedule/filter/filters.go @@ -723,15 +723,7 @@ var allSpeicalEngines = []string{EngineTiFlash} // FitRegion in filter func createRegionForRuleFit(startKey, endKey []byte, peers []*metapb.Peer, leader *metapb.Peer, opts ...core.RegionCreateOption) *core.RegionInfo { -<<<<<<< HEAD - copyLeader := &metapb.Peer{ - Id: leader.Id, - StoreId: leader.StoreId, - IsLearner: leader.IsLearner, - } -======= copyLeader := proto.Clone(leader).(*metapb.Peer) ->>>>>>> 4a95bca... scheduler: add leader verify in balance-region scheduler (#2966) copyPeers := make([]*metapb.Peer, 0, len(peers)) for _, p := range peers { peer := &metapb.Peer{ From e23b7bc0c3b6cc40941296d5d11e99719d08fa53 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Mon, 21 Sep 2020 14:30:26 +0800 Subject: [PATCH 3/3] fix test Signed-off-by: Song Gao --- server/schedulers/balance_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/schedulers/balance_test.go b/server/schedulers/balance_test.go index 1ebac02b7ae..0aac3b10087 100644 --- a/server/schedulers/balance_test.go +++ b/server/schedulers/balance_test.go @@ -1126,9 +1126,8 @@ func (s *testReplicaCheckerSuite) TestOpts(c *C) { } func (s *testBalanceRegionSchedulerSuite) TestShouldNotBalance(c *C) { - opt := config.NewTestOptions() + opt := mockoption.NewScheduleOptions() tc := mockcluster.NewCluster(opt) - tc.DisableFeature(versioninfo.JointConsensus) oc := schedule.NewOperatorController(s.ctx, nil, nil) sb, err := schedule.CreateScheduler(BalanceRegionType, oc, core.NewStorage(kv.NewMemoryKV()), schedule.ConfigSliceDecoder(BalanceRegionType, []string{"", ""})) c.Assert(err, IsNil)