From bb662942e579d08aa07209e2bc6714adc84891bc Mon Sep 17 00:00:00 2001 From: Song Gao Date: Sun, 15 May 2022 23:10:37 +0800 Subject: [PATCH] statistics: analyzed table by manual should be updated in lru (#34637) ref pingcap/tidb#34052 --- statistics/handle/handle.go | 26 ++++++++++++++++++++++++-- statistics/handle/handle_test.go | 27 +++++++++++++++++++++++++++ statistics/handle/lru_cache.go | 11 +++++++++++ statistics/handle/statscache.go | 7 +++++++ 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/statistics/handle/handle.go b/statistics/handle/handle.go index fb75619ed4..88ea07d7ae 100644 --- a/statistics/handle/handle.go +++ b/statistics/handle/handle.go @@ -260,6 +260,10 @@ func (h *Handle) Update(is infoschema.InfoSchema, opts ...TableStatsOpt) error { if err != nil { return errors.Trace(err) } + option := &tableStatsOption{} + for _, opt := range opts { + opt(option) + } for _, row := range rows { version := row.GetUint64(0) physicalID := row.GetInt64(1) @@ -293,9 +297,13 @@ func (h *Handle) Update(is infoschema.InfoSchema, opts ...TableStatsOpt) error { tbl.ModifyCount = modifyCount tbl.Name = getFullTableName(is, tableInfo) tbl.TblInfoUpdateTS = tableInfo.UpdateTS - oldCache.Put(physicalID, tbl) + if option.byQuery { + oldCache.PutByQuery(physicalID, tbl) + } else { + oldCache.Put(physicalID, tbl) + } } - h.updateStatsCache(oldCache.update(nil, nil, lastVersion, opts...)) + h.updateStatsCache(oldCache.update(nil, nil, lastVersion)) return nil } @@ -2076,3 +2084,17 @@ func (h *Handle) SetStatsCacheCapacity(c int64) { sc := v.(statsCache) sc.SetCapacity(c) } + +// GetStatsCacheFrontTable gets front table in statsCacheInner implementation +// only used for test +func (h *Handle) GetStatsCacheFrontTable() int64 { + if h == nil { + return 0 + } + v := h.statsCache.Load() + if v == nil { + return 0 + } + sc := v.(statsCache) + return sc.Front() +} diff --git a/statistics/handle/handle_test.go b/statistics/handle/handle_test.go index 0f6a21fb37..a84d2c71fa 100644 --- a/statistics/handle/handle_test.go +++ b/statistics/handle/handle_test.go @@ -3344,3 +3344,30 @@ func TestAnalyzeIncrementalEvictedIndex(t *testing.T) { tk.MustExec("analyze incremental table test.t index idx_b") require.Nil(t, failpoint.Disable("github.com/pingcap/tidb/executor/assertEvictIndex")) } + +func TestAnalyzeTableLRUPut(t *testing.T) { + restore := config.RestoreFunc() + defer restore() + config.UpdateGlobal(func(conf *config.Config) { + conf.Performance.EnableStatsCacheMemQuota = true + }) + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) + tk.MustExec("set @@tidb_analyze_version = 1") + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b varchar(10), index idx_b (b))") + tk.MustExec("create table t1(a int, b varchar(10), index idx_b (b))") + tk.MustExec("analyze table test.t") + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.Nil(t, err) + tbl1, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) + require.Nil(t, err) + // assert t1 should be front of lru + tk.MustExec("analyze table test.t1") + require.Equal(t, tbl1.Meta().ID, domain.GetDomain(tk.Session()).StatsHandle().GetStatsCacheFrontTable()) + // assert t should be front of lru + tk.MustExec("analyze table test.t") + require.Equal(t, tbl.Meta().ID, domain.GetDomain(tk.Session()).StatsHandle().GetStatsCacheFrontTable()) +} diff --git a/statistics/handle/lru_cache.go b/statistics/handle/lru_cache.go index ab4b05f268..5f87f4ec5d 100644 --- a/statistics/handle/lru_cache.go +++ b/statistics/handle/lru_cache.go @@ -278,6 +278,17 @@ func (s *statsInnerCache) EnableQuota() bool { return true } +// Front implements statsCacheInner +func (s *statsInnerCache) Front() int64 { + s.RLock() + defer s.RUnlock() + ele := s.lru.cache.Front() + if ele == nil { + return 0 + } + return s.lru.cache.Front().Value.(*lruCacheItem).tblID +} + func (s *statsInnerCache) onEvict(tblID int64) { element, exist := s.elements[tblID] if !exist { diff --git a/statistics/handle/statscache.go b/statistics/handle/statscache.go index 9f06c09b02..1c7b7c2918 100644 --- a/statistics/handle/statscache.go +++ b/statistics/handle/statscache.go @@ -39,6 +39,8 @@ type statsCacheInner interface { Copy() statsCacheInner SetCapacity(int64) EnableQuota() bool + // Front returns the front element's owner tableID, only used for test + Front() int64 } func newStatsCache() statsCache { @@ -253,3 +255,8 @@ func (m *mapCache) SetCapacity(int64) {} func (m *mapCache) EnableQuota() bool { return false } + +// Front implements statsCacheInner +func (m *mapCache) Front() int64 { + return 0 +}