diff --git a/executor/executor_test.go b/executor/executor_test.go index fe22553a41a0e..03dbf294c6f0e 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -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") diff --git a/executor/split.go b/executor/split.go index eefda2fa65601..6a67aaf83d219 100755 --- a/executor/split.go +++ b/executor/split.go @@ -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) diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index 574f60afa8b2f..b4c062c5f8a5d 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -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))