From 94d812749cc652391031e67129b2764a7668fdf6 Mon Sep 17 00:00:00 2001 From: crazycs Date: Thu, 27 Jun 2019 20:04:22 +0800 Subject: [PATCH] add check for gc life time too small (#10936) (#10951) --- store/tikv/gcworker/gc_worker.go | 27 +++++++++++++++++++++ store/tikv/gcworker/gc_worker_test.go | 35 +++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/store/tikv/gcworker/gc_worker.go b/store/tikv/gcworker/gc_worker.go index c6fc712804655..24050a6aa6e29 100644 --- a/store/tikv/gcworker/gc_worker.go +++ b/store/tikv/gcworker/gc_worker.go @@ -30,6 +30,7 @@ import ( "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/parser/terror" "github.com/pingcap/pd/client" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/ddl/util" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta" @@ -114,6 +115,7 @@ const ( gcLifeTimeKey = "tikv_gc_life_time" gcDefaultLifeTime = time.Minute * 10 + gcMinLifeTime = time.Minute * 10 gcSafePointKey = "tikv_gc_safe_point" gcConcurrencyKey = "tikv_gc_concurrency" gcDefaultConcurrency = 2 @@ -436,11 +438,36 @@ func (w *GCWorker) checkGCInterval(now time.Time) (bool, error) { return true, nil } +// validateGCLiftTime checks whether life time is small than min gc life time. +func (w *GCWorker) validateGCLiftTime(lifeTime time.Duration) (time.Duration, error) { + minLifeTime := gcMinLifeTime + // max-txn-time-use value is less than gc_life_time - 10s. + maxTxnTime := time.Duration(config.GetGlobalConfig().TiKVClient.MaxTxnTimeUse+10) * time.Second + if minLifeTime < maxTxnTime { + minLifeTime = maxTxnTime + } + + if lifeTime >= minLifeTime { + return lifeTime, nil + } + + logutil.Logger(context.Background()).Info("[gc worker] invalid gc life time", + zap.Duration("get gc life time", lifeTime), + zap.Duration("min gc life time", minLifeTime)) + + err := w.saveDuration(gcLifeTimeKey, minLifeTime) + return minLifeTime, err +} + func (w *GCWorker) calculateNewSafePoint(now time.Time) (*time.Time, error) { lifeTime, err := w.loadDurationWithDefault(gcLifeTimeKey, gcDefaultLifeTime) if err != nil { return nil, errors.Trace(err) } + *lifeTime, err = w.validateGCLiftTime(*lifeTime) + if err != nil { + return nil, err + } metrics.GCConfigGauge.WithLabelValues(gcLifeTimeKey).Set(lifeTime.Seconds()) lastSafePoint, err := w.loadTime(gcSafePointKey) if err != nil { diff --git a/store/tikv/gcworker/gc_worker_test.go b/store/tikv/gcworker/gc_worker_test.go index 58b1b5cea08b3..357ae13bcdfe0 100644 --- a/store/tikv/gcworker/gc_worker_test.go +++ b/store/tikv/gcworker/gc_worker_test.go @@ -23,6 +23,7 @@ import ( . "github.com/pingcap/check" "github.com/pingcap/failpoint" "github.com/pingcap/kvproto/pkg/errorpb" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/store/mockoracle" @@ -166,6 +167,40 @@ func (s *testGCWorkerSuite) TestPrepareGC(c *C) { c.Assert(err, IsNil) c.Assert(ok, IsTrue) + // Check gc life time small than min. + s.oracle.AddOffset(time.Minute * 40) + err = s.gcWorker.saveDuration(gcLifeTimeKey, time.Minute) + c.Assert(err, IsNil) + ok, _, err = s.gcWorker.prepare() + c.Assert(err, IsNil) + c.Assert(ok, IsTrue) + lifeTime, err := s.gcWorker.loadDuration(gcLifeTimeKey) + c.Assert(err, IsNil) + c.Assert(*lifeTime, Equals, gcMinLifeTime) + + // Check gc life time small than config.max-txn-use-time + s.oracle.AddOffset(time.Minute * 40) + config.GetGlobalConfig().TiKVClient.MaxTxnTimeUse = 20*60 - 10 // 20min - 10s + err = s.gcWorker.saveDuration(gcLifeTimeKey, time.Minute) + c.Assert(err, IsNil) + ok, _, err = s.gcWorker.prepare() + c.Assert(err, IsNil) + c.Assert(ok, IsTrue) + lifeTime, err = s.gcWorker.loadDuration(gcLifeTimeKey) + c.Assert(err, IsNil) + c.Assert(*lifeTime, Equals, 20*time.Minute) + + // check the tikv_gc_life_time more than config.max-txn-use-time situation. + s.oracle.AddOffset(time.Minute * 40) + err = s.gcWorker.saveDuration(gcLifeTimeKey, time.Minute*30) + c.Assert(err, IsNil) + ok, _, err = s.gcWorker.prepare() + c.Assert(err, IsNil) + c.Assert(ok, IsTrue) + lifeTime, err = s.gcWorker.loadDuration(gcLifeTimeKey) + c.Assert(err, IsNil) + c.Assert(*lifeTime, Equals, 30*time.Minute) + // Change auto concurrency err = s.gcWorker.saveValueToSysTable(gcAutoConcurrencyKey, booleanFalse) c.Assert(err, IsNil)