Skip to content

Commit

Permalink
domain: add a config to control updating stats (#10772)
Browse files Browse the repository at this point in the history
  • Loading branch information
alivxxx authored and zz-jason committed Jun 19, 2019
1 parent f185720 commit daa2a08
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 27 deletions.
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ type Performance struct {
TCPKeepAlive bool `toml:"tcp-keep-alive" json:"tcp-keep-alive"`
CrossJoin bool `toml:"cross-join" json:"cross-join"`
StatsLease string `toml:"stats-lease" json:"stats-lease"`
EnableUpdateStats bool `toml:"enable-update-stats" json:"enable-update-stats"`
RunAutoAnalyze bool `toml:"run-auto-analyze" json:"run-auto-analyze"`
StmtCountLimit uint `toml:"stmt-count-limit" json:"stmt-count-limit"`
FeedbackProbability float64 `toml:"feedback-probability" json:"feedback-probability"`
Expand Down Expand Up @@ -321,6 +322,7 @@ var defaultConf = Config{
TCPKeepAlive: true,
CrossJoin: true,
StatsLease: "3s",
EnableUpdateStats: true,
RunAutoAnalyze: true,
StmtCountLimit: 5000,
FeedbackProbability: 0.05,
Expand Down
3 changes: 3 additions & 0 deletions config/config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ cross-join = true
# Stats lease duration, which influences the time of analyze and stats load.
stats-lease = "3s"

# Whether run stats updates on this tidb-server. It will use the value of `stats-lease` to set its tickers' values, so it won't work when `stats-lease` is zero.
enable-update-stats = true

# Run auto analyze worker on this tidb-server.
run-auto-analyze = true

Expand Down
68 changes: 41 additions & 27 deletions domain/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,11 @@ func (do *Domain) UpdateTableStatsLoop(ctx sessionctx.Context) error {
if do.statsLease <= 0 {
return nil
}
do.wg.Add(1)
go do.loadStatsWorker()
if !config.GetGlobalConfig().Performance.EnableUpdateStats {
return nil
}
owner := do.newStatsOwner()
do.wg.Add(1)
do.SetStatsUpdating(true)
Expand Down Expand Up @@ -865,22 +870,12 @@ func (do *Domain) newStatsOwner() owner.Manager {
return statsOwner
}

func (do *Domain) updateStatsWorker(ctx sessionctx.Context, owner owner.Manager) {
defer recoverInDomain("updateStatsWorker", false)
func (do *Domain) loadStatsWorker() {
defer recoverInDomain("loadStatsWorker", false)
defer do.wg.Done()
lease := do.statsLease
deltaUpdateDuration := lease * 20
loadTicker := time.NewTicker(lease)
defer loadTicker.Stop()
deltaUpdateTicker := time.NewTicker(deltaUpdateDuration)
defer deltaUpdateTicker.Stop()
loadHistogramTicker := time.NewTicker(lease)
defer loadHistogramTicker.Stop()
gcStatsTicker := time.NewTicker(100 * lease)
defer gcStatsTicker.Stop()
dumpFeedbackTicker := time.NewTicker(200 * lease)
defer dumpFeedbackTicker.Stop()
loadFeedbackTicker := time.NewTicker(5 * lease)
defer loadFeedbackTicker.Stop()
statsHandle := do.StatsHandle()
t := time.Now()
err := statsHandle.InitStats(do.InfoSchema())
Expand All @@ -889,56 +884,75 @@ func (do *Domain) updateStatsWorker(ctx sessionctx.Context, owner owner.Manager)
} else {
logutil.Logger(context.Background()).Info("init stats info time", zap.Duration("take time", time.Since(t)))
}
defer func() {
do.SetStatsUpdating(false)
do.wg.Done()
}()
for {
select {
case <-loadTicker.C:
err = statsHandle.Update(do.InfoSchema())
if err != nil {
logutil.Logger(context.Background()).Debug("update stats info failed", zap.Error(err))
}
err = statsHandle.LoadNeededHistograms()
if err != nil {
logutil.Logger(context.Background()).Debug("load histograms failed", zap.Error(err))
}
case <-do.exit:
return
}
}
}

func (do *Domain) updateStatsWorker(ctx sessionctx.Context, owner owner.Manager) {
defer recoverInDomain("updateStatsWorker", false)
lease := do.statsLease
deltaUpdateTicker := time.NewTicker(20 * lease)
defer deltaUpdateTicker.Stop()
gcStatsTicker := time.NewTicker(100 * lease)
defer gcStatsTicker.Stop()
dumpFeedbackTicker := time.NewTicker(200 * lease)
defer dumpFeedbackTicker.Stop()
loadFeedbackTicker := time.NewTicker(5 * lease)
defer loadFeedbackTicker.Stop()
statsHandle := do.StatsHandle()
defer func() {
do.SetStatsUpdating(false)
do.wg.Done()
}()
for {
select {
case <-do.exit:
statsHandle.FlushStats()
return
// This channel is sent only by ddl owner.
case t := <-statsHandle.DDLEventCh():
err = statsHandle.HandleDDLEvent(t)
err := statsHandle.HandleDDLEvent(t)
if err != nil {
logutil.Logger(context.Background()).Debug("handle ddl event failed", zap.Error(err))
}
case <-deltaUpdateTicker.C:
err = statsHandle.DumpStatsDeltaToKV(statistics.DumpDelta)
err := statsHandle.DumpStatsDeltaToKV(statistics.DumpDelta)
if err != nil {
logutil.Logger(context.Background()).Debug("dump stats delta failed", zap.Error(err))
}
statsHandle.UpdateErrorRate(do.InfoSchema())
case <-loadHistogramTicker.C:
err = statsHandle.LoadNeededHistograms()
if err != nil {
logutil.Logger(context.Background()).Debug("load histograms failed", zap.Error(err))
}
case <-loadFeedbackTicker.C:
statsHandle.UpdateStatsByLocalFeedback(do.InfoSchema())
if !owner.IsOwner() {
continue
}
err = statsHandle.HandleUpdateStats(do.InfoSchema())
err := statsHandle.HandleUpdateStats(do.InfoSchema())
if err != nil {
logutil.Logger(context.Background()).Debug("update stats using feedback failed", zap.Error(err))
}
case <-dumpFeedbackTicker.C:
err = statsHandle.DumpStatsFeedbackToKV()
err := statsHandle.DumpStatsFeedbackToKV()
if err != nil {
logutil.Logger(context.Background()).Debug("dump stats feedback failed", zap.Error(err))
}
case <-gcStatsTicker.C:
if !owner.IsOwner() {
continue
}
err = statsHandle.GCStats(do.InfoSchema(), do.DDL().GetLease())
err := statsHandle.GCStats(do.InfoSchema(), do.DDL().GetLease())
if err != nil {
logutil.Logger(context.Background()).Debug("GC stats failed", zap.Error(err))
}
Expand Down

0 comments on commit daa2a08

Please sign in to comment.