diff --git a/executor/analyze.go b/executor/analyze.go index 4a16ba9ed07e7..821b7d0626398 100644 --- a/executor/analyze.go +++ b/executor/analyze.go @@ -42,6 +42,7 @@ import ( "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/dbterror/exeerrors" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tidb/util/sqlexec" "github.com/pingcap/tipb/go-tipb" "go.uber.org/zap" @@ -184,7 +185,7 @@ func (e *AnalyzeExec) Next(ctx context.Context, _ *chunk.Chunk) error { // needGlobalStats used to indicate whether we should merge the partition-level stats to global-level stats. needGlobalStats := pruneMode == variable.Dynamic globalStatsMap := make(map[globalStatsKey]globalStatsInfo) - err = e.handleResultsError(ctx, concurrency, needGlobalStats, globalStatsMap, resultsCh) + err = e.handleResultsError(ctx, concurrency, needGlobalStats, globalStatsMap, resultsCh, len(tasks)) for _, task := range tasks { if task.colExec != nil && task.colExec.memTracker != nil { task.colExec.memTracker.Detach() @@ -275,10 +276,18 @@ func recordHistoricalStats(sctx sessionctx.Context, tableID int64) error { } // handleResultsError will handle the error fetch from resultsCh and record it in log -func (e *AnalyzeExec) handleResultsError(ctx context.Context, concurrency int, needGlobalStats bool, - globalStatsMap globalStatsMap, resultsCh <-chan *statistics.AnalyzeResults) error { +func (e *AnalyzeExec) handleResultsError( + ctx context.Context, + concurrency int, + needGlobalStats bool, + globalStatsMap globalStatsMap, + resultsCh <-chan *statistics.AnalyzeResults, + taskNum int, +) error { partitionStatsConcurrency := e.ctx.GetSessionVars().AnalyzePartitionConcurrency - // If 'partitionStatsConcurrency' > 1, we will try to demand extra session from Domain to save Analyze results in concurrency. + // the concurrency of handleResultsError cannot be more than partitionStatsConcurrency + partitionStatsConcurrency = mathutil.Min(taskNum, partitionStatsConcurrency) + // If partitionStatsConcurrency > 1, we will try to demand extra session from Domain to save Analyze results in concurrency. // If there is no extra session we can use, we will save analyze results in single-thread. if partitionStatsConcurrency > 1 { dom := domain.GetDomain(e.ctx)