diff --git a/pkg/domain/domain.go b/pkg/domain/domain.go index 749b759f760a0..47d200321e32d 100644 --- a/pkg/domain/domain.go +++ b/pkg/domain/domain.go @@ -2288,6 +2288,7 @@ func (do *Domain) UpdateTableStatsLoop(ctx, initStatsCtx sessionctx.Context) err return nil } do.SetStatsUpdating(true) + do.wg.Run(do.asyncLoadHistogram, "asyncLoadHistogram") // The stats updated worker doesn't require the stats initialization to be completed. // This is because the updated worker's primary responsibilities are to update the change delta and handle DDL operations. // These tasks do not interfere with or depend on the initialization process. @@ -2409,6 +2410,33 @@ func (do *Domain) loadStatsWorker() { if err != nil { logutil.BgLogger().Warn("update stats info failed", zap.Error(err)) } + case <-do.exit: + return + } + } +} + +func (do *Domain) asyncLoadHistogram() { + defer util.Recover(metrics.LabelDomain, "asyncLoadStats", nil, false) + lease := do.statsLease + if lease == 0 { + lease = 3 * time.Second + } + cleanupTicker := time.NewTicker(lease) + defer func() { + cleanupTicker.Stop() + logutil.BgLogger().Info("asyncLoadStats exited.") + }() + select { + case <-do.StatsHandle().InitStatsDone: + case <-do.exit: // It may happen that before initStatsDone, tidb receive Ctrl+C + return + } + statsHandle := do.StatsHandle() + var err error + for { + select { + case <-cleanupTicker.C: err = statsHandle.LoadNeededHistograms() if err != nil { logutil.BgLogger().Warn("load histograms failed", zap.Error(err))