From 99765e13e3a56a8b684d1879b419d59c6d5cbacc Mon Sep 17 00:00:00 2001 From: Haibin Xie Date: Tue, 11 Jun 2019 19:24:02 +0800 Subject: [PATCH 1/4] domain: add a config to control updating stats --- config/config.go | 2 ++ config/config.toml.example | 3 ++ domain/domain.go | 68 +++++++++++++++++++++++--------------- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/config/config.go b/config/config.go index bc7ecedd073a6..fd3a1f0f1b209 100644 --- a/config/config.go +++ b/config/config.go @@ -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"` + UpdateStats bool `toml:"update-stats" json:"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"` @@ -321,6 +322,7 @@ var defaultConf = Config{ TCPKeepAlive: true, CrossJoin: true, StatsLease: "3s", + UpdateStats: true, RunAutoAnalyze: true, StmtCountLimit: 5000, FeedbackProbability: 0.05, diff --git a/config/config.toml.example b/config/config.toml.example index a1c236d5a1d3c..a0d89b5a0fe6d 100644 --- a/config/config.toml.example +++ b/config/config.toml.example @@ -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. +update-stats = true + # Run auto analyze worker on this tidb-server. run-auto-analyze = true diff --git a/domain/domain.go b/domain/domain.go index dfc91dbf622f5..8d54e8981b043 100644 --- a/domain/domain.go +++ b/domain/domain.go @@ -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.UpdateStats { + return nil + } owner := do.newStatsOwner() do.wg.Add(1) do.SetStatsUpdating(true) @@ -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()) @@ -889,10 +884,6 @@ 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: @@ -900,37 +891,60 @@ func (do *Domain) updateStatsWorker(ctx sessionctx.Context, owner owner.Manager) 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)) } @@ -938,7 +952,7 @@ func (do *Domain) updateStatsWorker(ctx sessionctx.Context, owner owner.Manager) 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)) } From dd3cd392aff5fa6ec02986b829dba410ed242a99 Mon Sep 17 00:00:00 2001 From: Haibin Xie Date: Wed, 12 Jun 2019 12:30:40 +0800 Subject: [PATCH 2/4] address comments --- config/config.go | 4 ++-- config/config.toml.example | 4 ++-- domain/domain.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/config.go b/config/config.go index fd3a1f0f1b209..f8248398f64cb 100644 --- a/config/config.go +++ b/config/config.go @@ -176,7 +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"` - UpdateStats bool `toml:"update-stats" json:"update-stats"` + 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"` @@ -322,7 +322,7 @@ var defaultConf = Config{ TCPKeepAlive: true, CrossJoin: true, StatsLease: "3s", - UpdateStats: true, + EnableUpdateStats: true, RunAutoAnalyze: true, StmtCountLimit: 5000, FeedbackProbability: 0.05, diff --git a/config/config.toml.example b/config/config.toml.example index a0d89b5a0fe6d..e1911df3cd7ba 100644 --- a/config/config.toml.example +++ b/config/config.toml.example @@ -143,8 +143,8 @@ 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. -update-stats = true +# Whether run stats updates on this tidb-server. It will only updates stats when stats-lease is non-zero. +enable-update-stats = true # Run auto analyze worker on this tidb-server. run-auto-analyze = true diff --git a/domain/domain.go b/domain/domain.go index 8d54e8981b043..1f779350d500e 100644 --- a/domain/domain.go +++ b/domain/domain.go @@ -839,7 +839,7 @@ func (do *Domain) UpdateTableStatsLoop(ctx sessionctx.Context) error { } do.wg.Add(1) go do.loadStatsWorker() - if !config.GetGlobalConfig().Performance.UpdateStats { + if !config.GetGlobalConfig().Performance.EnableUpdateStats { return nil } owner := do.newStatsOwner() From e652ca1113c5320c03a730bd8fdfc7d998cb54e6 Mon Sep 17 00:00:00 2001 From: Haibin Xie Date: Wed, 12 Jun 2019 13:42:01 +0800 Subject: [PATCH 3/4] address comments --- config/config.toml.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.toml.example b/config/config.toml.example index e1911df3cd7ba..6a84285d2fa57 100644 --- a/config/config.toml.example +++ b/config/config.toml.example @@ -143,7 +143,7 @@ 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 only updates stats when stats-lease is non-zero. +# Whether run stats updates on this tidb-server. It will updates stats only when stats-lease is non-zero. enable-update-stats = true # Run auto analyze worker on this tidb-server. From bac22e84c2a166fda77d69d85d93261e326018bd Mon Sep 17 00:00:00 2001 From: Haibin Xie Date: Wed, 12 Jun 2019 16:45:24 +0800 Subject: [PATCH 4/4] address comment --- config/config.toml.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.toml.example b/config/config.toml.example index 6a84285d2fa57..8c04c46cde3ca 100644 --- a/config/config.toml.example +++ b/config/config.toml.example @@ -143,7 +143,7 @@ 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 updates stats only when stats-lease is non-zero. +# 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.