@@ -19,18 +19,23 @@ import (
1919 "encoding/json"
2020 "fmt"
2121 "slices"
22+ "strconv"
2223
24+ "github.com/pingcap/tidb/pkg/config/kerneltype"
2325 "github.com/pingcap/tidb/pkg/parser/ast"
2426 "github.com/pingcap/tidb/pkg/tablecodec"
2527 "github.com/pingcap/tidb/pkg/util/codec"
28+ "github.com/tikv/client-go/v2/tikv"
2629 pd "github.com/tikv/pd/client/http"
2730 "gopkg.in/yaml.v2"
2831)
2932
3033const (
3134 // IDPrefix is the prefix for label rule ID.
3235 IDPrefix = "schema"
33- ruleType = "key-range"
36+ // KeyspacePrefix is the prefix for keyspace in label rule ID.
37+ KeyspacePrefix = "keyspace"
38+ ruleType = "key-range"
3439)
3540
3641const (
@@ -94,20 +99,43 @@ func (r *Rule) Clone() *Rule {
9499 return newRule
95100}
96101
97- // Reset will reset the label rule for a table/partition with a given ID and names.
98- func (r * Rule ) Reset (dbName , tableName , partName string , ids ... int64 ) * Rule {
102+ // UseKeyspaceAwareRules returns true when table attribute label rules should be
103+ // scoped by keyspace in NextGen deployments.
104+ func UseKeyspaceAwareRules (tikvCodec tikv.Codec ) bool {
105+ return kerneltype .IsNextGen () && tikvCodec != nil && tikvCodec .GetKeyspaceMeta () != nil
106+ }
107+
108+ // NewRuleID generates a new rule ID for a table or partition.
109+ func NewRuleID (tikvCodec tikv.Codec , dbName , tableName , partName string ) string {
110+ var id string
99111 isPartition := partName != ""
100112 if isPartition {
101- r . ID = fmt .Sprintf (PartitionIDFormat , IDPrefix , dbName , tableName , partName )
113+ id = fmt .Sprintf (PartitionIDFormat , IDPrefix , dbName , tableName , partName )
102114 } else {
103- r . ID = fmt .Sprintf (TableIDFormat , IDPrefix , dbName , tableName )
115+ id = fmt .Sprintf (TableIDFormat , IDPrefix , dbName , tableName )
104116 }
117+ if UseKeyspaceAwareRules (tikvCodec ) {
118+ id = fmt .Sprintf ("%s/%d/%s" , KeyspacePrefix , tikvCodec .GetKeyspaceID (), id )
119+ }
120+ return id
121+ }
122+
123+ // Reset will reset the label rule for a table/partition with a given ID and names.
124+ func (r * Rule ) Reset (tikvCodec tikv.Codec , dbName , tableName , partName string , ids ... int64 ) * Rule {
125+ isPartition := partName != ""
126+ useKeyspace := UseKeyspaceAwareRules (tikvCodec )
127+ r .ID = NewRuleID (tikvCodec , dbName , tableName , partName )
105128 if len (r .Labels ) == 0 {
106129 return r
107130 }
108- var hasDBKey , hasTableKey , hasPartitionKey bool
131+ var hasKeyspaceKey , hasDBKey , hasTableKey , hasPartitionKey bool
109132 for i := range r .Labels {
110133 switch r .Labels [i ].Key {
134+ case keyspaceKey :
135+ if useKeyspace {
136+ r .Labels [i ].Value = strconv .FormatInt (int64 (tikvCodec .GetKeyspaceID ()), 10 )
137+ hasKeyspaceKey = true
138+ }
111139 case dbKey :
112140 r .Labels [i ].Value = dbName
113141 hasDBKey = true
@@ -123,6 +151,10 @@ func (r *Rule) Reset(dbName, tableName, partName string, ids ...int64) *Rule {
123151 }
124152 }
125153
154+ if useKeyspace && ! hasKeyspaceKey {
155+ r .Labels = append (r .Labels , pd.RegionLabel {Key : keyspaceKey , Value : strconv .FormatInt (int64 (tikvCodec .GetKeyspaceID ()), 10 )})
156+ }
157+
126158 if ! hasDBKey {
127159 r .Labels = append (r .Labels , pd.RegionLabel {Key : dbKey , Value : dbName })
128160 }
@@ -138,9 +170,16 @@ func (r *Rule) Reset(dbName, tableName, partName string, ids ...int64) *Rule {
138170 dataSlice := make ([]any , 0 , len (ids ))
139171 slices .Sort (ids )
140172 for i := range ids {
173+ startKey := codec .EncodeBytes (nil , tablecodec .GenTablePrefix (ids [i ]))
174+ endKey := codec .EncodeBytes (nil , tablecodec .GenTablePrefix (ids [i ]+ 1 ))
175+ if useKeyspace {
176+ // Label rules are consumed as region boundary keys, so V2 must encode
177+ // the whole outer key instead of prefixing a mem-encoded table key.
178+ startKey , endKey = tikvCodec .EncodeRegionRange (tablecodec .GenTablePrefix (ids [i ]), tablecodec .GenTablePrefix (ids [i ]+ 1 ))
179+ }
141180 data := map [string ]string {
142- "start_key" : hex .EncodeToString (codec . EncodeBytes ( nil , tablecodec . GenTablePrefix ( ids [ i ])) ),
143- "end_key" : hex .EncodeToString (codec . EncodeBytes ( nil , tablecodec . GenTablePrefix ( ids [ i ] + 1 )) ),
181+ "start_key" : hex .EncodeToString (startKey ),
182+ "end_key" : hex .EncodeToString (endKey ),
144183 }
145184 dataSlice = append (dataSlice , data )
146185 }
0 commit comments