pingcap / pingcap/tidb

statistics: stats GC can leave dropped logical table meta-only stats_meta rows

Open
#68,076 0 comments 0 reactions 1 assignee Claimed by @0xPoe View on GitHub
affects-9.0 component/statistics severity/minor sig/planner type/bug
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

### 1. Minimal reproduce step (Required)

This is reproducible in **static partition prune mode**. It is the same flow as `pkg/statistics/handle/storage.TestGCPartition`:

```go
testKit.MustExec("set @@tidb_analyze_version = 2")
testkit.WithPruneMode(testKit, variable.Static, func() {
testKit.MustExec("use test")
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 with 0 topn")

h := dom.StatsHandle()
ddlLease := time.Duration(0)

testKit.MustExec("alter table t drop index idx")
require.Nil(t, h.GCStats(dom.InfoSchema(), ddlLease))

testKit.MustExec("alter table t drop column b")
require.Nil(t, h.GCStats(dom.InfoSchema(), ddlLease))

testKit.MustExec("drop table t")
require.Nil(t, h.GCStats(dom.InfoSchema(), ddlLease))
require.Nil(t, h.GCStats(dom.InfoSchema(), ddlLease))

testKit.MustQuery("select count(*) from mysql.stats_meta").Check(testkit.Rows("1"))
})
```

### 2. What did you expect to see? (Required)

After the partitioned table is dropped and stats GC runs, all stats records for the dropped table should eventually be removed.

```sql
select count(*) from mysql.stats_meta;
-- expected: 0
```

### 3. What did you see instead (Required)

One `mysql.stats_meta` row remains for the dropped logical table.

In static prune mode, `ANALYZE TABLE t` creates stats for the physical partitions and leaves a logical-table meta row. Later GC removes the partition stats, but the logical-table meta-only row can be skipped because stats GC scans only rows whose `version` is between `lastGC` and `gcVer`. If an earlier GC has already advanced `lastGC` past that row's version, later GC runs will not revisit it after the table is dropped.

### 4. What is your TiDB version? (Required)

Current master / PR branch.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.