From dfda82666b3ebbe509371121b0883ccb008f0c57 Mon Sep 17 00:00:00 2001 From: Ryan Leung Date: Fri, 19 Jul 2024 18:19:30 +0800 Subject: [PATCH] This is an automated cherry-pick of #8415 close tikv/pd#8419 Signed-off-by: ti-chi-bot --- pkg/keyspace/keyspace.go | 74 ++++++++++++++++++++++++++++++++ pkg/schedule/labeler/rules.go | 49 +++++++++++++++++++++ server/cluster/cluster_worker.go | 4 +- 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/pkg/keyspace/keyspace.go b/pkg/keyspace/keyspace.go index 7bd8de7bc28..4f09b192d29 100644 --- a/pkg/keyspace/keyspace.go +++ b/pkg/keyspace/keyspace.go @@ -28,6 +28,11 @@ import ( "github.com/tikv/pd/pkg/slice" "github.com/tikv/pd/pkg/storage/endpoint" "github.com/tikv/pd/pkg/storage/kv" +<<<<<<< HEAD +======= + "github.com/tikv/pd/pkg/utils/etcdutil" + "github.com/tikv/pd/pkg/utils/logutil" +>>>>>>> 2d8e03f33 (*: fix redact log (#8415)) "github.com/tikv/pd/pkg/utils/syncutil" "go.uber.org/zap" ) @@ -255,10 +260,69 @@ func (manager *Manager) splitKeyspaceRegion(id uint32) error { if cl, ok := manager.cluster.(interface{ GetRegionLabeler() *labeler.RegionLabeler }); ok { err := cl.GetRegionLabeler().SetLabelRule(keyspaceRule) if err != nil { +<<<<<<< HEAD log.Warn("[keyspace] failed to add region label for keyspace", zap.Uint32("keyspaceID", id), zap.Error(err), ) +======= + if err := cl.GetRegionLabeler().DeleteLabelRule(keyspaceRule.ID); err != nil { + log.Warn("[keyspace] failed to delete region label for keyspace", + zap.Uint32("keyspace-id", id), + zap.Error(err), + ) + } + } + }() + + if waitRegionSplit { + ranges := keyspaceRule.Data.([]*labeler.KeyRangeRule) + if len(ranges) < 2 { + log.Warn("[keyspace] failed to split keyspace region with insufficient range", logutil.ZapRedactString("label-rule", keyspaceRule.String())) + return ErrRegionSplitFailed + } + rawLeftBound, rawRightBound := ranges[0].StartKey, ranges[0].EndKey + txnLeftBound, txnRightBound := ranges[1].StartKey, ranges[1].EndKey + + ticker := time.NewTicker(manager.config.GetCheckRegionSplitInterval()) + timer := time.NewTimer(manager.config.GetWaitRegionSplitTimeout()) + defer func() { + ticker.Stop() + timer.Stop() + }() + for { + select { + case <-ticker.C: + c := manager.cluster.GetBasicCluster() + region := c.GetRegionByKey(rawLeftBound) + if region == nil || !bytes.Equal(region.GetStartKey(), rawLeftBound) { + continue + } + region = c.GetRegionByKey(rawRightBound) + if region == nil || !bytes.Equal(region.GetStartKey(), rawRightBound) { + continue + } + region = c.GetRegionByKey(txnLeftBound) + if region == nil || !bytes.Equal(region.GetStartKey(), txnLeftBound) { + continue + } + region = c.GetRegionByKey(txnRightBound) + if region == nil || !bytes.Equal(region.GetStartKey(), txnRightBound) { + continue + } + // Note: we reset the ticker here to support updating configuration dynamically. + ticker.Reset(manager.config.GetCheckRegionSplitInterval()) + case <-timer.C: + log.Warn("[keyspace] wait region split timeout", + zap.Uint32("keyspace-id", id), + zap.Error(err), + ) + err = ErrRegionSplitTimeout + return + } + log.Info("[keyspace] wait region split successfully", zap.Uint32("keyspace-id", id)) + break +>>>>>>> 2d8e03f33 (*: fix redact log (#8415)) } log.Info("[keyspace] added region label for keyspace", zap.Uint32("keyspaceID", id), @@ -266,7 +330,17 @@ func (manager *Manager) splitKeyspaceRegion(id uint32) error { ) return nil } +<<<<<<< HEAD return errors.New("cluster does not support region label") +======= + + log.Info("[keyspace] added region label for keyspace", + zap.Uint32("keyspace-id", id), + logutil.ZapRedactString("label-rule", keyspaceRule.String()), + zap.Duration("takes", time.Since(start)), + ) + return +>>>>>>> 2d8e03f33 (*: fix redact log (#8415)) } // LoadKeyspace returns the keyspace specified by name. diff --git a/pkg/schedule/labeler/rules.go b/pkg/schedule/labeler/rules.go index c902fff8f66..c88609a10f6 100644 --- a/pkg/schedule/labeler/rules.go +++ b/pkg/schedule/labeler/rules.go @@ -19,6 +19,7 @@ import ( "encoding/hex" "fmt" "reflect" + "strings" "time" "github.com/pingcap/failpoint" @@ -37,6 +38,10 @@ type RegionLabel struct { expire *time.Time } +func (l *RegionLabel) String() string { + return fmt.Sprintf("key: %s, value: %s", l.Key, l.Value) +} + // LabelRule is the rule to assign labels to a region. // NOTE: This type is exported by HTTP API. Please pay more attention when modifying it. type LabelRule struct { @@ -48,6 +53,50 @@ type LabelRule struct { minExpire *time.Time } +<<<<<<< HEAD +======= +func (rule *LabelRule) String() string { + var b strings.Builder + b.WriteString(fmt.Sprintf("id: %s, index: %d, type: %s", rule.ID, rule.Index, rule.RuleType)) + b.WriteString(", labels: ") + for i, l := range rule.Labels { + if i == 0 { + b.WriteString("[") + } + b.WriteString(l.String()) + if i == len(rule.Labels)-1 { + b.WriteString("]") + } else { + b.WriteString(", ") + } + } + b.WriteString(", data: ") + ranges := rule.Data.([]*KeyRangeRule) + for i, r := range ranges { + if i == 0 { + b.WriteString("[") + } + b.WriteString(fmt.Sprintf("startKey: {%s}, endKey: {%s}", r.StartKeyHex, r.EndKeyHex)) + if i == len(ranges)-1 { + b.WriteString("]") + } else { + b.WriteString(", ") + } + } + return b.String() +} + +// NewLabelRuleFromJSON creates a label rule from the JSON data. +func NewLabelRuleFromJSON(data []byte) (*LabelRule, error) { + lr := &LabelRule{} + err := json.Unmarshal(data, lr) + if err != nil { + return nil, err + } + return lr, nil +} + +>>>>>>> 2d8e03f33 (*: fix redact log (#8415)) const ( // KeyRange is the rule type that specifies a list of key ranges. KeyRange = "key-range" diff --git a/server/cluster/cluster_worker.go b/server/cluster/cluster_worker.go index fd0acfe7466..aa2dffda1b0 100644 --- a/server/cluster/cluster_worker.go +++ b/server/cluster/cluster_worker.go @@ -227,7 +227,7 @@ func (c *RaftCluster) HandleBatchReportSplit(request *pdpb.ReportBatchSplitReque err := c.checkSplitRegions(regions) if err != nil { log.Warn("report batch split region is invalid", - zap.Stringer("region-meta", hrm), + logutil.ZapRedactStringer("region-meta", hrm), errs.ZapError(err)) return nil, err } @@ -236,7 +236,7 @@ func (c *RaftCluster) HandleBatchReportSplit(request *pdpb.ReportBatchSplitReque hrm = core.RegionsToHexMeta(regions[:last]) log.Info("region batch split, generate new regions", zap.Uint64("region-id", originRegion.GetId()), - zap.Stringer("origin", hrm), + logutil.ZapRedactStringer("origin", hrm), zap.Int("total", last)) return &pdpb.ReportBatchSplitResponse{}, nil }