@@ -18,9 +18,11 @@ import (
18
18
"context"
19
19
"encoding/binary"
20
20
"math"
21
+ "time"
21
22
22
23
"github.com/cznic/mathutil"
23
24
"github.com/pingcap/errors"
25
+ "github.com/pingcap/failpoint"
24
26
"github.com/pingcap/parser/model"
25
27
"github.com/pingcap/parser/mysql"
26
28
"github.com/pingcap/tidb/kv"
@@ -60,6 +62,9 @@ func (e *SplitIndexRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
60
62
if err != nil {
61
63
return err
62
64
}
65
+
66
+ ctxWithTimeout , cancel := context .WithTimeout (ctx , e .ctx .GetSessionVars ().GetSplitRegionTimeout ())
67
+ defer cancel ()
63
68
regionIDs := make ([]uint64 , 0 , len (splitIdxKeys ))
64
69
for _ , idxKey := range splitIdxKeys {
65
70
regionID , err := s .SplitRegionAndScatter (idxKey )
@@ -72,8 +77,11 @@ func (e *SplitIndexRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
72
77
}
73
78
regionIDs = append (regionIDs , regionID )
74
79
80
+ if isCtxDone (ctxWithTimeout ) {
81
+ return errors .Errorf ("split region timeout(%v)" , e .ctx .GetSessionVars ().GetSplitRegionTimeout ())
82
+ }
75
83
}
76
- if ! e .ctx .GetSessionVars ().WaitTableSplitFinish {
84
+ if ! e .ctx .GetSessionVars ().WaitSplitRegionFinish {
77
85
return nil
78
86
}
79
87
for _ , regionID := range regionIDs {
@@ -85,6 +93,9 @@ func (e *SplitIndexRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
85
93
zap .String ("index" , e .indexInfo .Name .L ),
86
94
zap .Error (err ))
87
95
}
96
+ if isCtxDone (ctxWithTimeout ) {
97
+ return errors .Errorf ("wait split region scatter timeout(%v)" , e .ctx .GetSessionVars ().GetSplitRegionTimeout ())
98
+ }
88
99
}
89
100
return nil
90
101
}
@@ -228,6 +239,10 @@ func (e *SplitTableRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
228
239
if err != nil {
229
240
return err
230
241
}
242
+
243
+ ctxWithTimeout , cancel := context .WithTimeout (ctx , e .ctx .GetSessionVars ().GetSplitRegionTimeout ())
244
+ defer cancel ()
245
+
231
246
regionIDs := make ([]uint64 , 0 , len (splitKeys ))
232
247
for _ , key := range splitKeys {
233
248
regionID , err := s .SplitRegionAndScatter (key )
@@ -238,8 +253,18 @@ func (e *SplitTableRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
238
253
continue
239
254
}
240
255
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
+ }
241
266
}
242
- if ! e .ctx .GetSessionVars ().WaitTableSplitFinish {
267
+ if ! e .ctx .GetSessionVars ().WaitSplitRegionFinish {
243
268
return nil
244
269
}
245
270
for _ , regionID := range regionIDs {
@@ -250,10 +275,28 @@ func (e *SplitTableRegionExec) Next(ctx context.Context, _ *chunk.Chunk) error {
250
275
zap .String ("table" , e .tableInfo .Name .L ),
251
276
zap .Error (err ))
252
277
}
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
+ }
253
287
}
254
288
return nil
255
289
}
256
290
291
+ func isCtxDone (ctx context.Context ) bool {
292
+ select {
293
+ case <- ctx .Done ():
294
+ return true
295
+ default :
296
+ return false
297
+ }
298
+ }
299
+
257
300
var minRegionStepValue = uint64 (1000 )
258
301
259
302
func (e * SplitTableRegionExec ) getSplitTableKeys () ([][]byte , error ) {
0 commit comments