Skip to content

Commit 6b5b1a6

Browse files
crazycs520zimulala
authored andcommitted
*: rename and add tidb_wait_split_region_timeout session variable to set wait split region timeout. (pingcap#10797) (pingcap#10892)
1 parent c73c8ef commit 6b5b1a6

File tree

9 files changed

+119
-20
lines changed

9 files changed

+119
-20
lines changed

ddl/ddl_api.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -1171,10 +1171,10 @@ func (d *ddl) CreateTable(ctx sessionctx.Context, s *ast.CreateTableStmt) (err e
11711171
if err == nil {
11721172
// do pre-split and scatter.
11731173
if tbInfo.ShardRowIDBits > 0 && tbInfo.PreSplitRegions > 0 {
1174-
if ctx.GetSessionVars().WaitTableSplitFinish {
1175-
preSplitTableRegion(d.store, tbInfo, true)
1174+
if ctx.GetSessionVars().WaitSplitRegionFinish {
1175+
preSplitTableShardRowIDBitsRegion(d.store, tbInfo, true)
11761176
} else {
1177-
go preSplitTableRegion(d.store, tbInfo, false)
1177+
go preSplitTableShardRowIDBitsRegion(d.store, tbInfo, false)
11781178
}
11791179
}
11801180
if tbInfo.AutoIncID > 1 {

ddl/table.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ func splitTableRegion(store kv.Storage, tableID int64) {
178178
}
179179
}
180180

181-
func preSplitTableRegion(store kv.Storage, tblInfo *model.TableInfo, waitTableSplitFinish bool) {
181+
func preSplitTableShardRowIDBitsRegion(store kv.Storage, tblInfo *model.TableInfo, waitTableSplitFinish bool) {
182182
s, ok := store.(splitableStore)
183183
if !ok {
184184
return

executor/executor_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -1908,6 +1908,26 @@ func (s *testSuite) TestPointGetRepeatableRead(c *C) {
19081908
c.Assert(failpoint.Disable(step2), IsNil)
19091909
}
19101910

1911+
func (s *testSuite) TestSplitRegionTimeout(c *C) {
1912+
c.Assert(failpoint.Enable("github.com/pingcap/tidb/executor/mockSplitRegionTimeout", `return(true)`), IsNil)
1913+
tk := testkit.NewTestKit(c, s.store)
1914+
tk.MustExec("use test")
1915+
tk.MustExec("drop table if exists t")
1916+
tk.MustExec("create table t(a varchar(100),b int, index idx1(b,a))")
1917+
tk.MustExec(`split table t index idx1 by (10000,"abcd"),(10000000);`)
1918+
tk.MustExec(`set @@tidb_wait_split_region_timeout=1`)
1919+
_, err := tk.Exec(`split table t between (0) and (10000) regions 10`)
1920+
c.Assert(err, NotNil)
1921+
c.Assert(err.Error(), Equals, "split region timeout(1s)")
1922+
c.Assert(failpoint.Disable("github.com/pingcap/tidb/executor/mockSplitRegionTimeout"), IsNil)
1923+
1924+
c.Assert(failpoint.Enable("github.com/pingcap/tidb/executor/mockScatterRegionTimeout", `return(true)`), IsNil)
1925+
_, err = tk.Exec(`split table t between (0) and (10000) regions 10`)
1926+
c.Assert(err, NotNil)
1927+
c.Assert(err.Error(), Equals, "wait split region scatter timeout(1s)")
1928+
c.Assert(failpoint.Disable("github.com/pingcap/tidb/executor/mockScatterRegionTimeout"), IsNil)
1929+
}
1930+
19111931
func (s *testSuite) TestRow(c *C) {
19121932
tk := testkit.NewTestKit(c, s.store)
19131933
tk.MustExec("use test")

executor/set_test.go

+17-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
package executor_test
1515

1616
import (
17+
"strconv"
18+
1719
. "github.com/pingcap/check"
1820
"github.com/pingcap/parser/terror"
1921
"github.com/pingcap/tidb/config"
@@ -258,12 +260,21 @@ func (s *testSuite) TestSetVar(c *C) {
258260
tk.MustExec("set global tidb_constraint_check_in_place = 0")
259261
tk.MustQuery(`select @@global.tidb_constraint_check_in_place;`).Check(testkit.Rows("0"))
260262

261-
// test for tidb_wait_table_split_finish
262-
tk.MustQuery(`select @@session.tidb_wait_table_split_finish;`).Check(testkit.Rows("0"))
263-
tk.MustExec("set tidb_wait_table_split_finish = 1")
264-
tk.MustQuery(`select @@session.tidb_wait_table_split_finish;`).Check(testkit.Rows("1"))
265-
tk.MustExec("set tidb_wait_table_split_finish = 0")
266-
tk.MustQuery(`select @@session.tidb_wait_table_split_finish;`).Check(testkit.Rows("0"))
263+
// test for tidb_wait_split_region_finish
264+
tk.MustQuery(`select @@session.tidb_wait_split_region_finish;`).Check(testkit.Rows("1"))
265+
tk.MustExec("set tidb_wait_split_region_finish = 1")
266+
tk.MustQuery(`select @@session.tidb_wait_split_region_finish;`).Check(testkit.Rows("1"))
267+
tk.MustExec("set tidb_wait_split_region_finish = 0")
268+
tk.MustQuery(`select @@session.tidb_wait_split_region_finish;`).Check(testkit.Rows("0"))
269+
270+
// test for tidb_wait_split_region_timeout
271+
tk.MustQuery(`select @@session.tidb_wait_split_region_timeout;`).Check(testkit.Rows(strconv.Itoa(variable.DefWaitSplitRegionTimeout)))
272+
tk.MustExec("set tidb_wait_split_region_timeout = 1")
273+
tk.MustQuery(`select @@session.tidb_wait_split_region_timeout;`).Check(testkit.Rows("1"))
274+
_, err = tk.Exec("set tidb_wait_split_region_timeout = 0")
275+
c.Assert(err, NotNil)
276+
c.Assert(err.Error(), Equals, "tidb_wait_split_region_timeout(0) cannot be smaller than 1")
277+
tk.MustQuery(`select @@session.tidb_wait_split_region_timeout;`).Check(testkit.Rows("1"))
267278
}
268279

269280
func (s *testSuite) TestSetCharset(c *C) {

executor/split.go

+45-2
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ import (
1818
"context"
1919
"encoding/binary"
2020
"math"
21+
"time"
2122

2223
"github.com/cznic/mathutil"
2324
"github.com/pingcap/errors"
25+
"github.com/pingcap/failpoint"
2426
"github.com/pingcap/parser/model"
2527
"github.com/pingcap/parser/mysql"
2628
"github.com/pingcap/tidb/kv"
@@ -60,6 +62,9 @@ func (e *SplitIndexRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
6062
if err != nil {
6163
return err
6264
}
65+
66+
ctxWithTimeout, cancel := context.WithTimeout(ctx, e.ctx.GetSessionVars().GetSplitRegionTimeout())
67+
defer cancel()
6368
regionIDs := make([]uint64, 0, len(splitIdxKeys))
6469
for _, idxKey := range splitIdxKeys {
6570
regionID, err := s.SplitRegionAndScatter(idxKey)
@@ -72,8 +77,11 @@ func (e *SplitIndexRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
7277
}
7378
regionIDs = append(regionIDs, regionID)
7479

80+
if isCtxDone(ctxWithTimeout) {
81+
return errors.Errorf("split region timeout(%v)", e.ctx.GetSessionVars().GetSplitRegionTimeout())
82+
}
7583
}
76-
if !e.ctx.GetSessionVars().WaitTableSplitFinish {
84+
if !e.ctx.GetSessionVars().WaitSplitRegionFinish {
7785
return nil
7886
}
7987
for _, regionID := range regionIDs {
@@ -85,6 +93,9 @@ func (e *SplitIndexRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
8593
zap.String("index", e.indexInfo.Name.L),
8694
zap.Error(err))
8795
}
96+
if isCtxDone(ctxWithTimeout) {
97+
return errors.Errorf("wait split region scatter timeout(%v)", e.ctx.GetSessionVars().GetSplitRegionTimeout())
98+
}
8899
}
89100
return nil
90101
}
@@ -228,6 +239,10 @@ func (e *SplitTableRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
228239
if err != nil {
229240
return err
230241
}
242+
243+
ctxWithTimeout, cancel := context.WithTimeout(ctx, e.ctx.GetSessionVars().GetSplitRegionTimeout())
244+
defer cancel()
245+
231246
regionIDs := make([]uint64, 0, len(splitKeys))
232247
for _, key := range splitKeys {
233248
regionID, err := s.SplitRegionAndScatter(key)
@@ -238,8 +253,18 @@ func (e *SplitTableRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
238253
continue
239254
}
240255
regionIDs = append(regionIDs, regionID)
256+
257+
failpoint.Inject("mockSplitRegionTimeout", func(val failpoint.Value) {
258+
if val.(bool) {
259+
time.Sleep(time.Second * 1)
260+
}
261+
})
262+
263+
if isCtxDone(ctxWithTimeout) {
264+
return errors.Errorf("split region timeout(%v)", e.ctx.GetSessionVars().GetSplitRegionTimeout())
265+
}
241266
}
242-
if !e.ctx.GetSessionVars().WaitTableSplitFinish {
267+
if !e.ctx.GetSessionVars().WaitSplitRegionFinish {
243268
return nil
244269
}
245270
for _, regionID := range regionIDs {
@@ -250,10 +275,28 @@ func (e *SplitTableRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
250275
zap.String("table", e.tableInfo.Name.L),
251276
zap.Error(err))
252277
}
278+
failpoint.Inject("mockScatterRegionTimeout", func(val failpoint.Value) {
279+
if val.(bool) {
280+
time.Sleep(time.Second * 1)
281+
}
282+
})
283+
284+
if isCtxDone(ctxWithTimeout) {
285+
return errors.Errorf("wait split region scatter timeout(%v)", e.ctx.GetSessionVars().GetSplitRegionTimeout())
286+
}
253287
}
254288
return nil
255289
}
256290

291+
func isCtxDone(ctx context.Context) bool {
292+
select {
293+
case <-ctx.Done():
294+
return true
295+
default:
296+
return false
297+
}
298+
}
299+
257300
var minRegionStepValue = uint64(1000)
258301

259302
func (e *SplitTableRegionExec) getSplitTableKeys() ([][]byte, error) {

sessionctx/variable/session.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,11 @@ type SessionVars struct {
305305
// DDLReorgPriority is the operation priority of adding indices.
306306
DDLReorgPriority int
307307

308-
// WaitTableSplitFinish defines the create table pre-split behaviour is sync or async.
309-
WaitTableSplitFinish bool
308+
// WaitSplitRegionFinish defines the create table pre-split behaviour is sync or async.
309+
WaitSplitRegionFinish bool
310+
311+
// WaitSplitRegionTimeout defines the split region timeout.
312+
WaitSplitRegionTimeout uint64
310313

311314
// EnableStreaming indicates whether the coprocessor request can use streaming API.
312315
// TODO: remove this after tidb-server configuration "enable-streaming' removed.
@@ -367,6 +370,8 @@ func NewSessionVars() *SessionVars {
367370
DisableTxnAutoRetry: DefTiDBDisableTxnAutoRetry,
368371
DDLReorgPriority: kv.PriorityLow,
369372
SlowQueryFile: config.GetGlobalConfig().Log.SlowQueryFile,
373+
WaitSplitRegionFinish: DefTiDBWaitSplitRegionFinish,
374+
WaitSplitRegionTimeout: DefWaitSplitRegionTimeout,
370375
CommandValue: uint32(mysql.ComSleep),
371376
}
372377
vars.Concurrency = Concurrency{
@@ -418,6 +423,11 @@ func (s *SessionVars) CleanBuffers() {
418423
}
419424
}
420425

426+
// GetSplitRegionTimeout gets split region timeout.
427+
func (s *SessionVars) GetSplitRegionTimeout() time.Duration {
428+
return time.Duration(s.WaitSplitRegionTimeout) * time.Second
429+
}
430+
421431
// AllocPlanColumnID allocates column id for plan.
422432
func (s *SessionVars) AllocPlanColumnID() int64 {
423433
s.PlanColumnID++
@@ -650,8 +660,10 @@ func (s *SessionVars) SetSystemVar(name string, val string) error {
650660
config.GetGlobalConfig().CheckMb4ValueInUTF8 = TiDBOptOn(val)
651661
case TiDBSlowQueryFile:
652662
s.SlowQueryFile = val
653-
case TiDBWaitTableSplitFinish:
654-
s.WaitTableSplitFinish = TiDBOptOn(val)
663+
case TiDBWaitSplitRegionFinish:
664+
s.WaitSplitRegionFinish = TiDBOptOn(val)
665+
case TiDBWaitSplitRegionTimeout:
666+
s.WaitSplitRegionTimeout = uint64(tidbOptPositiveInt32(val, DefWaitSplitRegionTimeout))
655667
}
656668
s.systems[name] = val
657669
return nil

sessionctx/variable/sysvar.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,8 @@ var defaultSysVars = []*SysVar{
676676
{ScopeSession, TiDBForcePriority, mysql.Priority2Str[DefTiDBForcePriority]},
677677
{ScopeSession, TiDBCheckMb4ValueInUTF8, BoolToIntStr(config.GetGlobalConfig().CheckMb4ValueInUTF8)},
678678
{ScopeSession, TiDBSlowQueryFile, ""},
679-
{ScopeSession, TiDBWaitTableSplitFinish, BoolToIntStr(DefTiDBWaitTableSplitFinish)},
679+
{ScopeSession, TiDBWaitSplitRegionFinish, BoolToIntStr(DefTiDBWaitSplitRegionFinish)},
680+
{ScopeSession, TiDBWaitSplitRegionTimeout, strconv.Itoa(DefWaitSplitRegionTimeout)},
680681
}
681682

682683
// SynonymsSysVariables is synonyms of system variables.

sessionctx/variable/tidb_vars.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,11 @@ const (
203203
// It can be: PRIORITY_LOW, PRIORITY_NORMAL, PRIORITY_HIGH
204204
TiDBDDLReorgPriority = "tidb_ddl_reorg_priority"
205205

206-
// TiDBWaitTableSplitFinish defines the create table pre-split behaviour is sync or async.
207-
TiDBWaitTableSplitFinish = "tidb_wait_table_split_finish"
206+
// TiDBWaitSplitRegionFinish defines the split region behaviour is sync or async.
207+
TiDBWaitSplitRegionFinish = "tidb_wait_split_region_finish"
208+
209+
// TiDBWaitSplitRegionTimeout uses to set the split and scatter region back off time.
210+
TiDBWaitSplitRegionTimeout = "tidb_wait_split_region_timeout"
208211

209212
// tidb_force_priority defines the operations priority of all statements.
210213
// It can be "NO_PRIORITY", "LOW_PRIORITY", "HIGH_PRIORITY", "DELAYED"
@@ -261,7 +264,8 @@ const (
261264
DefTiDBHashAggPartialConcurrency = 4
262265
DefTiDBHashAggFinalConcurrency = 4
263266
DefTiDBForcePriority = mysql.NoPriority
264-
DefTiDBWaitTableSplitFinish = false
267+
DefTiDBWaitSplitRegionFinish = true
268+
DefWaitSplitRegionTimeout = 300 // 300s
265269
)
266270

267271
// Process global variables.

sessionctx/variable/varsutil.go

+8
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,14 @@ func ValidateSetSystemVar(vars *SessionVars, name string, value string) (string,
380380
return "", ErrWrongValueForVar.GenWithStackByArgs(name, value)
381381
}
382382
return upVal, nil
383+
case TiDBWaitSplitRegionTimeout:
384+
v, err := strconv.Atoi(value)
385+
if err != nil {
386+
return value, ErrWrongTypeForVar.GenWithStackByArgs(name)
387+
}
388+
if v <= 0 {
389+
return value, errors.Errorf("tidb_wait_split_region_timeout(%d) cannot be smaller than 1", v)
390+
}
383391
}
384392
return value, nil
385393
}

0 commit comments

Comments
 (0)