diff --git a/server/schedulers/label.go b/server/schedulers/label.go index 5222b59c4de..e8199595782 100644 --- a/server/schedulers/label.go +++ b/server/schedulers/label.go @@ -71,9 +71,17 @@ func (s *labelScheduler) Schedule(cluster schedule.Cluster, opInfluence schedule } log.Debugf("label scheduler reject leader store list: %v", rejectLeaderStores) for id := range rejectLeaderStores { - if region := cluster.RandLeaderRegion(id, core.HealthRegion()); region != nil { + if region := cluster.RandLeaderRegion(id); region != nil { log.Debugf("label scheduler selects region %d to transfer leader", region.GetId()) - target := s.selector.SelectTarget(cluster, cluster.GetFollowerStores(region)) + excludeStores := make(map[uint64]struct{}) + for _, p := range region.DownPeers { + excludeStores[p.GetPeer().GetStoreId()] = struct{}{} + } + for _, p := range region.PendingPeers { + excludeStores[p.GetStoreId()] = struct{}{} + } + filter := schedule.NewExcludedFilter(nil, excludeStores) + target := s.selector.SelectTarget(cluster, cluster.GetFollowerStores(region), filter) if target == nil { log.Debugf("label scheduler no target found for region %d", region.GetId()) schedulerCounter.WithLabelValues(s.GetName(), "no_target").Inc() diff --git a/server/schedulers/scheduler_test.go b/server/schedulers/scheduler_test.go index 2d3182b775f..d3783e7c84f 100644 --- a/server/schedulers/scheduler_test.go +++ b/server/schedulers/scheduler_test.go @@ -205,15 +205,28 @@ func (s *testRejectLeaderSuite) TestRejectLeader(c *C) { op := sl.Schedule(tc, schedule.NewOpInfluence(nil, tc)) CheckTransferLeader(c, op[0], schedule.OpLeader, 1, 3) + // If store3 is disconnected, transfer leader to store 2 instead. tc.SetStoreDisconnect(3) - // Transfer leader to store 2 instead. op = sl.Schedule(tc, schedule.NewOpInfluence(nil, tc)) CheckTransferLeader(c, op[0], schedule.OpLeader, 1, 2) // As store3 is disconnected, store1 rejects leader. Balancer will not create // any operators. - sl, err = schedule.CreateScheduler("balance-leader", schedule.NewLimiter()) + bs, err := schedule.CreateScheduler("balance-leader", schedule.NewLimiter()) c.Assert(err, IsNil) - op = sl.Schedule(tc, schedule.NewOpInfluence(nil, tc)) + op = bs.Schedule(tc, schedule.NewOpInfluence(nil, tc)) c.Assert(op, IsNil) + + // If the peer on store3 is pending, not trasnfer to store3 neither. + tc.SetStoreUp(3) + region := tc.Regions.GetRegion(1) + for _, p := range region.Peers { + if p.GetStoreId() == 3 { + region.PendingPeers = append(region.PendingPeers, p) + break + } + } + tc.Regions.AddRegion(region) + op = sl.Schedule(tc, schedule.NewOpInfluence(nil, tc)) + CheckTransferLeader(c, op[0], schedule.OpLeader, 1, 2) }