@@ -31,6 +31,8 @@ import (
31
31
"github.com/pingcap/tidb/pkg/statistics/handle/storage"
32
32
"github.com/pingcap/tidb/pkg/statistics/handle/util"
33
33
"github.com/pingcap/tidb/pkg/types"
34
+ "github.com/pingcap/tidb/pkg/util/logutil"
35
+ "go.uber.org/zap"
34
36
"golang.org/x/sync/errgroup"
35
37
)
36
38
@@ -79,8 +81,11 @@ type AsyncMergePartitionStats2GlobalStats struct {
79
81
PartitionDefinition map [int64 ]model.PartitionDefinition
80
82
tableInfo map [int64 ]* model.TableInfo
81
83
// key is partition id and histID
82
- skipPartition map [skipItem ]struct {}
83
- exitWhenErrChan chan struct {}
84
+ skipPartition map [skipItem ]struct {}
85
+ // ioWorker meet error, it will close this channel to notify cpuWorker.
86
+ ioWorkerExitWhenErrChan chan struct {}
87
+ // cpuWorker exit, it will close this channel to notify ioWorker.
88
+ cpuWorkerExitChan chan struct {}
84
89
globalTableInfo * model.TableInfo
85
90
histIDs []int64
86
91
globalStatsNDV []int64
@@ -97,20 +102,21 @@ func NewAsyncMergePartitionStats2GlobalStats(
97
102
is infoschema.InfoSchema ) (* AsyncMergePartitionStats2GlobalStats , error ) {
98
103
partitionNum := len (globalTableInfo .Partition .Definitions )
99
104
return & AsyncMergePartitionStats2GlobalStats {
100
- statsHandle : statsHandle ,
101
- cmsketch : make (chan mergeItem [* statistics.CMSketch ], 5 ),
102
- fmsketch : make (chan mergeItem [* statistics.FMSketch ], 5 ),
103
- histogramAndTopn : make (chan mergeItem [* StatsWrapper ]),
104
- PartitionDefinition : make (map [int64 ]model.PartitionDefinition ),
105
- tableInfo : make (map [int64 ]* model.TableInfo ),
106
- partitionIDs : make ([]int64 , 0 , partitionNum ),
107
- exitWhenErrChan : make (chan struct {}),
108
- skipPartition : make (map [skipItem ]struct {}),
109
- allPartitionStats : make (map [int64 ]* statistics.Table ),
110
- globalTableInfo : globalTableInfo ,
111
- histIDs : histIDs ,
112
- is : is ,
113
- partitionNum : partitionNum ,
105
+ statsHandle : statsHandle ,
106
+ cmsketch : make (chan mergeItem [* statistics.CMSketch ], 5 ),
107
+ fmsketch : make (chan mergeItem [* statistics.FMSketch ], 5 ),
108
+ histogramAndTopn : make (chan mergeItem [* StatsWrapper ]),
109
+ PartitionDefinition : make (map [int64 ]model.PartitionDefinition ),
110
+ tableInfo : make (map [int64 ]* model.TableInfo ),
111
+ partitionIDs : make ([]int64 , 0 , partitionNum ),
112
+ ioWorkerExitWhenErrChan : make (chan struct {}),
113
+ cpuWorkerExitChan : make (chan struct {}),
114
+ skipPartition : make (map [skipItem ]struct {}),
115
+ allPartitionStats : make (map [int64 ]* statistics.Table ),
116
+ globalTableInfo : globalTableInfo ,
117
+ histIDs : histIDs ,
118
+ is : is ,
119
+ partitionNum : partitionNum ,
114
120
}, nil
115
121
}
116
122
@@ -218,25 +224,32 @@ func (a *AsyncMergePartitionStats2GlobalStats) dealErrPartitionColumnStatsMissin
218
224
func (a * AsyncMergePartitionStats2GlobalStats ) ioWorker (sctx sessionctx.Context , isIndex bool ) (err error ) {
219
225
defer func () {
220
226
if r := recover (); r != nil {
221
- close (a .exitWhenErrChan )
227
+ logutil .BgLogger ().Warn ("ioWorker panic" , zap .Stack ("stack" ), zap .Any ("error" , r ), zap .String ("category" , "stats" ))
228
+ close (a .ioWorkerExitWhenErrChan )
222
229
err = errors .New (fmt .Sprint (r ))
223
230
}
224
231
}()
225
232
err = a .loadFmsketch (sctx , isIndex )
226
233
if err != nil {
227
- close (a .exitWhenErrChan )
234
+ close (a .ioWorkerExitWhenErrChan )
228
235
return err
229
236
}
230
237
close (a .fmsketch )
231
238
err = a .loadCMsketch (sctx , isIndex )
232
239
if err != nil {
233
- close (a .exitWhenErrChan )
240
+ close (a .ioWorkerExitWhenErrChan )
234
241
return err
235
242
}
236
243
close (a .cmsketch )
244
+ failpoint .Inject ("PanicSameTime" , func (val failpoint.Value ) {
245
+ if val , _ := val .(bool ); val {
246
+ time .Sleep (1 * time .Second )
247
+ panic ("test for PanicSameTime" )
248
+ }
249
+ })
237
250
err = a .loadHistogramAndTopN (sctx , a .globalTableInfo , isIndex )
238
251
if err != nil {
239
- close (a .exitWhenErrChan )
252
+ close (a .ioWorkerExitWhenErrChan )
240
253
return err
241
254
}
242
255
close (a .histogramAndTopn )
@@ -246,13 +259,14 @@ func (a *AsyncMergePartitionStats2GlobalStats) ioWorker(sctx sessionctx.Context,
246
259
func (a * AsyncMergePartitionStats2GlobalStats ) cpuWorker (stmtCtx * stmtctx.StatementContext , sctx sessionctx.Context , opts map [ast.AnalyzeOptionType ]uint64 , isIndex bool , tz * time.Location , analyzeVersion int ) (err error ) {
247
260
defer func () {
248
261
if r := recover (); r != nil {
249
- close ( a . exitWhenErrChan )
262
+ logutil . BgLogger (). Warn ( "cpuWorker panic" , zap . Stack ( "stack" ), zap . Any ( "error" , r ), zap . String ( "category" , "stats" ) )
250
263
err = errors .New (fmt .Sprint (r ))
251
264
}
265
+ close (a .cpuWorkerExitChan )
252
266
}()
253
267
a .dealFMSketch ()
254
268
select {
255
- case <- a .exitWhenErrChan :
269
+ case <- a .ioWorkerExitWhenErrChan :
256
270
return nil
257
271
default :
258
272
for i := 0 ; i < a .globalStats .Num ; i ++ {
@@ -267,10 +281,18 @@ func (a *AsyncMergePartitionStats2GlobalStats) cpuWorker(stmtCtx *stmtctx.Statem
267
281
}
268
282
err = a .dealCMSketch ()
269
283
if err != nil {
284
+ logutil .BgLogger ().Warn ("dealCMSketch failed" , zap .Error (err ), zap .String ("category" , "stats" ))
270
285
return err
271
286
}
287
+ failpoint .Inject ("PanicSameTime" , func (val failpoint.Value ) {
288
+ if val , _ := val .(bool ); val {
289
+ time .Sleep (1 * time .Second )
290
+ panic ("test for PanicSameTime" )
291
+ }
292
+ })
272
293
err = a .dealHistogramAndTopN (stmtCtx , sctx , opts , isIndex , tz , analyzeVersion )
273
294
if err != nil {
295
+ logutil .BgLogger ().Warn ("dealHistogramAndTopN failed" , zap .Error (err ), zap .String ("category" , "stats" ))
274
296
return err
275
297
}
276
298
return nil
@@ -337,7 +359,8 @@ func (a *AsyncMergePartitionStats2GlobalStats) loadFmsketch(sctx sessionctx.Cont
337
359
case a .fmsketch <- mergeItem [* statistics.FMSketch ]{
338
360
fmsketch , i ,
339
361
}:
340
- case <- a .exitWhenErrChan :
362
+ case <- a .cpuWorkerExitChan :
363
+ logutil .BgLogger ().Warn ("ioWorker detects CPUWorker has exited" , zap .String ("category" , "stats" ))
341
364
return nil
342
365
}
343
366
}
@@ -367,7 +390,8 @@ func (a *AsyncMergePartitionStats2GlobalStats) loadCMsketch(sctx sessionctx.Cont
367
390
case a .cmsketch <- mergeItem [* statistics.CMSketch ]{
368
391
cmsketch , i ,
369
392
}:
370
- case <- a .exitWhenErrChan :
393
+ case <- a .cpuWorkerExitChan :
394
+ logutil .BgLogger ().Warn ("ioWorker detects CPUWorker has exited" , zap .String ("category" , "stats" ))
371
395
return nil
372
396
}
373
397
}
@@ -376,6 +400,12 @@ func (a *AsyncMergePartitionStats2GlobalStats) loadCMsketch(sctx sessionctx.Cont
376
400
}
377
401
378
402
func (a * AsyncMergePartitionStats2GlobalStats ) loadHistogramAndTopN (sctx sessionctx.Context , tableInfo * model.TableInfo , isIndex bool ) error {
403
+ failpoint .Inject ("ErrorSameTime" , func (val failpoint.Value ) {
404
+ if val , _ := val .(bool ); val {
405
+ time .Sleep (1 * time .Second )
406
+ failpoint .Return (errors .New ("ErrorSameTime returned error" ))
407
+ }
408
+ })
379
409
for i := 0 ; i < a .globalStats .Num ; i ++ {
380
410
hists := make ([]* statistics.Histogram , 0 , a .partitionNum )
381
411
topn := make ([]* statistics.TopN , 0 , a .partitionNum )
@@ -402,7 +432,8 @@ func (a *AsyncMergePartitionStats2GlobalStats) loadHistogramAndTopN(sctx session
402
432
case a .histogramAndTopn <- mergeItem [* StatsWrapper ]{
403
433
NewStatsWrapper (hists , topn ), i ,
404
434
}:
405
- case <- a .exitWhenErrChan :
435
+ case <- a .cpuWorkerExitChan :
436
+ logutil .BgLogger ().Warn ("ioWorker detects CPUWorker has exited" , zap .String ("category" , "stats" ))
406
437
return nil
407
438
}
408
439
}
@@ -422,13 +453,18 @@ func (a *AsyncMergePartitionStats2GlobalStats) dealFMSketch() {
422
453
} else {
423
454
a .globalStats .Fms [fms .idx ].MergeFMSketch (fms .item )
424
455
}
425
- case <- a .exitWhenErrChan :
456
+ case <- a .ioWorkerExitWhenErrChan :
426
457
return
427
458
}
428
459
}
429
460
}
430
461
431
462
func (a * AsyncMergePartitionStats2GlobalStats ) dealCMSketch () error {
463
+ failpoint .Inject ("dealCMSketchErr" , func (val failpoint.Value ) {
464
+ if val , _ := val .(bool ); val {
465
+ failpoint .Return (errors .New ("dealCMSketch returned error" ))
466
+ }
467
+ })
432
468
for {
433
469
select {
434
470
case cms , ok := <- a .cmsketch :
@@ -443,13 +479,24 @@ func (a *AsyncMergePartitionStats2GlobalStats) dealCMSketch() error {
443
479
return err
444
480
}
445
481
}
446
- case <- a .exitWhenErrChan :
482
+ case <- a .ioWorkerExitWhenErrChan :
447
483
return nil
448
484
}
449
485
}
450
486
}
451
487
452
488
func (a * AsyncMergePartitionStats2GlobalStats ) dealHistogramAndTopN (stmtCtx * stmtctx.StatementContext , sctx sessionctx.Context , opts map [ast.AnalyzeOptionType ]uint64 , isIndex bool , tz * time.Location , analyzeVersion int ) (err error ) {
489
+ failpoint .Inject ("dealHistogramAndTopNErr" , func (val failpoint.Value ) {
490
+ if val , _ := val .(bool ); val {
491
+ failpoint .Return (errors .New ("dealHistogramAndTopNErr returned error" ))
492
+ }
493
+ })
494
+ failpoint .Inject ("ErrorSameTime" , func (val failpoint.Value ) {
495
+ if val , _ := val .(bool ); val {
496
+ time .Sleep (1 * time .Second )
497
+ failpoint .Return (errors .New ("ErrorSameTime returned error" ))
498
+ }
499
+ })
453
500
for {
454
501
select {
455
502
case item , ok := <- a .histogramAndTopn :
@@ -478,7 +525,7 @@ func (a *AsyncMergePartitionStats2GlobalStats) dealHistogramAndTopN(stmtCtx *stm
478
525
a .globalStats .Hg [item .idx ].Buckets [j ].NDV = 0
479
526
}
480
527
a .globalStats .Hg [item .idx ].NDV = a .globalStatsNDV [item .idx ]
481
- case <- a .exitWhenErrChan :
528
+ case <- a .ioWorkerExitWhenErrChan :
482
529
return nil
483
530
}
484
531
}
0 commit comments