From 0fbb980f9b9166ee7afebef88732ffebfc287a38 Mon Sep 17 00:00:00 2001 From: Haibin Xie Date: Tue, 26 Jun 2018 13:51:23 +0800 Subject: [PATCH] stats: refine stats delta update (#6808) --- domain/domain.go | 3 +- executor/show_stats_test.go | 7 +-- infoschema/tables_test.go | 9 ++-- plan/cbo_test.go | 13 +++--- server/statistics_handler_test.go | 5 ++- sessionctx/variable/session.go | 7 +-- statistics/dump_test.go | 3 +- statistics/handle.go | 24 ++++++++++ statistics/handle_test.go | 2 +- statistics/update.go | 45 ++++++++++++++++++- statistics/update_list_test.go | 4 +- statistics/update_test.go | 73 +++++++++++++++++++++---------- 12 files changed, 147 insertions(+), 48 deletions(-) diff --git a/domain/domain.go b/domain/domain.go index 43cc6213ef..254c96bda2 100644 --- a/domain/domain.go +++ b/domain/domain.go @@ -660,6 +660,7 @@ func (do *Domain) updateStatsWorker(ctx sessionctx.Context, owner owner.Manager) log.Debug("[stats] update stats info fail: ", errors.ErrorStack(err)) } case <-do.exit: + statsHandle.FlushStats() do.wg.Done() return // This channel is sent only by ddl owner or the drop stats executor. @@ -681,7 +682,7 @@ func (do *Domain) updateStatsWorker(ctx sessionctx.Context, owner owner.Manager) log.Debug("[stats] save meta to storage fail: ", errors.ErrorStack(err)) } case <-deltaUpdateTicker.C: - err = statsHandle.DumpStatsDeltaToKV() + err = statsHandle.DumpStatsDeltaToKV(statistics.DumpDelta) if err != nil { log.Debug("[stats] dump stats delta fail: ", errors.ErrorStack(err)) } diff --git a/executor/show_stats_test.go b/executor/show_stats_test.go index 324d818a90..03ddf98909 100644 --- a/executor/show_stats_test.go +++ b/executor/show_stats_test.go @@ -16,6 +16,7 @@ package executor_test import ( . "github.com/pingcap/check" "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/util/testkit" ) @@ -74,17 +75,17 @@ func (s *testSuite) TestShowStatsHealthy(c *C) { tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 100")) tk.MustExec("insert into t values (1), (2)") do, _ := session.GetDomain(s.store) - do.StatsHandle().DumpStatsDeltaToKV() + do.StatsHandle().DumpStatsDeltaToKV(statistics.DumpAll) tk.MustExec("analyze table t") tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 100")) tk.MustExec("insert into t values (3), (4), (5), (6), (7), (8), (9), (10)") - do.StatsHandle().DumpStatsDeltaToKV() + do.StatsHandle().DumpStatsDeltaToKV(statistics.DumpAll) do.StatsHandle().Update(do.InfoSchema()) tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 19")) tk.MustExec("analyze table t") tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 100")) tk.MustExec("delete from t") - do.StatsHandle().DumpStatsDeltaToKV() + do.StatsHandle().DumpStatsDeltaToKV(statistics.DumpAll) do.StatsHandle().Update(do.InfoSchema()) tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 0")) } diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 047af35958..6067b4df9b 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -16,6 +16,7 @@ package infoschema_test import ( . "github.com/pingcap/check" "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/util/auth" "github.com/pingcap/tidb/util/testkit" @@ -42,22 +43,22 @@ func (s *testSuite) TestDataForTableRowsCountField(c *C) { tk.MustQuery("select table_rows from information_schema.tables where table_name='t'").Check( testkit.Rows("0")) tk.MustExec("insert into t(c, d) values(1, 2), (2, 3), (3, 4)") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) tk.MustQuery("select table_rows from information_schema.tables where table_name='t'").Check( testkit.Rows("3")) tk.MustExec("insert into t(c, d) values(4, 5)") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) tk.MustQuery("select table_rows from information_schema.tables where table_name='t'").Check( testkit.Rows("4")) tk.MustExec("delete from t where c >= 3") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) tk.MustQuery("select table_rows from information_schema.tables where table_name='t'").Check( testkit.Rows("2")) tk.MustExec("delete from t where c=3") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) tk.MustQuery("select table_rows from information_schema.tables where table_name='t'").Check( testkit.Rows("2")) diff --git a/plan/cbo_test.go b/plan/cbo_test.go index 9abfccd35f..b5cd9555c4 100644 --- a/plan/cbo_test.go +++ b/plan/cbo_test.go @@ -25,6 +25,7 @@ import ( "github.com/pingcap/tidb/plan" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx" + "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/util/testkit" "github.com/pingcap/tidb/util/testleak" @@ -53,7 +54,7 @@ func (s *testAnalyzeSuite) TestCBOWithoutAnalyze(c *C) { c.Assert(h.HandleDDLEvent(<-h.DDLEventCh()), IsNil) testKit.MustExec("insert into t1 values (1), (2), (3), (4), (5), (6)") testKit.MustExec("insert into t2 values (1), (2), (3), (4), (5), (6)") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) c.Assert(h.Update(dom.InfoSchema()), IsNil) testKit.MustQuery("explain select * from t1, t2 where t1.a = t2.a").Check(testkit.Rows( "TableScan_10 cop table:t1, range:[-inf,+inf], keep order:false 6.00", @@ -139,7 +140,7 @@ func (s *testAnalyzeSuite) TestTableDual(c *C) { testKit.MustExec("insert into t values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)") c.Assert(h.HandleDDLEvent(<-h.DDLEventCh()), IsNil) - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) c.Assert(h.Update(dom.InfoSchema()), IsNil) testKit.MustQuery(`explain select * from t where 1 = 0`).Check(testkit.Rows( @@ -170,12 +171,12 @@ func (s *testAnalyzeSuite) TestEstimation(c *C) { testKit.MustExec("insert into t select * from t") h := dom.StatsHandle() h.HandleDDLEvent(<-h.DDLEventCh()) - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) testKit.MustExec("analyze table t") for i := 1; i <= 8; i++ { testKit.MustExec("delete from t where a = ?", i) } - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) c.Assert(h.Update(dom.InfoSchema()), IsNil) testKit.MustQuery("explain select count(*) from t group by a").Check(testkit.Rows( "TableScan_8 HashAgg_5 cop table:t, range:[-inf,+inf], keep order:false 8.00", @@ -486,12 +487,12 @@ func (s *testAnalyzeSuite) TestOutdatedAnalyze(c *C) { } h := dom.StatsHandle() h.HandleDDLEvent(<-h.DDLEventCh()) - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) testKit.MustExec("analyze table t") testKit.MustExec("insert into t select * from t") testKit.MustExec("insert into t select * from t") testKit.MustExec("insert into t select * from t") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) c.Assert(h.Update(dom.InfoSchema()), IsNil) plan.RatioOfPseudoEstimate = 10.0 testKit.MustQuery("explain select * from t where a <= 5 and b <= 5").Check(testkit.Rows( diff --git a/server/statistics_handler_test.go b/server/statistics_handler_test.go index 4e70c88e40..33f1ab700a 100644 --- a/server/statistics_handler_test.go +++ b/server/statistics_handler_test.go @@ -27,6 +27,7 @@ import ( "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/store/mockstore/mocktikv" ) @@ -118,11 +119,11 @@ func (ds *testDumpStatsSuite) prepareData(c *C) { h.HandleDDLEvent(<-h.DDLEventCh()) dbt.mustExec("create index c on test (a, b)") dbt.mustExec("insert test values (1, 's')") - c.Assert(h.DumpStatsDeltaToKV(), IsNil) + c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil) dbt.mustExec("analyze table test") dbt.mustExec("insert into test(a,b) values (1, 'v'),(3, 'vvv'),(5, 'vv')") is := ds.sh.do.InfoSchema() - c.Assert(h.DumpStatsDeltaToKV(), IsNil) + c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil) c.Assert(h.Update(is), IsNil) } diff --git a/sessionctx/variable/session.go b/sessionctx/variable/session.go index eb999254de..bf04361ba8 100644 --- a/sessionctx/variable/session.go +++ b/sessionctx/variable/session.go @@ -561,9 +561,10 @@ const ( // TableDelta stands for the changed count for one table. type TableDelta struct { - Delta int64 - Count int64 - ColSize map[int64]int64 + Delta int64 + Count int64 + ColSize map[int64]int64 + InitTime time.Time // InitTime is the time that this delta is generated. } // Concurrency defines concurrency values. diff --git a/statistics/dump_test.go b/statistics/dump_test.go index c631d5ef5e..44474db803 100644 --- a/statistics/dump_test.go +++ b/statistics/dump_test.go @@ -18,6 +18,7 @@ import ( "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/model" + "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/util/testkit" "github.com/pingcap/tidb/util/testleak" ) @@ -54,7 +55,7 @@ func (s *testDumpStatsSuite) TestConversion(c *C) { tk.MustExec("insert into t(a,b) values (1, 1),(3, 1),(5, 10)") is := s.do.InfoSchema() h := s.do.StatsHandle() - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) tableInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) diff --git a/statistics/handle.go b/statistics/handle.go index 784dea828c..4636cc9731 100644 --- a/statistics/handle.go +++ b/statistics/handle.go @@ -214,3 +214,27 @@ func (h *Handle) LoadNeededHistograms() error { func (h *Handle) LoadMetaCh() chan *LoadMeta { return h.loadMetaCh } + +// FlushStats flushes the cached stats update into store. +func (h *Handle) FlushStats() { + for len(h.ddlEventCh) > 0 { + e := <-h.ddlEventCh + if err := h.HandleDDLEvent(e); err != nil { + log.Debug("[stats] handle ddl event fail: ", errors.ErrorStack(err)) + } + } + if err := h.DumpStatsDeltaToKV(DumpAll); err != nil { + log.Debug("[stats] dump stats delta fail: ", errors.ErrorStack(err)) + } + for len(h.analyzeResultCh) > 0 { + t := <-h.analyzeResultCh + for i, hg := range t.Hist { + if err := SaveStatsToStorage(h.ctx, t.TableID, t.Count, t.IsIndex, hg, t.Cms[i]); err != nil { + log.Debug("[stats] save histogram to storage fail: ", errors.ErrorStack(err)) + } + } + } + if err := h.DumpStatsFeedbackToKV(); err != nil { + log.Debug("[stats] dump stats feedback fail: ", errors.ErrorStack(err)) + } +} diff --git a/statistics/handle_test.go b/statistics/handle_test.go index 68647c58c1..7241de263c 100644 --- a/statistics/handle_test.go +++ b/statistics/handle_test.go @@ -339,7 +339,7 @@ func (s *testStatsCacheSuite) TestLoadHist(c *C) { for i := 0; i < rowCount; i++ { testKit.MustExec("insert into t values('bb','sdfga')") } - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(do.InfoSchema()) newStatsTbl := h.GetTableStats(tableInfo) // The stats table is updated. diff --git a/statistics/update.go b/statistics/update.go index f42aa33929..69b32b6043 100644 --- a/statistics/update.go +++ b/statistics/update.go @@ -156,15 +156,56 @@ func (h *Handle) NewSessionStatsCollector() *SessionStatsCollector { return newCollector } -// DumpStatsDeltaToKV sweeps the whole list and updates the global map. Then we dumps every table that held in map to KV. -func (h *Handle) DumpStatsDeltaToKV() error { +var ( + // DumpStatsDeltaRatio is the lower bound of `Modify Count / Table Count` for stats delta to be dumped. + DumpStatsDeltaRatio = 1 / 10000.0 + // dumpStatsMaxDuration is the max duration since last update. + dumpStatsMaxDuration = time.Hour +) + +// needDumpStatsDelta returns true when only updates a small portion of the table and the time since last update +// do not exceed one hour. +func needDumpStatsDelta(h *Handle, id int64, item variable.TableDelta, currentTime time.Time) bool { + if item.InitTime.IsZero() { + item.InitTime = currentTime + } + tbl, ok := h.statsCache.Load().(statsCache)[id] + if !ok { + // No need to dump if the stats is invalid. + return false + } + if currentTime.Sub(item.InitTime) > dumpStatsMaxDuration { + // Dump the stats to kv at least once an hour. + return true + } + if tbl.Count == 0 || float64(item.Count)/float64(tbl.Count) > DumpStatsDeltaRatio { + // Dump the stats when there are many modifications. + return true + } + return false +} + +const ( + // DumpAll indicates dump all the delta info in to kv + DumpAll = true + // DumpDelta indicates dump part of the delta info in to kv. + DumpDelta = false +) + +// DumpStatsDeltaToKV sweeps the whole list and updates the global map, then we dumps every table that held in map to KV. +// If the `dumpAll` is false, it will only dump that delta info that `Modify Count / Table Count` greater than a ratio. +func (h *Handle) DumpStatsDeltaToKV(dumpMode bool) error { h.listHead.Lock() for collector := h.listHead.next; collector != nil; collector = collector.next { collector.tryToRemoveFromList() h.merge(collector) } h.listHead.Unlock() + currentTime := time.Now() for id, item := range h.globalMap { + if dumpMode == DumpDelta && !needDumpStatsDelta(h, id, item, currentTime) { + continue + } updated, err := h.dumpTableStatCountToKV(id, item) if err != nil { return errors.Trace(err) diff --git a/statistics/update_list_test.go b/statistics/update_list_test.go index 36aea92f08..366b134591 100644 --- a/statistics/update_list_test.go +++ b/statistics/update_list_test.go @@ -31,7 +31,7 @@ func (s *testUpdateListSuite) TestInsertAndDelete(c *C) { items[0].Delete() // delete tail items[2].Delete() // delete middle items[4].Delete() // delete head - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(DumpAll) c.Assert(h.listHead.next, Equals, items[3]) c.Assert(items[3].next, Equals, items[1]) @@ -42,6 +42,6 @@ func (s *testUpdateListSuite) TestInsertAndDelete(c *C) { // delete rest items[1].Delete() items[3].Delete() - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(DumpAll) c.Assert(h.listHead.next, IsNil) } diff --git a/statistics/update_test.go b/statistics/update_test.go index 8fd7cdf2b7..2a28e76b5f 100644 --- a/statistics/update_test.go +++ b/statistics/update_test.go @@ -75,7 +75,7 @@ func (s *testStatsUpdateSuite) TestSingleSessionInsert(c *C) { h.HandleDDLEvent(<-h.DDLEventCh()) h.HandleDDLEvent(<-h.DDLEventCh()) - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats1 := h.GetTableStats(tableInfo1) c.Assert(stats1.Count, Equals, int64(rowCount1)) @@ -91,7 +91,7 @@ func (s *testStatsUpdateSuite) TestSingleSessionInsert(c *C) { for i := 0; i < rowCount1; i++ { testKit.MustExec("insert into t1 values(1, 2)") } - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats1 = h.GetTableStats(tableInfo1) c.Assert(stats1.Count, Equals, int64(rowCount1*2)) @@ -106,7 +106,7 @@ func (s *testStatsUpdateSuite) TestSingleSessionInsert(c *C) { testKit.MustExec("insert into t1 values(1, 2)") } testKit.MustExec("commit") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats1 = h.GetTableStats(tableInfo1) c.Assert(stats1.Count, Equals, int64(rowCount1*3)) @@ -122,7 +122,7 @@ func (s *testStatsUpdateSuite) TestSingleSessionInsert(c *C) { testKit.MustExec("update t2 set c2 = c1") } testKit.MustExec("commit") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats1 = h.GetTableStats(tableInfo1) c.Assert(stats1.Count, Equals, int64(rowCount1*3)) @@ -132,7 +132,7 @@ func (s *testStatsUpdateSuite) TestSingleSessionInsert(c *C) { testKit.MustExec("begin") testKit.MustExec("delete from t1") testKit.MustExec("commit") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats1 = h.GetTableStats(tableInfo1) c.Assert(stats1.Count, Equals, int64(0)) @@ -142,6 +142,33 @@ func (s *testStatsUpdateSuite) TestSingleSessionInsert(c *C) { rs = testKit.MustQuery("select tot_col_size from mysql.stats_histograms") rs.Check(testkit.Rows("0", "0", "10", "10")) + + // test dump delta only when `modify count / count` is greater than the ratio. + originValue := statistics.DumpStatsDeltaRatio + statistics.DumpStatsDeltaRatio = 0.5 + defer func() { + statistics.DumpStatsDeltaRatio = originValue + }() + statistics.DumpStatsDeltaRatio = 0.5 + for i := 0; i < rowCount1; i++ { + testKit.MustExec("insert into t1 values (1,2)") + } + h.DumpStatsDeltaToKV(statistics.DumpDelta) + h.Update(is) + stats1 = h.GetTableStats(tableInfo1) + c.Assert(stats1.Count, Equals, int64(rowCount1)) + + // not dumped + testKit.MustExec("insert into t1 values (1,2)") + h.DumpStatsDeltaToKV(statistics.DumpDelta) + h.Update(is) + stats1 = h.GetTableStats(tableInfo1) + c.Assert(stats1.Count, Equals, int64(rowCount1)) + + h.FlushStats() + h.Update(is) + stats1 = h.GetTableStats(tableInfo1) + c.Assert(stats1.Count, Equals, int64(rowCount1+1)) } func (s *testStatsUpdateSuite) TestRollback(c *C) { @@ -159,7 +186,7 @@ func (s *testStatsUpdateSuite) TestRollback(c *C) { tableInfo := tbl.Meta() h := s.do.StatsHandle() h.HandleDDLEvent(<-h.DDLEventCh()) - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats := h.GetTableStats(tableInfo) @@ -194,7 +221,7 @@ func (s *testStatsUpdateSuite) TestMultiSession(c *C) { h.HandleDDLEvent(<-h.DDLEventCh()) - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats1 := h.GetTableStats(tableInfo1) c.Assert(stats1.Count, Equals, int64(rowCount1)) @@ -214,7 +241,7 @@ func (s *testStatsUpdateSuite) TestMultiSession(c *C) { testKit.Se.Close() testKit2.Se.Close() - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats1 = h.GetTableStats(tableInfo1) c.Assert(stats1.Count, Equals, int64(rowCount1*2)) @@ -243,14 +270,14 @@ func (s *testStatsUpdateSuite) TestTxnWithFailure(c *C) { for i := 0; i < rowCount1; i++ { testKit.MustExec("insert into t1 values(?, 2)", i) } - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats1 := h.GetTableStats(tableInfo1) // have not commit c.Assert(stats1.Count, Equals, int64(0)) testKit.MustExec("commit") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats1 = h.GetTableStats(tableInfo1) c.Assert(stats1.Count, Equals, int64(rowCount1)) @@ -258,13 +285,13 @@ func (s *testStatsUpdateSuite) TestTxnWithFailure(c *C) { _, err = testKit.Exec("insert into t1 values(0, 2)") c.Assert(err, NotNil) - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats1 = h.GetTableStats(tableInfo1) c.Assert(stats1.Count, Equals, int64(rowCount1)) testKit.MustExec("insert into t1 values(-1, 2)") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) stats1 = h.GetTableStats(tableInfo1) c.Assert(stats1.Count, Equals, int64(rowCount1+1)) @@ -297,7 +324,7 @@ func (s *testStatsUpdateSuite) TestAutoUpdate(c *C) { _, err = testKit.Exec("insert into t values ('ss')") c.Assert(err, IsNil) - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Update(is) err = h.HandleAutoAnalyze(is) c.Assert(err, IsNil) @@ -313,7 +340,7 @@ func (s *testStatsUpdateSuite) TestAutoUpdate(c *C) { _, err = testKit.Exec("insert into t values ('fff')") c.Assert(err, IsNil) - c.Assert(h.DumpStatsDeltaToKV(), IsNil) + c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil) c.Assert(h.Update(is), IsNil) err = h.HandleAutoAnalyze(is) c.Assert(err, IsNil) @@ -324,7 +351,7 @@ func (s *testStatsUpdateSuite) TestAutoUpdate(c *C) { _, err = testKit.Exec("insert into t values ('fff')") c.Assert(err, IsNil) - c.Assert(h.DumpStatsDeltaToKV(), IsNil) + c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil) c.Assert(h.Update(is), IsNil) err = h.HandleAutoAnalyze(is) c.Assert(err, IsNil) @@ -335,7 +362,7 @@ func (s *testStatsUpdateSuite) TestAutoUpdate(c *C) { _, err = testKit.Exec("insert into t values ('eee')") c.Assert(err, IsNil) - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) h.Clear() // We set `Lease` here so that `Update` will use load by need strategy. h.Lease = time.Second @@ -482,7 +509,7 @@ func (s *testStatsUpdateSuite) TestQueryFeedback(c *C) { table, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) for i, t := range tests { testKit.MustQuery(t.sql) - c.Assert(h.DumpStatsDeltaToKV(), IsNil) + c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil) c.Assert(h.DumpStatsFeedbackToKV(), IsNil) c.Assert(h.HandleUpdateStats(s.do.InfoSchema()), IsNil) c.Assert(err, IsNil) @@ -498,7 +525,7 @@ func (s *testStatsUpdateSuite) TestQueryFeedback(c *C) { // Feedback from limit executor may not be accurate. testKit.MustQuery("select * from t where t.a <= 2 limit 1") - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) feedback := h.GetQueryFeedback() c.Assert(len(feedback), Equals, 0) @@ -506,7 +533,7 @@ func (s *testStatsUpdateSuite) TestQueryFeedback(c *C) { statistics.MaxNumberOfRanges = 0 for _, t := range tests { testKit.MustQuery(t.sql) - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) feedback := h.GetQueryFeedback() c.Assert(len(feedback), Equals, 0) } @@ -516,7 +543,7 @@ func (s *testStatsUpdateSuite) TestQueryFeedback(c *C) { statistics.MaxNumberOfRanges = oriNumber for _, t := range tests { testKit.MustQuery(t.sql) - h.DumpStatsDeltaToKV() + h.DumpStatsDeltaToKV(statistics.DumpAll) feedback := h.GetQueryFeedback() c.Assert(len(feedback), Equals, 0) } @@ -554,16 +581,16 @@ func (s *testStatsUpdateSuite) TestOutOfOrderUpdate(c *C) { // Simulate the case that another tidb has inserted some value, but delta info has not been dumped to kv yet. testKit.MustExec("insert into t values (2,2),(4,5)") - c.Assert(h.DumpStatsDeltaToKV(), IsNil) + c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil) testKit.MustExec(fmt.Sprintf("update mysql.stats_meta set count = 1 where table_id = %d", tableInfo.ID)) testKit.MustExec("delete from t") - c.Assert(h.DumpStatsDeltaToKV(), IsNil) + c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil) testKit.MustQuery("select count from mysql.stats_meta").Check(testkit.Rows("1")) // Now another tidb has updated the delta info. testKit.MustExec(fmt.Sprintf("update mysql.stats_meta set count = 3 where table_id = %d", tableInfo.ID)) - c.Assert(h.DumpStatsDeltaToKV(), IsNil) + c.Assert(h.DumpStatsDeltaToKV(statistics.DumpAll), IsNil) testKit.MustQuery("select count from mysql.stats_meta").Check(testkit.Rows("0")) }