Skip to content

Commit

Permalink
stats: garbage collect stats for partition table (#7962)
Browse files Browse the repository at this point in the history
  • Loading branch information
alivxxx authored and zz-jason committed Oct 24, 2018
1 parent 50eb73f commit 9c91374
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 14 deletions.
30 changes: 16 additions & 14 deletions statistics/gc.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,24 @@ func (h *Handle) GCStats(is infoschema.InfoSchema, ddlLease time.Duration) error
return nil
}

func (h *Handle) gcTableStats(is infoschema.InfoSchema, tableID int64) error {
sql := fmt.Sprintf("select is_index, hist_id from mysql.stats_histograms where table_id = %d", tableID)
func (h *Handle) gcTableStats(is infoschema.InfoSchema, physicalID int64) error {
sql := fmt.Sprintf("select is_index, hist_id from mysql.stats_histograms where table_id = %d", physicalID)
rows, _, err := h.restrictedExec.ExecRestrictedSQL(nil, sql)
if err != nil {
return errors.Trace(err)
}
// The table has already been deleted in stats and acknowledged to all tidb,
// we can safely remove the meta info now.
if len(rows) == 0 {
sql := fmt.Sprintf("delete from mysql.stats_meta where table_id = %d", tableID)
sql := fmt.Sprintf("delete from mysql.stats_meta where table_id = %d", physicalID)
_, _, err := h.restrictedExec.ExecRestrictedSQL(nil, sql)
return errors.Trace(err)
}
tbl, ok := is.TableByID(tableID)
h.mu.Lock()
tbl, ok := h.getTableByPhysicalID(is, physicalID)
h.mu.Unlock()
if !ok {
return errors.Trace(h.DeleteTableStatsFromKV(tableID))
return errors.Trace(h.DeleteTableStatsFromKV(physicalID))
}
tblInfo := tbl.Meta()
for _, row := range rows {
Expand All @@ -85,7 +87,7 @@ func (h *Handle) gcTableStats(is infoschema.InfoSchema, tableID int64) error {
}
}
if !find {
if err := h.deleteHistStatsFromKV(tblInfo.ID, histID, int(isIndex)); err != nil {
if err := h.deleteHistStatsFromKV(physicalID, histID, int(isIndex)); err != nil {
return errors.Trace(err)
}
}
Expand All @@ -94,7 +96,7 @@ func (h *Handle) gcTableStats(is infoschema.InfoSchema, tableID int64) error {
}

// deleteHistStatsFromKV deletes all records about a column or an index and updates version.
func (h *Handle) deleteHistStatsFromKV(tableID int64, histID int64, isIndex int) (err error) {
func (h *Handle) deleteHistStatsFromKV(physicalID int64, histID int64, isIndex int) (err error) {
h.mu.Lock()
defer h.mu.Unlock()
exec := h.mu.ctx.(sqlexec.SQLExecutor)
Expand All @@ -106,22 +108,22 @@ func (h *Handle) deleteHistStatsFromKV(tableID int64, histID int64, isIndex int)
err = finishTransaction(context.Background(), exec, err)
}()
// First of all, we update the version. If this table doesn't exist, it won't have any problem. Because we cannot delete anything.
_, err = exec.Execute(context.Background(), fmt.Sprintf("update mysql.stats_meta set version = %d where table_id = %d ", h.mu.ctx.Txn().StartTS(), tableID))
_, err = exec.Execute(context.Background(), fmt.Sprintf("update mysql.stats_meta set version = %d where table_id = %d ", h.mu.ctx.Txn().StartTS(), physicalID))
if err != nil {
return
}
// delete histogram meta
_, err = exec.Execute(context.Background(), fmt.Sprintf("delete from mysql.stats_histograms where table_id = %d and hist_id = %d and is_index = %d", tableID, histID, isIndex))
_, err = exec.Execute(context.Background(), fmt.Sprintf("delete from mysql.stats_histograms where table_id = %d and hist_id = %d and is_index = %d", physicalID, histID, isIndex))
if err != nil {
return
}
// delete all buckets
_, err = exec.Execute(context.Background(), fmt.Sprintf("delete from mysql.stats_buckets where table_id = %d and hist_id = %d and is_index = %d", tableID, histID, isIndex))
_, err = exec.Execute(context.Background(), fmt.Sprintf("delete from mysql.stats_buckets where table_id = %d and hist_id = %d and is_index = %d", physicalID, histID, isIndex))
return
}

// DeleteTableStatsFromKV deletes table statistics from kv.
func (h *Handle) DeleteTableStatsFromKV(id int64) (err error) {
func (h *Handle) DeleteTableStatsFromKV(physicalID int64) (err error) {
h.mu.Lock()
defer h.mu.Unlock()
exec := h.mu.ctx.(sqlexec.SQLExecutor)
Expand All @@ -133,15 +135,15 @@ func (h *Handle) DeleteTableStatsFromKV(id int64) (err error) {
err = finishTransaction(context.Background(), exec, err)
}()
// We only update the version so that other tidb will know that this table is deleted.
sql := fmt.Sprintf("update mysql.stats_meta set version = %d where table_id = %d ", h.mu.ctx.Txn().StartTS(), id)
sql := fmt.Sprintf("update mysql.stats_meta set version = %d where table_id = %d ", h.mu.ctx.Txn().StartTS(), physicalID)
_, err = exec.Execute(context.Background(), sql)
if err != nil {
return
}
_, err = exec.Execute(context.Background(), fmt.Sprintf("delete from mysql.stats_histograms where table_id = %d", id))
_, err = exec.Execute(context.Background(), fmt.Sprintf("delete from mysql.stats_histograms where table_id = %d", physicalID))
if err != nil {
return
}
_, err = exec.Execute(context.Background(), fmt.Sprintf("delete from mysql.stats_buckets where table_id = %d", id))
_, err = exec.Execute(context.Background(), fmt.Sprintf("delete from mysql.stats_buckets where table_id = %d", physicalID))
return
}
36 changes: 36 additions & 0 deletions statistics/gc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,39 @@ func (s *testStatsUpdateSuite) TestGCStats(c *C) {
c.Assert(h.GCStats(s.do.InfoSchema(), ddlLease), IsNil)
testKit.MustQuery("select count(*) from mysql.stats_meta").Check(testkit.Rows("0"))
}

func (s *testStatsUpdateSuite) TestGCPartition(c *C) {
defer cleanEnv(c, s.store, s.do)
testKit := testkit.NewTestKit(c, s.store)
testKit.MustExec("use test")
testKit.MustExec("set @@session.tidb_enable_table_partition=1")
testKit.MustExec(`create table t (a bigint(64), b bigint(64), index idx(a, b))
partition by range (a) (
partition p0 values less than (3),
partition p1 values less than (6))`)
testKit.MustExec("insert into t values (1,2),(2,3),(3,4),(4,5),(5,6)")
testKit.MustExec("analyze table t")

testKit.MustQuery("select count(*) from mysql.stats_histograms").Check(testkit.Rows("6"))
testKit.MustQuery("select count(*) from mysql.stats_buckets").Check(testkit.Rows("15"))
h := s.do.StatsHandle()
h.SetLastUpdateVersion(math.MaxUint64)
ddlLease := time.Duration(0)
testKit.MustExec("alter table t drop index idx")
c.Assert(h.GCStats(s.do.InfoSchema(), ddlLease), IsNil)
testKit.MustQuery("select count(*) from mysql.stats_histograms").Check(testkit.Rows("4"))
testKit.MustQuery("select count(*) from mysql.stats_buckets").Check(testkit.Rows("10"))

testKit.MustExec("alter table t drop column b")
c.Assert(h.GCStats(s.do.InfoSchema(), ddlLease), IsNil)
testKit.MustQuery("select count(*) from mysql.stats_histograms").Check(testkit.Rows("2"))
testKit.MustQuery("select count(*) from mysql.stats_buckets").Check(testkit.Rows("5"))

testKit.MustExec("drop table t")
c.Assert(h.GCStats(s.do.InfoSchema(), ddlLease), IsNil)
testKit.MustQuery("select count(*) from mysql.stats_meta").Check(testkit.Rows("2"))
testKit.MustQuery("select count(*) from mysql.stats_histograms").Check(testkit.Rows("0"))
testKit.MustQuery("select count(*) from mysql.stats_buckets").Check(testkit.Rows("0"))
c.Assert(h.GCStats(s.do.InfoSchema(), ddlLease), IsNil)
testKit.MustQuery("select count(*) from mysql.stats_meta").Check(testkit.Rows("0"))
}

0 comments on commit 9c91374

Please sign in to comment.