Skip to content

Commit 430d7f8

Browse files
authored
store/tikv: fix performance issue under mixed transaction mode (#10847) (#10881)
1 parent 4238d74 commit 430d7f8

File tree

6 files changed

+45
-12
lines changed

6 files changed

+45
-12
lines changed

config/config.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ import (
3535

3636
// Config number limitations
3737
const (
38-
MaxLogFileSize = 4096 // MB
38+
MaxLogFileSize = 4096 // MB
39+
MinPessimisticTTL = time.Second * 15
40+
MaxPessimisticTTL = time.Second * 60
3941
)
4042

4143
// Valid config maps
@@ -564,10 +566,9 @@ func (c *Config) Valid() error {
564566
if err != nil {
565567
return err
566568
}
567-
minDur := time.Second * 15
568-
maxDur := time.Second * 60
569-
if dur < minDur || dur > maxDur {
570-
return fmt.Errorf("pessimistic transaction ttl %s out of range [%s, %s]", dur, minDur, maxDur)
569+
if dur < MinPessimisticTTL || dur > MaxPessimisticTTL {
570+
return fmt.Errorf("pessimistic transaction ttl %s out of range [%s, %s]",
571+
dur, MinPessimisticTTL, MaxPessimisticTTL)
571572
}
572573
}
573574
return nil

session/pessimistic_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/pingcap/tidb/session"
2828
"github.com/pingcap/tidb/store/mockstore"
2929
"github.com/pingcap/tidb/store/mockstore/mocktikv"
30+
"github.com/pingcap/tidb/store/tikv"
3031
"github.com/pingcap/tidb/tablecodec"
3132
"github.com/pingcap/tidb/util/codec"
3233
"github.com/pingcap/tidb/util/testkit"
@@ -52,6 +53,7 @@ func (s *testPessimisticSuite) SetUpSuite(c *C) {
5253
mockstore.WithCluster(s.cluster),
5354
mockstore.WithMVCCStore(s.mvccStore),
5455
)
56+
tikv.PessimisticLockTTL = uint64(config.MinPessimisticTTL / time.Millisecond)
5557
c.Assert(err, IsNil)
5658
s.store = store
5759
session.SetSchemaLease(0)

store/tikv/2pc.go

+13
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,19 @@ func (c *twoPhaseCommitter) prewriteSingleBatch(bo *Backoffer, batch batchKeys)
538538
if err1 != nil {
539539
return errors.Trace(err1)
540540
}
541+
if !c.isPessimistic && c.lockTTL < lock.TTL && lock.TTL >= uint64(config.MinPessimisticTTL/time.Millisecond) {
542+
// An optimistic prewrite meets a pessimistic or large transaction lock.
543+
// If we wait for the lock, other written optimistic locks would block reads for long time.
544+
// And it is very unlikely this transaction would succeed after wait for the long TTL lock.
545+
// Return write conflict error to cleanup locks.
546+
return newWriteConflictError(&pb.WriteConflict{
547+
StartTs: c.startTS,
548+
ConflictTs: lock.TxnID,
549+
ConflictCommitTs: 0,
550+
Key: lock.Key,
551+
Primary: lock.Primary,
552+
})
553+
}
541554
logutil.Logger(context.Background()).Debug("prewrite encounters lock",
542555
zap.Uint64("conn", c.connID),
543556
zap.Stringer("lock", lock))

store/tikv/2pc_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
. "github.com/pingcap/check"
2424
"github.com/pingcap/errors"
2525
"github.com/pingcap/kvproto/pkg/kvrpcpb"
26+
"github.com/pingcap/tidb/config"
2627
"github.com/pingcap/tidb/kv"
2728
"github.com/pingcap/tidb/store/mockstore/mocktikv"
2829
"github.com/pingcap/tidb/store/tikv/tikvrpc"
@@ -38,6 +39,7 @@ var _ = Suite(&testCommitterSuite{})
3839

3940
func (s *testCommitterSuite) SetUpTest(c *C) {
4041
s.cluster = mocktikv.NewCluster()
42+
PessimisticLockTTL = uint64(config.MinPessimisticTTL / time.Millisecond)
4143
mocktikv.BootstrapWithMultiRegions(s.cluster, []byte("a"), []byte("b"), []byte("c"))
4244
mvccStore, err := mocktikv.NewMVCCLevelDB("")
4345
c.Assert(err, IsNil)
@@ -468,3 +470,18 @@ func (s *testCommitterSuite) TestPessimisticLockedKeysDedup(c *C) {
468470
c.Assert(err, IsNil)
469471
c.Assert(txn.lockKeys, HasLen, 2)
470472
}
473+
474+
func (s *testCommitterSuite) TestPessimistOptimisticConflict(c *C) {
475+
txnPes := s.begin(c)
476+
txnPes.SetOption(kv.Pessimistic, true)
477+
err := txnPes.LockKeys(context.Background(), txnPes.startTS, kv.Key("pes"))
478+
c.Assert(err, IsNil)
479+
c.Assert(txnPes.IsPessimistic(), IsTrue)
480+
c.Assert(txnPes.lockKeys, HasLen, 1)
481+
txnOpt := s.begin(c)
482+
err = txnOpt.Set(kv.Key("pes"), []byte("v"))
483+
c.Assert(err, IsNil)
484+
err = txnOpt.Commit(context.Background())
485+
c.Assert(kv.ErrWriteConflict.Equal(err), IsTrue)
486+
c.Assert(txnPes.Commit(context.Background()), IsNil)
487+
}

store/tikv/lock_resolver.go

+2-7
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,12 @@ func (l *Lock) String() string {
138138

139139
// NewLock creates a new *Lock.
140140
func NewLock(l *kvrpcpb.LockInfo) *Lock {
141-
ttl := l.GetLockTtl()
142-
if ttl == 0 {
143-
ttl = defaultLockTTL
144-
}
145-
txnSize := l.GetTxnSize()
146141
return &Lock{
147142
Key: l.GetKey(),
148143
Primary: l.GetPrimaryLock(),
149144
TxnID: l.GetLockVersion(),
150-
TTL: ttl,
151-
TxnSize: txnSize,
145+
TTL: l.GetLockTtl(),
146+
TxnSize: l.GetTxnSize(),
152147
}
153148
}
154149

store/tikv/lock_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ func (s *testLockSuite) TestLockTTL(c *C) {
277277
s.ttlEquals(c, l.TTL, defaultLockTTL+uint64(time.Since(start)/time.Millisecond))
278278
}
279279

280+
func (s *testLockSuite) TestNewLockZeroTTL(c *C) {
281+
l := NewLock(&kvrpcpb.LockInfo{})
282+
c.Assert(l.TTL, Equals, uint64(0))
283+
}
284+
280285
func init() {
281286
// Speed up tests.
282287
defaultLockTTL = 3

0 commit comments

Comments
 (0)