Skip to content

Commit 38cb4f3

Browse files
authored
Revert "placement: merge the rules if the constraints are the same (#… (#47527)
ref tikv/pd#7185
1 parent 04ac200 commit 38cb4f3

File tree

4 files changed

+50
-639
lines changed

4 files changed

+50
-639
lines changed

ddl/placement/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ go_test(
3535
embed = [":placement"],
3636
flaky = True,
3737
race = "on",
38-
shard_count = 25,
38+
shard_count = 24,
3939
deps = [
4040
"//kv",
4141
"//meta",

ddl/placement/bundle.go

Lines changed: 40 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,27 @@ func (b *Bundle) String() string {
288288

289289
// Tidy will post optimize Rules, trying to generate rules that suits PD.
290290
func (b *Bundle) Tidy() error {
291-
tempRules := b.Rules[:0]
292-
id := 0
291+
extraCnt := map[PeerRoleType]int{}
292+
newRules := b.Rules[:0]
293+
294+
// One Bundle is from one PlacementSettings, rule share same location labels, so we can use the first rule's location labels.
295+
var locationLabels []string
293296
for _, rule := range b.Rules {
297+
if len(rule.LocationLabels) > 0 {
298+
locationLabels = rule.LocationLabels
299+
break
300+
}
301+
}
302+
for i, rule := range b.Rules {
294303
// useless Rule
295304
if rule.Count <= 0 {
296305
continue
297306
}
307+
// merge all empty constraints
308+
if len(rule.Constraints) == 0 {
309+
extraCnt[rule.Role] += rule.Count
310+
continue
311+
}
298312
// refer to tidb#22065.
299313
// add -engine=tiflash to every rule to avoid schedules to tiflash instances.
300314
// placement rules in SQL is not compatible with `set tiflash replica` yet
@@ -306,139 +320,36 @@ func (b *Bundle) Tidy() error {
306320
if err != nil {
307321
return err
308322
}
309-
rule.ID = strconv.Itoa(id)
310-
tempRules = append(tempRules, rule)
311-
id++
312-
}
313-
314-
groups := make(map[string]*constraintsGroup)
315-
finalRules := tempRules[:0]
316-
for _, rule := range tempRules {
317-
key := rule.Constraints.FingerPrint()
318-
existing, ok := groups[key]
319-
if !ok {
320-
groups[key] = &constraintsGroup{rules: []*Rule{rule}}
323+
// Constraints.Add() will automatically avoid duplication
324+
// if -engine=tiflash is added and there is only one constraint
325+
// then it must be -engine=tiflash
326+
// it is seen as an empty constraint, so merge it
327+
if len(rule.Constraints) == 1 {
328+
extraCnt[rule.Role] += rule.Count
321329
continue
322330
}
323-
existing.rules = append(existing.rules, rule)
324-
}
325-
for _, group := range groups {
326-
group.MergeRulesByRole()
327-
}
328-
if err := transformableLeaderConstraint(groups); err != nil {
329-
return err
330-
}
331-
for _, group := range groups {
332-
finalRules = append(finalRules, group.rules...)
333-
}
334-
// sort by id
335-
sort.SliceStable(finalRules, func(i, j int) bool {
336-
return finalRules[i].ID < finalRules[j].ID
337-
})
338-
b.Rules = finalRules
339-
return nil
340-
}
341-
342-
// constraintsGroup is a group of rules with the same constraints.
343-
type constraintsGroup struct {
344-
rules []*Rule
345-
// canBecameLeader means the group has leader/voter role,
346-
// it's valid if it has leader.
347-
canBecameLeader bool
348-
// isLeaderGroup means it has specified leader role in this group.
349-
isLeaderGroup bool
350-
}
351-
352-
func transformableLeaderConstraint(groups map[string]*constraintsGroup) error {
353-
var leaderGroup *constraintsGroup
354-
canBecameLeaderNum := 0
355-
for _, group := range groups {
356-
if group.isLeaderGroup {
357-
if leaderGroup != nil {
358-
return ErrInvalidPlacementOptions
359-
}
360-
leaderGroup = group
361-
}
362-
if group.canBecameLeader {
363-
canBecameLeaderNum++
364-
}
365-
}
366-
// If there is a specified group should have leader, and only this group can be a leader, that means
367-
// the leader's priority is certain, so we can merge the transformable rules into one.
368-
// eg:
369-
// - [ group1 (L F), group2 (F) ], after merging is [group1 (2*V), group2 (F)], we still know the leader prefers group1.
370-
// - [ group1 (L F), group2 (V) ], after merging is [group1 (2*V), group2 (V)], we can't know leader priority after merge.
371-
if leaderGroup != nil && canBecameLeaderNum == 1 {
372-
leaderGroup.MergeTransformableRoles()
331+
rule.ID = strconv.Itoa(i)
332+
newRules = append(newRules, rule)
333+
}
334+
for role, cnt := range extraCnt {
335+
// add -engine=tiflash, refer to tidb#22065.
336+
newRules = append(newRules, &Rule{
337+
ID: string(role),
338+
Role: role,
339+
Count: cnt,
340+
Constraints: []Constraint{{
341+
Op: NotIn,
342+
Key: EngineLabelKey,
343+
Values: []string{EngineLabelTiFlash},
344+
}},
345+
// the merged rule should have the same location labels with the original rules.
346+
LocationLabels: locationLabels,
347+
})
373348
}
349+
b.Rules = newRules
374350
return nil
375351
}
376352

377-
// MergeRulesByRole merges the rules with the same role.
378-
func (c *constraintsGroup) MergeRulesByRole() {
379-
// Create a map to store rules by role
380-
rulesByRole := make(map[PeerRoleType][]*Rule)
381-
382-
// Iterate through each rule
383-
for _, rule := range c.rules {
384-
// Add the rule to the map based on its role
385-
rulesByRole[rule.Role] = append(rulesByRole[rule.Role], rule)
386-
if rule.Role == Leader || rule.Role == Voter {
387-
c.canBecameLeader = true
388-
}
389-
if rule.Role == Leader {
390-
c.isLeaderGroup = true
391-
}
392-
}
393-
394-
// Clear existing rules
395-
c.rules = nil
396-
397-
// Iterate through each role and merge the rules
398-
for _, rules := range rulesByRole {
399-
mergedRule := rules[0]
400-
for i, rule := range rules {
401-
if i == 0 {
402-
continue
403-
}
404-
mergedRule.Count += rule.Count
405-
if mergedRule.ID > rule.ID {
406-
mergedRule.ID = rule.ID
407-
}
408-
}
409-
c.rules = append(c.rules, mergedRule)
410-
}
411-
}
412-
413-
// MergeTransformableRoles merges all the rules to one that can be transformed to other roles.
414-
func (c *constraintsGroup) MergeTransformableRoles() {
415-
if len(c.rules) == 0 || len(c.rules) == 1 {
416-
return
417-
}
418-
var mergedRule *Rule
419-
newRules := make([]*Rule, 0, len(c.rules))
420-
for _, rule := range c.rules {
421-
// Learner is not transformable, it should be promote by PD.
422-
if rule.Role == Learner {
423-
newRules = append(newRules, rule)
424-
continue
425-
}
426-
if mergedRule == nil {
427-
mergedRule = rule
428-
continue
429-
}
430-
mergedRule.Count += rule.Count
431-
if mergedRule.ID > rule.ID {
432-
mergedRule.ID = rule.ID
433-
}
434-
}
435-
if mergedRule != nil {
436-
mergedRule.Role = Voter
437-
newRules = append(newRules, mergedRule)
438-
}
439-
c.rules = newRules
440-
}
441-
442353
// Reset resets the bundle ID and keyrange of all rules.
443354
func (b *Bundle) Reset(ruleIndex int, newIDs []int64) *Bundle {
444355
// eliminate the redundant rules.

0 commit comments

Comments
 (0)