Skip to content

Commit 14d29c3

Browse files
crazycs520winkyao
authored andcommitted
*: add show table regions syntax (#10612) (#11234)
1 parent 4c5a9ac commit 14d29c3

12 files changed

+490
-5
lines changed

executor/builder.go

+1
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,7 @@ func (b *executorBuilder) buildShow(v *plannercore.Show) Executor {
553553
DBName: model.NewCIStr(v.DBName),
554554
Table: v.Table,
555555
Column: v.Column,
556+
IndexName: v.IndexName,
556557
User: v.User,
557558
Roles: v.Roles,
558559
IfNotExists: v.IfNotExists,

executor/executor_test.go

+116
Original file line numberDiff line numberDiff line change
@@ -3921,6 +3921,122 @@ func (s *testSuite) TestSplitRegion(c *C) {
39213921
tk.MustExec(`split table t by (0),(1000),(1000000)`)
39223922
}
39233923

3924+
func (s *testSuite) TestShowTableRegion(c *C) {
3925+
tk := testkit.NewTestKit(c, s.store)
3926+
tk.MustExec("use test")
3927+
tk.MustExec("drop table if exists t_regions1, t_regions")
3928+
tk.MustExec("create table t_regions1 (a int key, b int, index idx(b))")
3929+
tk.MustExec("create table t_regions (a int key, b int, index idx(b))")
3930+
3931+
// Test show table regions.
3932+
tk.MustExec(`split table t_regions1 by (0)`)
3933+
tk.MustExec(`split table t_regions between (-10000) and (10000) regions 4;`)
3934+
re := tk.MustQuery("show table t_regions regions")
3935+
rows := re.Rows()
3936+
// Table t_regions should have 4 regions now.
3937+
c.Assert(len(rows), Equals, 4)
3938+
c.Assert(len(rows[0]), Equals, 7)
3939+
tbl1 := testGetTableByName(c, tk.Se, "test", "t_regions1")
3940+
tbl := testGetTableByName(c, tk.Se, "test", "t_regions")
3941+
// Check the region start key.
3942+
c.Assert(rows[0][1], Matches, fmt.Sprintf("t_%d_.*", tbl1.Meta().ID))
3943+
c.Assert(rows[1][1], Equals, fmt.Sprintf("t_%d_r_-5000", tbl.Meta().ID))
3944+
c.Assert(rows[2][1], Equals, fmt.Sprintf("t_%d_r_0", tbl.Meta().ID))
3945+
c.Assert(rows[3][1], Equals, fmt.Sprintf("t_%d_r_5000", tbl.Meta().ID))
3946+
3947+
// Test show table index regions.
3948+
tk.MustExec(`split table t_regions index idx between (-1000) and (1000) regions 4;`)
3949+
re = tk.MustQuery("show table t_regions index idx regions")
3950+
rows = re.Rows()
3951+
// The index `idx` of table t_regions should have 4 regions now.
3952+
c.Assert(len(rows), Equals, 4)
3953+
// Check the region start key.
3954+
c.Assert(rows[0][1], Equals, fmt.Sprintf("t_%d_i_1_", tbl.Meta().ID))
3955+
c.Assert(rows[1][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
3956+
c.Assert(rows[2][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
3957+
c.Assert(rows[3][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
3958+
3959+
re = tk.MustQuery("show table t_regions regions")
3960+
rows = re.Rows()
3961+
// The index `idx` of table t_regions should have 4 regions now.
3962+
c.Assert(len(rows), Equals, 7)
3963+
// Check the region start key.
3964+
c.Assert(rows[0][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
3965+
c.Assert(rows[1][1], Equals, fmt.Sprintf("t_%d_r_-5000", tbl.Meta().ID))
3966+
c.Assert(rows[2][1], Equals, fmt.Sprintf("t_%d_r_0", tbl.Meta().ID))
3967+
c.Assert(rows[3][1], Equals, fmt.Sprintf("t_%d_r_5000", tbl.Meta().ID))
3968+
c.Assert(rows[4][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
3969+
c.Assert(rows[5][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
3970+
c.Assert(rows[6][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
3971+
3972+
// Test unsigned primary key and wait scatter finish.
3973+
tk.MustExec("drop table if exists t_regions")
3974+
tk.MustExec("create table t_regions (a int unsigned key, b int, index idx(b))")
3975+
3976+
// Test show table regions.
3977+
tk.MustExec(`set @@session.tidb_wait_split_region_finish=1;`)
3978+
tk.MustExec(`split table t_regions between (0) and (10000) regions 4;`)
3979+
re = tk.MustQuery("show table t_regions regions")
3980+
rows = re.Rows()
3981+
// Table t_regions should have 4 regions now.
3982+
c.Assert(len(rows), Equals, 4)
3983+
tbl = testGetTableByName(c, tk.Se, "test", "t_regions")
3984+
// Check the region start key.
3985+
c.Assert(rows[0][1], Matches, "t_.*")
3986+
c.Assert(rows[1][1], Equals, fmt.Sprintf("t_%d_r_2500", tbl.Meta().ID))
3987+
c.Assert(rows[2][1], Equals, fmt.Sprintf("t_%d_r_5000", tbl.Meta().ID))
3988+
c.Assert(rows[3][1], Equals, fmt.Sprintf("t_%d_r_7500", tbl.Meta().ID))
3989+
3990+
// Test show table index regions.
3991+
tk.MustExec(`split table t_regions index idx between (0) and (1000) regions 4;`)
3992+
re = tk.MustQuery("show table t_regions index idx regions")
3993+
rows = re.Rows()
3994+
// The index `idx` of table t_regions should have 4 regions now.
3995+
c.Assert(len(rows), Equals, 4)
3996+
// Check the region start key.
3997+
c.Assert(rows[0][1], Equals, fmt.Sprintf("t_%d_i_1_", tbl.Meta().ID))
3998+
c.Assert(rows[1][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
3999+
c.Assert(rows[2][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
4000+
c.Assert(rows[3][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
4001+
4002+
// Test show table regions for partition table when disable split region when create table.
4003+
atomic.StoreUint32(&ddl.EnableSplitTableRegion, 0)
4004+
tk.MustExec("drop table if exists partition_t;")
4005+
tk.MustExec("set @@session.tidb_enable_table_partition = '1';")
4006+
tk.MustExec("create table partition_t (a int, b int,index(a)) partition by hash (a) partitions 3")
4007+
re = tk.MustQuery("show table partition_t regions")
4008+
rows = re.Rows()
4009+
// Table t_regions should have 4 regions now.
4010+
c.Assert(len(rows), Equals, 1)
4011+
c.Assert(rows[0][1], Matches, "t_.*")
4012+
4013+
// Test show table regions for partition table when enable split region when create table.
4014+
atomic.StoreUint32(&ddl.EnableSplitTableRegion, 1)
4015+
tk.MustExec("set @@global.tidb_scatter_region=1;")
4016+
tk.MustExec("drop table if exists partition_t;")
4017+
tk.MustExec("create table partition_t (a int, b int,index(a)) partition by hash (a) partitions 3")
4018+
re = tk.MustQuery("show table partition_t regions")
4019+
rows = re.Rows()
4020+
// Table t_regions should have 4 regions now.
4021+
c.Assert(len(rows), Equals, 3)
4022+
tbl = testGetTableByName(c, tk.Se, "test", "partition_t")
4023+
partitionDef := tbl.Meta().GetPartitionInfo().Definitions
4024+
c.Assert(rows[0][1], Matches, fmt.Sprintf("t_%d_.*", partitionDef[0].ID))
4025+
c.Assert(rows[1][1], Matches, fmt.Sprintf("t_%d_.*", partitionDef[1].ID))
4026+
c.Assert(rows[2][1], Matches, fmt.Sprintf("t_%d_.*", partitionDef[2].ID))
4027+
atomic.StoreUint32(&ddl.EnableSplitTableRegion, 0)
4028+
}
4029+
4030+
func testGetTableByName(c *C, ctx sessionctx.Context, db, table string) table.Table {
4031+
dom := domain.GetDomain(ctx)
4032+
// Make sure the table schema is the new schema.
4033+
err := dom.Reload()
4034+
c.Assert(err, IsNil)
4035+
tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table))
4036+
c.Assert(err, IsNil)
4037+
return tbl
4038+
}
4039+
39244040
func (s *testSuite) TestIssue10435(c *C) {
39254041
tk := testkit.NewTestKit(c, s.store)
39264042
tk.MustExec("use test")

executor/show.go

+110
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ import (
3737
"github.com/pingcap/tidb/config"
3838
"github.com/pingcap/tidb/domain"
3939
"github.com/pingcap/tidb/infoschema"
40+
"github.com/pingcap/tidb/kv"
4041
plannercore "github.com/pingcap/tidb/planner/core"
4142
"github.com/pingcap/tidb/plugin"
4243
"github.com/pingcap/tidb/privilege"
4344
"github.com/pingcap/tidb/sessionctx/stmtctx"
4445
"github.com/pingcap/tidb/sessionctx/variable"
46+
"github.com/pingcap/tidb/store/tikv"
4547
"github.com/pingcap/tidb/table"
4648
"github.com/pingcap/tidb/types"
4749
"github.com/pingcap/tidb/types/json"
@@ -60,6 +62,7 @@ type ShowExec struct {
6062
DBName model.CIStr
6163
Table *ast.TableName // Used for showing columns.
6264
Column *ast.ColumnName // Used for `desc table column`.
65+
IndexName model.CIStr // Used for show table regions.
6366
Flag int // Some flag parsed from sql, such as FULL.
6467
Full bool
6568
User *auth.UserIdentity // Used for show grants.
@@ -178,6 +181,8 @@ func (e *ShowExec) fetchAll() error {
178181
case ast.ShowAnalyzeStatus:
179182
e.fetchShowAnalyzeStatus()
180183
return nil
184+
case ast.ShowRegions:
185+
return e.fetchShowTableRegions()
181186
}
182187
return nil
183188
}
@@ -1166,3 +1171,108 @@ func (e *ShowExec) appendRow(row []interface{}) {
11661171
}
11671172
}
11681173
}
1174+
1175+
func (e *ShowExec) fetchShowTableRegions() error {
1176+
store := e.ctx.GetStore()
1177+
tikvStore, ok := store.(tikv.Storage)
1178+
if !ok {
1179+
return nil
1180+
}
1181+
splitStore, ok := store.(kv.SplitableStore)
1182+
if !ok {
1183+
return nil
1184+
}
1185+
1186+
tb, err := e.getTable()
1187+
if err != nil {
1188+
return errors.Trace(err)
1189+
}
1190+
1191+
// Get table regions from from pd, not from regionCache, because the region cache maybe outdated.
1192+
var regions []regionMeta
1193+
if len(e.IndexName.L) != 0 {
1194+
indexInfo := tb.Meta().FindIndexByName(e.IndexName.L)
1195+
if indexInfo == nil {
1196+
return plannercore.ErrKeyDoesNotExist.GenWithStackByArgs(e.IndexName, tb.Meta().Name)
1197+
}
1198+
regions, err = getTableIndexRegions(tb, indexInfo, tikvStore, splitStore)
1199+
} else {
1200+
regions, err = getTableRegions(tb, tikvStore, splitStore)
1201+
}
1202+
1203+
if err != nil {
1204+
return err
1205+
}
1206+
e.fillRegionsToChunk(regions)
1207+
return nil
1208+
}
1209+
1210+
func getTableRegions(tb table.Table, tikvStore tikv.Storage, splitStore kv.SplitableStore) ([]regionMeta, error) {
1211+
if info := tb.Meta().GetPartitionInfo(); info != nil {
1212+
return getPartitionTableRegions(info, tb.(table.PartitionedTable), tikvStore, splitStore)
1213+
}
1214+
return getPhysicalTableRegions(tb.Meta().ID, tb.Meta(), tikvStore, splitStore, nil)
1215+
}
1216+
1217+
func getTableIndexRegions(tb table.Table, indexInfo *model.IndexInfo, tikvStore tikv.Storage, splitStore kv.SplitableStore) ([]regionMeta, error) {
1218+
if info := tb.Meta().GetPartitionInfo(); info != nil {
1219+
return getPartitionIndexRegions(info, tb.(table.PartitionedTable), indexInfo, tikvStore, splitStore)
1220+
}
1221+
return getPhysicalIndexRegions(tb.Meta().ID, indexInfo, tikvStore, splitStore, nil)
1222+
}
1223+
1224+
func getPartitionTableRegions(info *model.PartitionInfo, tbl table.PartitionedTable, tikvStore tikv.Storage, splitStore kv.SplitableStore) ([]regionMeta, error) {
1225+
regions := make([]regionMeta, 0, len(info.Definitions))
1226+
uniqueRegionMap := make(map[uint64]struct{})
1227+
for _, def := range info.Definitions {
1228+
pid := def.ID
1229+
partition := tbl.GetPartition(pid)
1230+
partition.GetPhysicalID()
1231+
partitionRegions, err := getPhysicalTableRegions(partition.GetPhysicalID(), tbl.Meta(), tikvStore, splitStore, uniqueRegionMap)
1232+
if err != nil {
1233+
return nil, err
1234+
}
1235+
regions = append(regions, partitionRegions...)
1236+
}
1237+
return regions, nil
1238+
}
1239+
1240+
func getPartitionIndexRegions(info *model.PartitionInfo, tbl table.PartitionedTable, indexInfo *model.IndexInfo, tikvStore tikv.Storage, splitStore kv.SplitableStore) ([]regionMeta, error) {
1241+
var regions []regionMeta
1242+
uniqueRegionMap := make(map[uint64]struct{})
1243+
for _, def := range info.Definitions {
1244+
pid := def.ID
1245+
partition := tbl.GetPartition(pid)
1246+
partition.GetPhysicalID()
1247+
partitionRegions, err := getPhysicalIndexRegions(partition.GetPhysicalID(), indexInfo, tikvStore, splitStore, uniqueRegionMap)
1248+
if err != nil {
1249+
return nil, err
1250+
}
1251+
regions = append(regions, partitionRegions...)
1252+
}
1253+
return regions, nil
1254+
}
1255+
1256+
func (e *ShowExec) fillRegionsToChunk(regions []regionMeta) {
1257+
for i := range regions {
1258+
e.result.AppendUint64(0, regions[i].region.Id)
1259+
e.result.AppendString(1, regions[i].start)
1260+
e.result.AppendString(2, regions[i].end)
1261+
e.result.AppendUint64(3, regions[i].leaderID)
1262+
e.result.AppendUint64(4, regions[i].storeID)
1263+
1264+
peers := ""
1265+
for i, peer := range regions[i].region.Peers {
1266+
if i > 0 {
1267+
peers += ", "
1268+
}
1269+
peers += strconv.FormatUint(peer.Id, 10)
1270+
}
1271+
e.result.AppendString(5, peers)
1272+
if regions[i].scattering {
1273+
e.result.AppendInt64(6, 1)
1274+
} else {
1275+
e.result.AppendInt64(6, 0)
1276+
}
1277+
}
1278+
}

0 commit comments

Comments
 (0)