executor: split a separate region for index when split table region (#11721)

This commit is contained in:
crazycs
2019-08-22 10:35:46 +08:00
committed by pingcap-github-bot
parent 82ec3ca20f
commit ddace4f3fc
3 changed files with 36 additions and 14 deletions

View File

@ -4124,29 +4124,28 @@ func (s *testSuiteP1) TestSplitRegion(c *C) {
func (s *testSuite) TestShowTableRegion(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t_regions1, t_regions")
atomic.StoreUint32(&ddl.EnableSplitTableRegion, 0)
tk.MustExec("create table t_regions1 (a int key, b int, index idx(b))")
tk.MustExec("create table t_regions (a int key, b int, index idx(b))")
tk.MustExec("drop table if exists t_regions")
tk.MustExec("create table t_regions (a int key, b int, c int, index idx(b), index idx2(c))")
// Test show table regions.
tk.MustExec(`split table t_regions1 by (0)`)
tk.MustQuery(`split table t_regions between (-10000) and (10000) regions 4;`).Check(testkit.Rows("3 1"))
tk.MustQuery(`split table t_regions between (-10000) and (10000) regions 4;`).Check(testkit.Rows("4 1"))
re := tk.MustQuery("show table t_regions regions")
rows := re.Rows()
// Table t_regions should have 4 regions now.
c.Assert(len(rows), Equals, 4)
// Table t_regions should have 5 regions now.
// 4 regions to store record data.
// 1 region to store index data.
c.Assert(len(rows), Equals, 5)
c.Assert(len(rows[0]), Equals, 7)
tbl1 := testGetTableByName(c, tk.Se, "test", "t_regions1")
tbl := testGetTableByName(c, tk.Se, "test", "t_regions")
// Check the region start key.
c.Assert(rows[0][1], Matches, fmt.Sprintf("t_%d_.*", tbl1.Meta().ID))
c.Assert(rows[0][1], Equals, fmt.Sprintf("t_%d_r", tbl.Meta().ID))
c.Assert(rows[1][1], Equals, fmt.Sprintf("t_%d_r_-5000", tbl.Meta().ID))
c.Assert(rows[2][1], Equals, fmt.Sprintf("t_%d_r_0", tbl.Meta().ID))
c.Assert(rows[3][1], Equals, fmt.Sprintf("t_%d_r_5000", tbl.Meta().ID))
c.Assert(rows[4][2], Equals, fmt.Sprintf("t_%d_r", tbl.Meta().ID))
// Test show table index regions.
tk.MustQuery(`split table t_regions index idx between (-1000) and (1000) regions 4;`).Check(testkit.Rows("4 1"))
tk.MustQuery(`split table t_regions index idx between (-1000) and (1000) regions 4;`).Check(testkit.Rows("5 1"))
re = tk.MustQuery("show table t_regions index idx regions")
rows = re.Rows()
// The index `idx` of table t_regions should have 4 regions now.
@ -4159,15 +4158,21 @@ func (s *testSuite) TestShowTableRegion(c *C) {
re = tk.MustQuery("show table t_regions regions")
rows = re.Rows()
c.Assert(len(rows), Equals, 7)
// The index `idx` of table t_regions should have 9 regions now.
// 4 regions to store record data.
// 4 region to store index idx data.
// 1 region to store index idx2 data.
c.Assert(len(rows), Equals, 9)
// Check the region start key.
c.Assert(rows[0][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
c.Assert(rows[0][1], Equals, fmt.Sprintf("t_%d_r", tbl.Meta().ID))
c.Assert(rows[1][1], Equals, fmt.Sprintf("t_%d_r_-5000", tbl.Meta().ID))
c.Assert(rows[2][1], Equals, fmt.Sprintf("t_%d_r_0", tbl.Meta().ID))
c.Assert(rows[3][1], Equals, fmt.Sprintf("t_%d_r_5000", tbl.Meta().ID))
c.Assert(rows[4][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
c.Assert(rows[5][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
c.Assert(rows[6][1], Matches, fmt.Sprintf("t_%d_i_1_.*", tbl.Meta().ID))
c.Assert(rows[7][2], Equals, fmt.Sprintf("t_%d_i_2_", tbl.Meta().ID))
c.Assert(rows[8][2], Equals, fmt.Sprintf("t_%d_r", tbl.Meta().ID))
// Test unsigned primary key and wait scatter finish.
tk.MustExec("drop table if exists t_regions")

View File

@ -132,6 +132,16 @@ func (e *SplitIndexRegionExec) getSplitIdxKeys() ([][]byte, error) {
startIdxKey := tablecodec.EncodeTableIndexPrefix(e.tableInfo.ID, e.indexInfo.ID)
idxKeys = append(idxKeys, startIdxKey)
// Split in the end for the other index key.
for _, idx := range e.tableInfo.Indices {
if idx.ID <= e.indexInfo.ID {
continue
}
endIdxKey := tablecodec.EncodeTableIndexPrefix(e.tableInfo.ID, idx.ID)
idxKeys = append(idxKeys, endIdxKey)
break
}
index := tables.NewIndex(e.tableInfo.ID, e.tableInfo, e.indexInfo)
// Split index regions by user specified value lists.
if len(e.valueLists) > 0 {
@ -414,6 +424,10 @@ func (e *SplitTableRegionExec) getSplitTableKeys() ([][]byte, error) {
return nil, errors.Errorf("Split table `%s` region step value should more than %v, step %v is invalid", e.tableInfo.Name, minRegionStepValue, step)
}
// Split a separate region for index.
if len(e.tableInfo.Indices) > 0 {
keys = append(keys, recordPrefix)
}
recordID := lowerValue
for i := 1; i < e.num; i++ {
recordID += int64(step)
@ -538,6 +552,9 @@ func (d *regionKeyDecoder) decodeRegionKey(key []byte) string {
if len(d.indexPrefix) > 0 && bytes.HasPrefix(key, d.indexPrefix) {
return fmt.Sprintf("t_%d_i_%d_%x", d.physicalTableID, d.indexID, key[len(d.indexPrefix):])
} else if len(d.recordPrefix) > 0 && bytes.HasPrefix(key, d.recordPrefix) {
if len(d.recordPrefix) == len(key) {
return fmt.Sprintf("t_%d_r", d.physicalTableID)
}
_, handle, err := codec.DecodeInt(key[len(d.recordPrefix):])
if err == nil {
return fmt.Sprintf("t_%d_r_%d", d.physicalTableID, handle)

View File

@ -1210,7 +1210,7 @@ func buildTableRegionsSchema() *expression.Schema {
schema := expression.NewSchema(make([]*expression.Column, 0, 10)...)
schema.Append(buildColumn("", "REGION_ID", mysql.TypeLonglong, 4))
schema.Append(buildColumn("", "START_KEY", mysql.TypeVarchar, 64))
schema.Append(buildColumn("", "END_Key", mysql.TypeVarchar, 64))
schema.Append(buildColumn("", "END_KEY", mysql.TypeVarchar, 64))
schema.Append(buildColumn("", "LEADER_ID", mysql.TypeLonglong, 4))
schema.Append(buildColumn("", "LEADER_STORE_ID", mysql.TypeLonglong, 4))
schema.Append(buildColumn("", "PEERS", mysql.TypeVarchar, 64))