From 9ddab592fb2bbeacf4722962fac369b08e0ebccc Mon Sep 17 00:00:00 2001 From: Yuanjia Zhang Date: Wed, 3 Jul 2019 13:20:27 +0800 Subject: [PATCH] store/tikv: Make maxTxnTimeUse a configurable value (#10480) --- config/config.go | 3 +++ config/config.toml.example | 5 +++++ store/tikv/2pc.go | 36 ++++++++++++++++++++---------------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/config/config.go b/config/config.go index f8248398f64cb..f690f360a40bb 100644 --- a/config/config.go +++ b/config/config.go @@ -264,6 +264,8 @@ type TiKVClient struct { GrpcKeepAliveTimeout uint `toml:"grpc-keepalive-timeout" json:"grpc-keepalive-timeout"` // CommitTimeout is the max time which command 'commit' will wait. CommitTimeout string `toml:"commit-timeout" json:"commit-timeout"` + // MaxTxnTimeUse is the max time a Txn may use (in seconds) from its startTS to commitTS. + MaxTxnTimeUse uint `toml:"max-txn-time-use" json:"max-txn-time-use"` } // Plugin is the config for plugin @@ -357,6 +359,7 @@ var defaultConf = Config{ GrpcKeepAliveTime: 10, GrpcKeepAliveTimeout: 3, CommitTimeout: "41s", + MaxTxnTimeUse: 590, }, Binlog: Binlog{ WriteTimeout: "15s", diff --git a/config/config.toml.example b/config/config.toml.example index 8c04c46cde3ca..4545dfdf77a6e 100644 --- a/config/config.toml.example +++ b/config/config.toml.example @@ -253,6 +253,11 @@ grpc-keepalive-timeout = 3 # max time for commit command, must be twice bigger than raft election timeout. commit-timeout = "41s" +# The max time a Txn may use (in seconds) from its startTS to commitTS. +# We use it to guarantee GC worker will not influence any active txn. Please make sure that this +# value is less than gc_life_time - 10s. +max-txn-time-use = 590 + [txn-local-latches] # Enable local latches for transactions. Enable it when # there are lots of conflicts between transactions. diff --git a/store/tikv/2pc.go b/store/tikv/2pc.go index 1e4ed7f2bf9c8..4a23632366758 100644 --- a/store/tikv/2pc.go +++ b/store/tikv/2pc.go @@ -23,6 +23,7 @@ import ( "github.com/pingcap/errors" pb "github.com/pingcap/kvproto/pkg/kvrpcpb" "github.com/pingcap/parser/terror" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/sessionctx/binloginfo" @@ -79,6 +80,11 @@ type twoPhaseCommitter struct { connID uint64 // connID is used for log. cleanWg sync.WaitGroup detail *execdetails.CommitDetails + + // The max time a Txn may use (in ms) from its startTS to commitTS. + // We use it to guarantee GC worker will not influence any active txn. The value + // should be less than GC life time. + maxTxnTimeUse uint64 } // newTwoPhaseCommitter creates a twoPhaseCommitter. @@ -159,20 +165,23 @@ func newTwoPhaseCommitter(txn *tikvTxn, connID uint64) (*twoPhaseCommitter, erro return nil, errors.Trace(err) } + // Convert from sec to ms + maxTxnTimeUse := uint64(config.GetGlobalConfig().TiKVClient.MaxTxnTimeUse) * 1000 commitDetail := &execdetails.CommitDetails{WriteSize: size, WriteKeys: len(keys)} metrics.TiKVTxnWriteKVCountHistogram.Observe(float64(commitDetail.WriteKeys)) metrics.TiKVTxnWriteSizeHistogram.Observe(float64(commitDetail.WriteSize)) return &twoPhaseCommitter{ - store: txn.store, - txn: txn, - startTS: txn.StartTS(), - keys: keys, - mutations: mutations, - lockTTL: txnLockTTL(txn.startTime, size), - priority: getTxnPriority(txn), - syncLog: getTxnSyncLog(txn), - connID: connID, - detail: commitDetail, + store: txn.store, + txn: txn, + startTS: txn.StartTS(), + keys: keys, + mutations: mutations, + lockTTL: txnLockTTL(txn.startTime, size), + priority: getTxnPriority(txn), + syncLog: getTxnSyncLog(txn), + connID: connID, + detail: commitDetail, + maxTxnTimeUse: maxTxnTimeUse, }, nil } @@ -593,11 +602,6 @@ func (c *twoPhaseCommitter) cleanupKeys(bo *Backoffer, keys [][]byte) error { return c.doActionOnKeys(bo, actionCleanup, keys) } -// The max time a Txn may use (in ms) from its startTS to commitTS. -// We use it to guarantee GC worker will not influence any active txn. The value -// should be less than `gcRunInterval`. -const maxTxnTimeUse = 590000 - func (c *twoPhaseCommitter) executeAndWriteFinishBinlog(ctx context.Context) error { err := c.execute(ctx) if err != nil { @@ -677,7 +681,7 @@ func (c *twoPhaseCommitter) execute(ctx context.Context) error { return errors.Trace(err) } - if c.store.oracle.IsExpired(c.startTS, maxTxnTimeUse) { + if c.store.oracle.IsExpired(c.startTS, c.maxTxnTimeUse) { err = errors.Errorf("conn%d txn takes too much time, txnStartTS: %d, comm: %d", c.connID, c.startTS, c.commitTS) return errors.Annotate(err, txnRetryableMark)