@@ -22,6 +22,7 @@ import (
22
22
"time"
23
23
24
24
"github.com/pingcap/errors"
25
+ "github.com/pingcap/failpoint"
25
26
"github.com/pingcap/tidb/pkg/infoschema"
26
27
"github.com/pingcap/tidb/pkg/parser/terror"
27
28
"github.com/pingcap/tidb/pkg/sessionctx"
@@ -91,6 +92,10 @@ func GCStats(
91
92
return nil
92
93
}
93
94
95
+ failpoint .Inject ("injectGCStatsLastTSOffset" , func (val failpoint.Value ) {
96
+ offset = uint64 (val .(int ))
97
+ })
98
+
94
99
// Get the last gc time.
95
100
gcVer := now - offset
96
101
lastGC , err := getLastGCTimestamp (sctx )
@@ -266,29 +271,36 @@ func removeDeletedExtendedStats(sctx sessionctx.Context, version uint64) (err er
266
271
}
267
272
268
273
// gcTableStats GC this table's stats.
274
+ // The GC of a table will be a two-phase process:
275
+ // 1. Delete the column/index's stats from storage. Then other TiDB nodes will be aware that those stats are deleted.
276
+ // 2. Then delete the record in stats_meta.
269
277
func gcTableStats (sctx sessionctx.Context ,
270
278
statsHandler types.StatsHandle ,
271
279
is infoschema.InfoSchema , physicalID int64 ) error {
280
+ tbl , ok := statsHandler .TableInfoByID (is , physicalID )
272
281
rows , _ , err := util .ExecRows (sctx , "select is_index, hist_id from mysql.stats_histograms where table_id = %?" , physicalID )
273
282
if err != nil {
274
283
return errors .Trace (err )
275
284
}
276
- // The table has already been deleted in stats and acknowledged to all tidb,
277
- // we can safely remove the meta info now.
278
- if len (rows ) == 0 {
285
+ if ! ok {
286
+ if len (rows ) > 0 {
287
+ // It's the first time to run into it. Delete column/index stats to notify other TiDB nodes.
288
+ logutil .BgLogger ().Info ("remove stats in GC due to dropped table" , zap .Int64 ("tableID" , physicalID ))
289
+ return util .WrapTxn (sctx , func (sctx sessionctx.Context ) error {
290
+ return errors .Trace (DeleteTableStatsFromKV (sctx , []int64 {physicalID }))
291
+ })
292
+ }
293
+ // len(rows) == 0 => The table's stats is empty.
294
+ // The table has already been deleted in stats and acknowledged to all tidb,
295
+ // We can safely remove the meta info now.
279
296
_ , _ , err = util .ExecRows (sctx , "delete from mysql.stats_meta where table_id = %?" , physicalID )
280
297
if err != nil {
281
298
return errors .Trace (err )
282
299
}
283
300
cache .TableRowStatsCache .Invalidate (physicalID )
301
+ return nil
284
302
}
285
- tbl , ok := statsHandler .TableInfoByID (is , physicalID )
286
- if ! ok {
287
- logutil .BgLogger ().Info ("remove stats in GC due to dropped table" , zap .Int64 ("table_id" , physicalID ))
288
- return util .WrapTxn (sctx , func (sctx sessionctx.Context ) error {
289
- return errors .Trace (DeleteTableStatsFromKV (sctx , []int64 {physicalID }))
290
- })
291
- }
303
+
292
304
tblInfo := tbl .Meta ()
293
305
for _ , row := range rows {
294
306
isIndex , histID := row .GetInt64 (0 ), row .GetInt64 (1 )
0 commit comments