diff --git a/store/gcworker/gc_worker.go b/store/gcworker/gc_worker.go index ba6df3c7b2ea0..b85095850d183 100644 --- a/store/gcworker/gc_worker.go +++ b/store/gcworker/gc_worker.go @@ -42,6 +42,7 @@ import ( "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/privilege" "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/store/tikv" "github.com/pingcap/tidb/store/tikv/logutil" "github.com/pingcap/tidb/store/tikv/oracle" @@ -93,6 +94,7 @@ func NewGCWorker(store kv.Storage, pdClient pd.Client) (*GCWorker, error) { lastFinish: time.Now(), done: make(chan error), } + variable.RegisterStatistics(worker) return worker, nil } @@ -155,6 +157,13 @@ const ( gcDefaultAutoConcurrency = true gcWorkerServiceSafePointID = "gc_worker" + + // Status var names start with tidb_% + tidbGCLastRunTime = "tidb_gc_last_run_time" + tidbGCLeaderDesc = "tidb_gc_leader_desc" + tidbGCLeaderLease = "tidb_gc_leader_lease" + tidbGCLeaderUUID = "tidb_gc_leader_uuid" + tidbGCSafePoint = "tidb_gc_safe_point" ) var gcSafePointCacheInterval = tikv.GcSafePointCacheInterval @@ -223,6 +232,32 @@ func createSession(store kv.Storage) session.Session { } } +// GetScope gets the status variables scope. +func (w *GCWorker) GetScope(status string) variable.ScopeFlag { + return variable.DefaultStatusVarScopeFlag +} + +// Stats returns the server statistics. +func (w *GCWorker) Stats(vars *variable.SessionVars) (map[string]interface{}, error) { + m := make(map[string]interface{}) + if v, err := w.loadValueFromSysTable(gcLeaderUUIDKey); err == nil { + m[tidbGCLeaderUUID] = v + } + if v, err := w.loadValueFromSysTable(gcLeaderDescKey); err == nil { + m[tidbGCLeaderDesc] = v + } + if v, err := w.loadValueFromSysTable(gcLeaderLeaseKey); err == nil { + m[tidbGCLeaderLease] = v + } + if v, err := w.loadValueFromSysTable(gcLastRunTimeKey); err == nil { + m[tidbGCLastRunTime] = v + } + if v, err := w.loadValueFromSysTable(gcSafePointKey); err == nil { + m[tidbGCSafePoint] = v + } + return m, nil +} + func (w *GCWorker) tick(ctx context.Context) { isLeader, err := w.checkLeader() if err != nil { diff --git a/store/gcworker/gc_worker_test.go b/store/gcworker/gc_worker_test.go index d8c07f6ebfa99..c4006fa3f31aa 100644 --- a/store/gcworker/gc_worker_test.go +++ b/store/gcworker/gc_worker_test.go @@ -390,6 +390,26 @@ func (s *testGCWorkerSuite) TestPrepareGC(c *C) { c.Assert(safepoint, Equals, uint64(0)) } +func (s *testGCWorkerSuite) TestStatusVars(c *C) { + // Status variables should now exist for: + // tidb_gc_safe_point, tidb_gc_last_run_time + se := createSession(s.gcWorker.store) + defer se.Close() + + safePoint, err := s.gcWorker.loadValueFromSysTable(gcSafePointKey) + c.Assert(err, IsNil) + lastRunTime, err := s.gcWorker.loadValueFromSysTable(gcLastRunTimeKey) + c.Assert(err, IsNil) + + statusVars, _ := s.gcWorker.Stats(se.GetSessionVars()) + val, ok := statusVars[tidbGCSafePoint] + c.Assert(ok, IsTrue) + c.Assert(val, Equals, safePoint) + val, ok = statusVars[tidbGCLastRunTime] + c.Assert(ok, IsTrue) + c.Assert(val, Equals, lastRunTime) +} + func (s *testGCWorkerSuite) TestDoGCForOneRegion(c *C) { ctx := context.Background() bo := tikv.NewBackofferWithVars(ctx, tikv.GcOneRegionMaxBackoff, nil)