Skip to content

Commit

Permalink
operator: allows to skip placement rules checks (#5458)
Browse files Browse the repository at this point in the history
close #5401

Signed-off-by: HunDunDM <hundundm@gmail.com>
  • Loading branch information
HunDunDM authored Aug 31, 2022
1 parent 1efd822 commit d8620c9
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 5 deletions.
12 changes: 9 additions & 3 deletions server/schedule/operator/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ type Builder struct {
targetLeaderStoreIDs []uint64 // This field is only used during multi-target evict leader, and will not be filtered during `Build`.
err error

// skip origin check flags
// skip check flags
skipOriginJointStateCheck bool
skipPlacementRulesCheck bool

// build flags
useJointConsensus bool
Expand All @@ -94,6 +95,11 @@ func SkipOriginJointStateCheck(b *Builder) {
b.skipOriginJointStateCheck = true
}

// SkipPlacementRulesCheck lets the builder skip the placement rules check for origin and target peers.
func SkipPlacementRulesCheck(b *Builder) {
b.skipPlacementRulesCheck = true
}

// NewBuilder creates a Builder.
func NewBuilder(desc string, ci ClusterInformer, region *core.RegionInfo, opts ...BuilderOption) *Builder {
b := &Builder{
Expand Down Expand Up @@ -138,7 +144,7 @@ func NewBuilder(desc string, ci ClusterInformer, region *core.RegionInfo, opts .

// placement rules
var rules []*placement.Rule
if err == nil && b.GetOpts().IsPlacementRulesEnabled() {
if err == nil && !b.skipPlacementRulesCheck && b.GetOpts().IsPlacementRulesEnabled() {
fit := b.GetRuleManager().FitRegion(b.GetBasicCluster(), region)
for _, rf := range fit.RuleFits {
rules = append(rules, rf.Rule)
Expand Down Expand Up @@ -775,7 +781,7 @@ func (b *Builder) allowLeader(peer *metapb.Peer, ignoreClusterLimit bool) bool {
}

// placement rules
if len(b.rules) == 0 {
if b.skipPlacementRulesCheck || len(b.rules) == 0 {
return true
}
for _, r := range b.rules {
Expand Down
4 changes: 2 additions & 2 deletions server/schedule/operator/create_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func CreateTransferLeaderOperator(desc string, ci ClusterInformer, region *core.

// CreateForceTransferLeaderOperator creates an operator that transfers the leader from a source store to a target store forcible.
func CreateForceTransferLeaderOperator(desc string, ci ClusterInformer, region *core.RegionInfo, sourceStoreID uint64, targetStoreID uint64, kind OpKind) (*Operator, error) {
return NewBuilder(desc, ci, region, SkipOriginJointStateCheck).
return NewBuilder(desc, ci, region, SkipOriginJointStateCheck, SkipPlacementRulesCheck).
SetLeader(targetStoreID).
EnableForceTargetLeader().
Build(kind)
Expand Down Expand Up @@ -225,7 +225,7 @@ const OpDescLeaveJointState = "leave-joint-state"

// CreateLeaveJointStateOperator creates an operator that let region leave joint state.
func CreateLeaveJointStateOperator(desc string, ci ClusterInformer, origin *core.RegionInfo) (*Operator, error) {
b := NewBuilder(desc, ci, origin, SkipOriginJointStateCheck)
b := NewBuilder(desc, ci, origin, SkipOriginJointStateCheck, SkipPlacementRulesCheck)

if b.err == nil && !core.IsInJointState(origin.GetPeers()...) {
b.err = errors.Errorf("cannot build leave joint state operator for region which is not in joint state")
Expand Down
60 changes: 60 additions & 0 deletions server/schedule/operator/create_operator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ package operator

import (
"context"
"encoding/hex"
"testing"

"github.com/pingcap/errors"
"github.com/pingcap/kvproto/pkg/metapb"
"github.com/pingcap/kvproto/pkg/pdpb"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/tikv/pd/pkg/mock/mockcluster"
"github.com/tikv/pd/server/config"
Expand Down Expand Up @@ -1078,3 +1080,61 @@ func (suite *createOperatorTestSuite) TestMoveRegionWithoutJointConsensus() {
}
}
}

// Ref https://github.com/tikv/pd/issues/5401
func TestCreateLeaveJointStateOperatorWithoutFitRules(t *testing.T) {
re := require.New(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

opts := config.NewTestOptions()
cluster := mockcluster.NewCluster(ctx, opts)
re.NoError(cluster.SetRules([]*placement.Rule{
{
GroupID: "pd",
ID: "default",
StartKeyHex: hex.EncodeToString([]byte("")),
EndKeyHex: hex.EncodeToString([]byte("")),
Role: placement.Voter,
Count: 1,
},
{
GroupID: "t1",
ID: "t1",
StartKeyHex: hex.EncodeToString([]byte("a")),
EndKeyHex: hex.EncodeToString([]byte("b")),
Role: placement.Voter,
Count: 1,
},
{
GroupID: "t2",
ID: "t2",
StartKeyHex: hex.EncodeToString([]byte("b")),
EndKeyHex: hex.EncodeToString([]byte("c")),
Role: placement.Voter,
Count: 1,
},
}))
cluster.AddRegionStore(1, 1)
cluster.AddRegionStore(2, 1)
cluster.AddRegionStore(3, 1)
cluster.AddRegionStore(4, 1)
originPeers := []*metapb.Peer{
{Id: 3, StoreId: 3, Role: metapb.PeerRole_DemotingVoter},
{Id: 4, StoreId: 4, Role: metapb.PeerRole_IncomingVoter},
}

region := core.NewRegionInfo(&metapb.Region{Id: 1, Peers: originPeers, StartKey: []byte("a"), EndKey: []byte("c")}, originPeers[0])
op, err := CreateLeaveJointStateOperator("test", cluster, region)
re.NoError(err)
re.Equal(OpLeader, op.Kind())
re.Len(op.steps, 2)
step0 := op.steps[0].(TransferLeader)
re.Equal(uint64(3), step0.FromStore)
re.Equal(uint64(4), step0.ToStore)
step1 := op.steps[1].(ChangePeerV2Leave)
re.Len(step1.PromoteLearners, 1)
re.Len(step1.DemoteVoters, 1)
re.Equal(uint64(4), step1.PromoteLearners[0].ToStore)
re.Equal(uint64(3), step1.DemoteVoters[0].ToStore)
}

0 comments on commit d8620c9

Please sign in to comment.