From 4ce8dba67e9eca768a8e3ddd4cb9191e15fda259 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 2 Sep 2019 13:57:49 +0800 Subject: [PATCH 01/13] *: implement the TxnHeartBeat API for the large transaction --- go.mod | 4 +++ go.sum | 2 ++ store/mockstore/mocktikv/mock_tikv_test.go | 23 +++++++++++++ store/mockstore/mocktikv/mvcc.go | 1 + store/mockstore/mocktikv/mvcc_leveldb.go | 40 ++++++++++++++++++++++ store/mockstore/mocktikv/rpc.go | 20 +++++++++++ store/tikv/lock_test.go | 18 ++++++++++ store/tikv/tikvrpc/tikvrpc.go | 14 ++++++++ 8 files changed, 122 insertions(+) diff --git a/go.mod b/go.mod index 6413c20dd1b09..611f6164087aa 100644 --- a/go.mod +++ b/go.mod @@ -75,3 +75,7 @@ require ( sourcegraph.com/sourcegraph/appdash v0.0.0-20180531100431-4c381bd170b4 sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 ) + +replace github.com/pingcap/kvproto => github.com/pingcap/kvproto v0.0.0-20190829095345-6a581f25586d + +go 1.13 diff --git a/go.sum b/go.sum index 87f81d487e605..c87c51bed2c38 100644 --- a/go.sum +++ b/go.sum @@ -162,6 +162,8 @@ github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e/go.mod h1:O17Xtb github.com/pingcap/kvproto v0.0.0-20190516013202-4cf58ad90b6c/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/pingcap/kvproto v0.0.0-20190724165112-ec9df5f208a7 h1:BMrtxXqQeZ9y27LN/V3PHA/tSyDWHK+90VLYaymrXQE= github.com/pingcap/kvproto v0.0.0-20190724165112-ec9df5f208a7/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= +github.com/pingcap/kvproto v0.0.0-20190829095345-6a581f25586d h1:/yAB1ikjMxGOyBCYO8O+POBlarPfcMjJkhVy2ZHENCA= +github.com/pingcap/kvproto v0.0.0-20190829095345-6a581f25586d/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/pingcap/log v0.0.0-20190214045112-b37da76f67a7/go.mod h1:xsfkWVaFVV5B8e1K9seWfyJWFrIhbtUTAD8NV1Pq3+w= github.com/pingcap/log v0.0.0-20190307075452-bd41d9273596 h1:t2OQTpPJnrPDGlvA+3FwJptMTt6MEPdzK1Wt99oaefQ= github.com/pingcap/log v0.0.0-20190307075452-bd41d9273596/go.mod h1:WpHUKhNZ18v116SvGrmjkA9CBhYmuUTKL+p8JC9ANEw= diff --git a/store/mockstore/mocktikv/mock_tikv_test.go b/store/mockstore/mocktikv/mock_tikv_test.go index ddb71d775d46e..70fca32bd6024 100644 --- a/store/mockstore/mocktikv/mock_tikv_test.go +++ b/store/mockstore/mocktikv/mock_tikv_test.go @@ -157,6 +157,10 @@ func (s *testMockTiKVSuite) mustRangeReverseScanOK(c *C, start, end string, limi } func (s *testMockTiKVSuite) mustPrewriteOK(c *C, mutations []*kvrpcpb.Mutation, primary string, startTS uint64) { + s.mustPrewriteOK1(c, mutations, primary, startTS, 0) +} + +func (s *testMockTiKVSuite) mustPrewriteOK1(c *C, mutations []*kvrpcpb.Mutation, primary string, startTS uint64, ttl uint64) { req := &kvrpcpb.PrewriteRequest{ Mutations: mutations, PrimaryLock: []byte(primary), @@ -650,3 +654,22 @@ func (s *testMVCCLevelDB) TestErrors(c *C) { c.Assert(ErrAlreadyCommitted(0).Error(), Equals, "txn already committed") c.Assert((&ErrConflict{}).Error(), Equals, "write conflict") } + +func (s *testMVCCLevelDB) TestTxnHeartBeat(c *C) { + s.mustPrewriteOK1(c, putMutations("pk", "val"), "pk", 5, 666) + + // Update the ttl + ttl, err := s.store.TxnHeartBeat([]byte("pk"), 5, 888) + c.Assert(err, IsNil) + c.Assert(ttl, Greater, uint64(666)) + + // Advise ttl is small + ttl, err = s.store.TxnHeartBeat([]byte("pk"), 5, 300) + c.Assert(err, IsNil) + c.Assert(ttl, Greater, uint64(300)) + + // The lock has already been clean up + c.Assert(s.store.Cleanup([]byte("pk"), 5), IsNil) + ttl, err = s.store.TxnHeartBeat([]byte("pk"), 5, 1000) + c.Assert(err, NotNil) +} diff --git a/store/mockstore/mocktikv/mvcc.go b/store/mockstore/mocktikv/mvcc.go index 02b4ba3c5a6c4..6250d664db963 100644 --- a/store/mockstore/mocktikv/mvcc.go +++ b/store/mockstore/mocktikv/mvcc.go @@ -258,6 +258,7 @@ type MVCCStore interface { Rollback(keys [][]byte, startTS uint64) error Cleanup(key []byte, startTS uint64) error ScanLock(startKey, endKey []byte, maxTS uint64) ([]*kvrpcpb.LockInfo, error) + TxnHeartBeat(primaryKey []byte, startTS uint64, adviseTTL uint64) (uint64, error) ResolveLock(startKey, endKey []byte, startTS, commitTS uint64) error BatchResolveLock(startKey, endKey []byte, txnInfos map[uint64]uint64) error GC(startKey, endKey []byte, safePoint uint64) error diff --git a/store/mockstore/mocktikv/mvcc_leveldb.go b/store/mockstore/mocktikv/mvcc_leveldb.go index 056824834d437..287e8338c477b 100644 --- a/store/mockstore/mocktikv/mvcc_leveldb.go +++ b/store/mockstore/mocktikv/mvcc_leveldb.go @@ -931,6 +931,46 @@ func (mvcc *MVCCLevelDB) Cleanup(key []byte, startTS uint64) error { return mvcc.db.Write(batch, nil) } +// TxnHeartBeat implements the MVCCStore interface. +func (mvcc *MVCCLevelDB) TxnHeartBeat(key []byte, startTS uint64, adviseTTL uint64) (uint64, error) { + startKey := mvccEncode(key, lockVer) + iter := newIterator(mvcc.db, &util.Range{ + Start: startKey, + }) + defer iter.Release() + + if iter.Valid() { + dec := lockDecoder{ + expectKey: key, + } + ok, err := dec.Decode(iter) + if err != nil { + return 0, errors.Trace(err) + } + if ok && dec.lock.startTS == startTS { + lock := dec.lock + batch := &leveldb.Batch{} + // Increase the ttl of this transaction. + if adviseTTL < lock.ttl { + lock.ttl = lock.ttl/2 + adviseTTL/2 + } else { + lock.ttl = adviseTTL + } + writeKey := mvccEncode(key, lockVer) + writeValue, err := lock.MarshalBinary() + if err != nil { + return 0, errors.Trace(err) + } + batch.Put(writeKey, writeValue) + if err = mvcc.db.Write(batch, nil); err != nil { + return 0, errors.Trace(err) + } + return lock.ttl, nil + } + } + return 0, errors.New("lock doesn't exist!!") +} + // ScanLock implements the MVCCStore interface. func (mvcc *MVCCLevelDB) ScanLock(startKey, endKey []byte, maxTS uint64) ([]*kvrpcpb.LockInfo, error) { mvcc.mu.RLock() diff --git a/store/mockstore/mocktikv/rpc.go b/store/mockstore/mocktikv/rpc.go index 8dd8109a523e2..b2c9c9943e169 100644 --- a/store/mockstore/mocktikv/rpc.go +++ b/store/mockstore/mocktikv/rpc.go @@ -368,6 +368,19 @@ func (h *rpcHandler) handleKvCleanup(req *kvrpcpb.CleanupRequest) *kvrpcpb.Clean return &resp } +func (h *rpcHandler) handleTxnHeartBeat(req *kvrpcpb.TxnHeartBeatRequest) *kvrpcpb.TxnHeartBeatResponse { + if !h.checkKeyInRegion(req.PrimaryLock) { + panic("KvTxnHeartBeat: key not in region") + } + var resp kvrpcpb.TxnHeartBeatResponse + ttl, err := h.mvccStore.TxnHeartBeat(req.PrimaryLock, req.StartVersion, req.AdviseLockTtl) + if err != nil { + resp.Error = convertToKeyError(err) + } + resp.LockTtl = ttl + return &resp +} + func (h *rpcHandler) handleKvBatchGet(req *kvrpcpb.BatchGetRequest) *kvrpcpb.BatchGetResponse { for _, k := range req.Keys { if !h.checkKeyInRegion(k) { @@ -766,6 +779,13 @@ func (c *RPCClient) SendRequest(ctx context.Context, addr string, req *tikvrpc.R return resp, nil } resp.Resp = handler.handleKvCleanup(r) + case tikvrpc.CmdTxnHeartBeat: + r := req.TxnHeartBeat() + if err := handler.checkRequest(reqCtx, r.Size()); err != nil { + resp.Resp = &kvrpcpb.TxnHeartBeatResponse{RegionError: err} + return resp, nil + } + resp.Resp = handler.handleTxnHeartBeat(r) case tikvrpc.CmdBatchGet: r := req.BatchGet() if err := handler.checkRequest(reqCtx, r.Size()); err != nil { diff --git a/store/tikv/lock_test.go b/store/tikv/lock_test.go index 2675ef436011f..0b9e87ec88078 100644 --- a/store/tikv/lock_test.go +++ b/store/tikv/lock_test.go @@ -202,6 +202,24 @@ func (s *testLockSuite) TestGetTxnStatus(c *C) { c.Assert(status.IsCommitted(), IsFalse) } +func (s *testLockSuite) TestTxnHeartBeat(c *C) { + txn, err := s.store.Begin() + c.Assert(err, IsNil) + txn.Set(kv.Key("key"), []byte("value")) + s.prewriteTxn(c, txn.(*tikvTxn)) + + bo := NewBackoffer(context.Background(), prewriteMaxBackoff) + err = sendTxnHeartBeat(bo, s.store, []byte("key"), txn.StartTS(), 666) + c.Assert(err, IsNil) + + // The getTxnStatus API is confusing, it really means rollback! + _, err = newLockResolver(s.store).getTxnStatus(bo, txn.StartTS(), []byte("key")) + c.Assert(err, IsNil) + + err = sendTxnHeartBeat(bo, s.store, []byte("key"), txn.StartTS(), 666) + c.Assert(err, NotNil) +} + func (s *testLockSuite) prewriteTxn(c *C, txn *tikvTxn) { committer, err := newTwoPhaseCommitterWithInit(txn, 0) c.Assert(err, IsNil) diff --git a/store/tikv/tikvrpc/tikvrpc.go b/store/tikv/tikvrpc/tikvrpc.go index 9f2e1f6eb14fb..ce04ce522b397 100644 --- a/store/tikv/tikvrpc/tikvrpc.go +++ b/store/tikv/tikvrpc/tikvrpc.go @@ -47,6 +47,7 @@ const ( CmdDeleteRange CmdPessimisticLock CmdPessimisticRollback + CmdTxnHeartBeat CmdRawGet CmdType = 256 + iota CmdRawBatchGet @@ -129,6 +130,8 @@ func (t CmdType) String() string { return "SplitRegion" case CmdDebugGetRegionProperties: return "DebugGetRegionProperties" + case CmdTxnHeartBeat: + return "TxnHeartBeat" } return "Unknown" } @@ -304,6 +307,11 @@ func (req *Request) Empty() *tikvpb.BatchCommandsEmptyRequest { return req.req.(*tikvpb.BatchCommandsEmptyRequest) } +// TxnHeartBeat returns TxnHeartBeatRequest in request. +func (req *Request) TxnHeartBeat() *kvrpcpb.TxnHeartBeatRequest { + return req.req.(*kvrpcpb.TxnHeartBeatRequest) +} + // ToBatchCommandsRequest converts the request to an entry in BatchCommands request. func (req *Request) ToBatchCommandsRequest() *tikvpb.BatchCommandsRequest_Request { switch req.Type { @@ -353,6 +361,8 @@ func (req *Request) ToBatchCommandsRequest() *tikvpb.BatchCommandsRequest_Reques return &tikvpb.BatchCommandsRequest_Request{Cmd: &tikvpb.BatchCommandsRequest_Request_PessimisticRollback{PessimisticRollback: req.PessimisticRollback()}} case CmdEmpty: return &tikvpb.BatchCommandsRequest_Request{Cmd: &tikvpb.BatchCommandsRequest_Request_Empty{Empty: req.Empty()}} + case CmdTxnHeartBeat: + return &tikvpb.BatchCommandsRequest_Request{Cmd: &tikvpb.BatchCommandsRequest_Request_TxnHeartBeat{TxnHeartBeat: req.TxnHeartBeat()}} } return nil } @@ -498,6 +508,8 @@ func SetContext(req *Request, region *metapb.Region, peer *metapb.Peer) error { req.SplitRegion().Context = ctx case CmdEmpty: req.SplitRegion().Context = ctx + case CmdTxnHeartBeat: + req.TxnHeartBeat().Context = ctx default: return fmt.Errorf("invalid request type %v", req.Type) } @@ -714,6 +726,8 @@ func CallRPC(ctx context.Context, client tikvpb.TikvClient, req *Request) (*Resp resp.Resp, err = client.SplitRegion(ctx, req.SplitRegion()) case CmdEmpty: resp.Resp, err = &tikvpb.BatchCommandsEmptyResponse{}, nil + case CmdTxnHeartBeat: + resp.Resp, err = client.KvTxnHeartBeat(ctx, req.TxnHeartBeat()) default: return nil, errors.Errorf("invalid request type: %v", req.Type) } From e736d9737ac87f2ac7313c029a40c2b2c915d0c6 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 2 Sep 2019 14:22:53 +0800 Subject: [PATCH 02/13] fix CI --- store/tikv/2pc.go | 37 +++++++++++++++++++++++++++++++ store/tikv/region_request_test.go | 8 +++++++ 2 files changed, 45 insertions(+) diff --git a/store/tikv/2pc.go b/store/tikv/2pc.go index 05ba781a50ba8..a7128eacd0a83 100644 --- a/store/tikv/2pc.go +++ b/store/tikv/2pc.go @@ -145,6 +145,43 @@ func newTwoPhaseCommitter(txn *tikvTxn, connID uint64) (*twoPhaseCommitter, erro }, nil } +func sendTxnHeartBeat(bo *Backoffer, store *tikvStore, primary []byte, startTS, ttl uint64) error { + req := tikvrpc.NewRequest(tikvrpc.CmdTxnHeartBeat, &pb.TxnHeartBeatRequest{ + PrimaryLock: primary, + StartVersion: startTS, + AdviseLockTtl: ttl, + }) + for { + loc, err := store.GetRegionCache().LocateKey(bo, primary) + if err != nil { + return errors.Trace(err) + } + resp, err := store.SendReq(bo, req, loc.Region, readTimeoutShort) + if err != nil { + return errors.Trace(err) + } + regionErr, err := resp.GetRegionError() + if err != nil { + return errors.Trace(err) + } + if regionErr != nil { + err = bo.Backoff(BoRegionMiss, errors.New(regionErr.String())) + if err != nil { + return errors.Trace(err) + } + continue + } + if resp.Resp == nil { + return errors.Trace(ErrBodyMissing) + } + cmdResp := resp.Resp.(*pb.TxnHeartBeatResponse) + if keyErr := cmdResp.GetError(); keyErr != nil { + return errors.Errorf("txn %d heartbeat fail, primary key = %v, err = %s", startTS, primary, keyErr.Abort) + } + return nil + } +} + func (c *twoPhaseCommitter) initKeysAndMutations() error { var ( keys [][]byte diff --git a/store/tikv/region_request_test.go b/store/tikv/region_request_test.go index e14bdc0208147..c7fde12997352 100644 --- a/store/tikv/region_request_test.go +++ b/store/tikv/region_request_test.go @@ -313,6 +313,14 @@ func (s *mockTikvGrpcServer) ReadIndex(context.Context, *kvrpcpb.ReadIndexReques return nil, errors.New("unreachable") } +func (s *mockTikvGrpcServer) KvTxnHeartBeat(ctx context.Context, in *kvrpcpb.TxnHeartBeatRequest) (*kvrpcpb.TxnHeartBeatResponse, error) { + return nil, errors.New("unreachable") +} + +func (s *mockTikvGrpcServer) KvCheckTxnStatus(ctx context.Context, in *kvrpcpb.CheckTxnStatusRequest) (*kvrpcpb.CheckTxnStatusResponse, error) { + return nil, errors.New("unreachable") +} + func (s *testRegionRequestSuite) TestNoReloadRegionForGrpcWhenCtxCanceled(c *C) { // prepare a mock tikv grpc server addr := "localhost:56341" From 1ff204f3da7e201856f8ded192a7493cad2c9f29 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 2 Sep 2019 14:43:38 +0800 Subject: [PATCH 03/13] make golint happy --- store/mockstore/mocktikv/mvcc_leveldb.go | 2 +- tools/check/go.mod | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/store/mockstore/mocktikv/mvcc_leveldb.go b/store/mockstore/mocktikv/mvcc_leveldb.go index 287e8338c477b..6f65858b9da12 100644 --- a/store/mockstore/mocktikv/mvcc_leveldb.go +++ b/store/mockstore/mocktikv/mvcc_leveldb.go @@ -968,7 +968,7 @@ func (mvcc *MVCCLevelDB) TxnHeartBeat(key []byte, startTS uint64, adviseTTL uint return lock.ttl, nil } } - return 0, errors.New("lock doesn't exist!!") + return 0, errors.New("lock doesn't exist") } // ScanLock implements the MVCCStore interface. diff --git a/tools/check/go.mod b/tools/check/go.mod index ca5d580f6d6a4..6dfc12cecadbd 100644 --- a/tools/check/go.mod +++ b/tools/check/go.mod @@ -20,3 +20,5 @@ require ( gopkg.in/yaml.v2 v2.2.2 // indirect honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3 ) + +go 1.13 From 0943045f6b67276d9ff6abcb655c1a750f4b2ef5 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 2 Sep 2019 15:11:13 +0800 Subject: [PATCH 04/13] using Go1.12 --- go.sum | 3 --- 1 file changed, 3 deletions(-) diff --git a/go.sum b/go.sum index c87c51bed2c38..3ba8e90a1d267 100644 --- a/go.sum +++ b/go.sum @@ -159,9 +159,6 @@ github.com/pingcap/failpoint v0.0.0-20190512135322-30cc7431d99c h1:hvQd3aOLKLF7x github.com/pingcap/failpoint v0.0.0-20190512135322-30cc7431d99c/go.mod h1:DNS3Qg7bEDhU6EXNHF+XSv/PGznQaMJ5FWvctpm6pQI= github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e h1:P73/4dPCL96rGrobssy1nVy2VaVpNCuLpCbr+FEaTA8= github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= -github.com/pingcap/kvproto v0.0.0-20190516013202-4cf58ad90b6c/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= -github.com/pingcap/kvproto v0.0.0-20190724165112-ec9df5f208a7 h1:BMrtxXqQeZ9y27LN/V3PHA/tSyDWHK+90VLYaymrXQE= -github.com/pingcap/kvproto v0.0.0-20190724165112-ec9df5f208a7/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/pingcap/kvproto v0.0.0-20190829095345-6a581f25586d h1:/yAB1ikjMxGOyBCYO8O+POBlarPfcMjJkhVy2ZHENCA= github.com/pingcap/kvproto v0.0.0-20190829095345-6a581f25586d/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/pingcap/log v0.0.0-20190214045112-b37da76f67a7/go.mod h1:xsfkWVaFVV5B8e1K9seWfyJWFrIhbtUTAD8NV1Pq3+w= From 7ef446460d879bba5aace2539249e1f4cff313ae Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 2 Sep 2019 15:24:39 +0800 Subject: [PATCH 05/13] make golint happy --- store/mockstore/mocktikv/mock_tikv_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/store/mockstore/mocktikv/mock_tikv_test.go b/store/mockstore/mocktikv/mock_tikv_test.go index 70fca32bd6024..69c3f9854fd7e 100644 --- a/store/mockstore/mocktikv/mock_tikv_test.go +++ b/store/mockstore/mocktikv/mock_tikv_test.go @@ -670,6 +670,6 @@ func (s *testMVCCLevelDB) TestTxnHeartBeat(c *C) { // The lock has already been clean up c.Assert(s.store.Cleanup([]byte("pk"), 5), IsNil) - ttl, err = s.store.TxnHeartBeat([]byte("pk"), 5, 1000) + _, err = s.store.TxnHeartBeat([]byte("pk"), 5, 1000) c.Assert(err, NotNil) } From 03a24322642eb3f0e08b0bf1a02073f27e832bb7 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Tue, 3 Sep 2019 17:55:10 +0800 Subject: [PATCH 06/13] address comment --- store/mockstore/mocktikv/mvcc_leveldb.go | 22 ++++++++++------------ store/tikv/2pc.go | 16 ++++++++-------- store/tikv/lock_test.go | 9 ++++++--- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/store/mockstore/mocktikv/mvcc_leveldb.go b/store/mockstore/mocktikv/mvcc_leveldb.go index 6f65858b9da12..48275a532cb58 100644 --- a/store/mockstore/mocktikv/mvcc_leveldb.go +++ b/store/mockstore/mocktikv/mvcc_leveldb.go @@ -951,19 +951,17 @@ func (mvcc *MVCCLevelDB) TxnHeartBeat(key []byte, startTS uint64, adviseTTL uint lock := dec.lock batch := &leveldb.Batch{} // Increase the ttl of this transaction. - if adviseTTL < lock.ttl { - lock.ttl = lock.ttl/2 + adviseTTL/2 - } else { + if adviseTTL > lock.ttl { lock.ttl = adviseTTL - } - writeKey := mvccEncode(key, lockVer) - writeValue, err := lock.MarshalBinary() - if err != nil { - return 0, errors.Trace(err) - } - batch.Put(writeKey, writeValue) - if err = mvcc.db.Write(batch, nil); err != nil { - return 0, errors.Trace(err) + writeKey := mvccEncode(key, lockVer) + writeValue, err := lock.MarshalBinary() + if err != nil { + return 0, errors.Trace(err) + } + batch.Put(writeKey, writeValue) + if err = mvcc.db.Write(batch, nil); err != nil { + return 0, errors.Trace(err) + } } return lock.ttl, nil } diff --git a/store/tikv/2pc.go b/store/tikv/2pc.go index a7128eacd0a83..978bb79bc4ab4 100644 --- a/store/tikv/2pc.go +++ b/store/tikv/2pc.go @@ -145,7 +145,7 @@ func newTwoPhaseCommitter(txn *tikvTxn, connID uint64) (*twoPhaseCommitter, erro }, nil } -func sendTxnHeartBeat(bo *Backoffer, store *tikvStore, primary []byte, startTS, ttl uint64) error { +func sendTxnHeartBeat(bo *Backoffer, store *tikvStore, primary []byte, startTS, ttl uint64) (uint64, error) { req := tikvrpc.NewRequest(tikvrpc.CmdTxnHeartBeat, &pb.TxnHeartBeatRequest{ PrimaryLock: primary, StartVersion: startTS, @@ -154,31 +154,31 @@ func sendTxnHeartBeat(bo *Backoffer, store *tikvStore, primary []byte, startTS, for { loc, err := store.GetRegionCache().LocateKey(bo, primary) if err != nil { - return errors.Trace(err) + return 0, errors.Trace(err) } resp, err := store.SendReq(bo, req, loc.Region, readTimeoutShort) if err != nil { - return errors.Trace(err) + return 0, errors.Trace(err) } regionErr, err := resp.GetRegionError() if err != nil { - return errors.Trace(err) + return 0, errors.Trace(err) } if regionErr != nil { err = bo.Backoff(BoRegionMiss, errors.New(regionErr.String())) if err != nil { - return errors.Trace(err) + return 0, errors.Trace(err) } continue } if resp.Resp == nil { - return errors.Trace(ErrBodyMissing) + return 0, errors.Trace(ErrBodyMissing) } cmdResp := resp.Resp.(*pb.TxnHeartBeatResponse) if keyErr := cmdResp.GetError(); keyErr != nil { - return errors.Errorf("txn %d heartbeat fail, primary key = %v, err = %s", startTS, primary, keyErr.Abort) + return 0, errors.Errorf("txn %d heartbeat fail, primary key = %v, err = %s", startTS, primary, keyErr.Abort) } - return nil + return cmdResp.GetLockTtl(), nil } } diff --git a/store/tikv/lock_test.go b/store/tikv/lock_test.go index 0b9e87ec88078..8b4f7f3f681e3 100644 --- a/store/tikv/lock_test.go +++ b/store/tikv/lock_test.go @@ -209,15 +209,18 @@ func (s *testLockSuite) TestTxnHeartBeat(c *C) { s.prewriteTxn(c, txn.(*tikvTxn)) bo := NewBackoffer(context.Background(), prewriteMaxBackoff) - err = sendTxnHeartBeat(bo, s.store, []byte("key"), txn.StartTS(), 666) + newTTL, err := sendTxnHeartBeat(bo, s.store, []byte("key"), txn.StartTS(), 666) c.Assert(err, IsNil) + c.Assert(newTTL, Equals, 666) // The getTxnStatus API is confusing, it really means rollback! - _, err = newLockResolver(s.store).getTxnStatus(bo, txn.StartTS(), []byte("key")) + status, err = newLockResolver(s.store).getTxnStatus(bo, txn.StartTS(), []byte("key")) c.Assert(err, IsNil) + c.Assert(status, Equals, 0) - err = sendTxnHeartBeat(bo, s.store, []byte("key"), txn.StartTS(), 666) + newTTL, err = sendTxnHeartBeat(bo, s.store, []byte("key"), txn.StartTS(), 666) c.Assert(err, NotNil) + c.Assert(newTTL, Equals, 0) } func (s *testLockSuite) prewriteTxn(c *C, txn *tikvTxn) { From f1e97dfc233bc24d19e242bfa9fe2445a174ea57 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Tue, 3 Sep 2019 20:14:17 +0800 Subject: [PATCH 07/13] address comment --- store/mockstore/mocktikv/mvcc_leveldb.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/store/mockstore/mocktikv/mvcc_leveldb.go b/store/mockstore/mocktikv/mvcc_leveldb.go index 48275a532cb58..6bdb856424a35 100644 --- a/store/mockstore/mocktikv/mvcc_leveldb.go +++ b/store/mockstore/mocktikv/mvcc_leveldb.go @@ -948,6 +948,10 @@ func (mvcc *MVCCLevelDB) TxnHeartBeat(key []byte, startTS uint64, adviseTTL uint return 0, errors.Trace(err) } if ok && dec.lock.startTS == startTS { + if !bytes.Equal(dec.lock.primary, key) { + return 0, errors.New("txnHeartBeat on non-primary key, the code should not run here") + } + lock := dec.lock batch := &leveldb.Batch{} // Increase the ttl of this transaction. From d49ebfccabd22d952b418fa9fc48d55df7b9a327 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Tue, 3 Sep 2019 20:42:58 +0800 Subject: [PATCH 08/13] fix CI --- go.mod | 2 -- store/tikv/lock_test.go | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 611f6164087aa..64aa49cda65e8 100644 --- a/go.mod +++ b/go.mod @@ -77,5 +77,3 @@ require ( ) replace github.com/pingcap/kvproto => github.com/pingcap/kvproto v0.0.0-20190829095345-6a581f25586d - -go 1.13 diff --git a/store/tikv/lock_test.go b/store/tikv/lock_test.go index 8b4f7f3f681e3..d15ace9ab6abd 100644 --- a/store/tikv/lock_test.go +++ b/store/tikv/lock_test.go @@ -211,16 +211,16 @@ func (s *testLockSuite) TestTxnHeartBeat(c *C) { bo := NewBackoffer(context.Background(), prewriteMaxBackoff) newTTL, err := sendTxnHeartBeat(bo, s.store, []byte("key"), txn.StartTS(), 666) c.Assert(err, IsNil) - c.Assert(newTTL, Equals, 666) + c.Assert(newTTL, Equals, uint64(666)) // The getTxnStatus API is confusing, it really means rollback! - status, err = newLockResolver(s.store).getTxnStatus(bo, txn.StartTS(), []byte("key")) + status, err := newLockResolver(s.store).getTxnStatus(bo, txn.StartTS(), []byte("key")) c.Assert(err, IsNil) - c.Assert(status, Equals, 0) + c.Assert(status, Equals, TxnStatus(0)) newTTL, err = sendTxnHeartBeat(bo, s.store, []byte("key"), txn.StartTS(), 666) c.Assert(err, NotNil) - c.Assert(newTTL, Equals, 0) + c.Assert(newTTL, Equals, uint64(0)) } func (s *testLockSuite) prewriteTxn(c *C, txn *tikvTxn) { From dbe8d3478a52827932e51ed0152467f452efffdc Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Thu, 5 Sep 2019 16:58:40 +0800 Subject: [PATCH 09/13] update go.mod --- go.mod | 20 +++++++---------- go.sum | 70 +++++++++++++++++----------------------------------------- 2 files changed, 28 insertions(+), 62 deletions(-) diff --git a/go.mod b/go.mod index 4e5185cb74311..9c00d5faacc1a 100644 --- a/go.mod +++ b/go.mod @@ -15,9 +15,8 @@ require ( github.com/dustin/go-humanize v1.0.0 // indirect github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-sql-driver/mysql v0.0.0-20170715192408-3955978caca4 - github.com/gogo/protobuf v1.3.0 - github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect - github.com/golang/protobuf v1.3.2 + github.com/gogo/protobuf v1.2.0 + github.com/golang/protobuf v1.2.0 github.com/google/btree v1.0.0 github.com/google/uuid v1.1.1 github.com/gorilla/context v1.1.1 // indirect @@ -66,15 +65,12 @@ require ( go.etcd.io/bbolt v1.3.3 // indirect go.uber.org/atomic v1.3.2 go.uber.org/zap v1.9.1 - golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 // indirect - golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 - golang.org/x/sys v0.0.0-20190904154756-749cb33beabd - golang.org/x/text v0.3.2 - golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect - golang.org/x/tools v0.0.0-20190905035308-adb45749da8e - google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 // indirect - google.golang.org/grpc v1.23.0 - gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect + golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e + golang.org/x/sys v0.0.0-20190109145017-48ac38b7c8cb + golang.org/x/text v0.3.0 + golang.org/x/tools v0.0.0-20190130214255-bb1329dc71a0 + google.golang.org/genproto v0.0.0-20190108161440-ae2f86662275 // indirect + google.golang.org/grpc v1.17.0 gopkg.in/natefinch/lumberjack.v2 v2.0.0 sourcegraph.com/sourcegraph/appdash v0.0.0-20180531100431-4c381bd170b4 sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 diff --git a/go.sum b/go.sum index b7094ce1d8b59..7230900a87171 100644 --- a/go.sum +++ b/go.sum @@ -58,21 +58,18 @@ github.com/go-sql-driver/mysql v0.0.0-20170715192408-3955978caca4 h1:3DFRjZdCDhz github.com/go-sql-driver/mysql v0.0.0-20170715192408-3955978caca4/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/gogo/protobuf v0.0.0-20180717141946-636bf0302bc9/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff h1:kOkM9whyQYodu09SJ6W3NCsHG7crFaJILQ22Gozp3lg= github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v0.0.0-20180814211427-aa810b61a9c7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -80,7 +77,6 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCy github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= @@ -111,7 +107,6 @@ github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwK github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/juju/ratelimit v1.0.1 h1:+7AIFJVQ0EQgq/K9+0Krm7m530Du7tIz0METWzN0RgY= github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= @@ -167,6 +162,8 @@ github.com/pingcap/failpoint v0.0.0-20190512135322-30cc7431d99c/go.mod h1:DNS3Qg github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e h1:P73/4dPCL96rGrobssy1nVy2VaVpNCuLpCbr+FEaTA8= github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= github.com/pingcap/kvproto v0.0.0-20190516013202-4cf58ad90b6c/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= +github.com/pingcap/kvproto v0.0.0-20190821201150-798d27658fae h1:WR4d5ga8zXT+QDWYFzzyA+PJMMszR0kQxyYMh6dvHPg= +github.com/pingcap/kvproto v0.0.0-20190821201150-798d27658fae/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/pingcap/kvproto v0.0.0-20190904075355-9a1bd6a31da2 h1:wBORZD4gvEKK0tGP4g1Rv0Y7f2cNnObzI/ckPhsU11M= github.com/pingcap/kvproto v0.0.0-20190904075355-9a1bd6a31da2/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/pingcap/log v0.0.0-20190214045112-b37da76f67a7/go.mod h1:xsfkWVaFVV5B8e1K9seWfyJWFrIhbtUTAD8NV1Pq3+w= @@ -266,73 +263,47 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180608092829-8ac0e0d97ce4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM= -golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190109145017-48ac38b7c8cb h1:1w588/yEchbPNpa9sEvOcMZYbWHedwJjg4VOAdDHWHk= +golang.org/x/sys v0.0.0-20190109145017-48ac38b7c8cb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 h1:+DCIGbF/swA92ohVg0//6X2IVY3KZs6p9mix0ziNYJM= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190905035308-adb45749da8e h1:UboUef6L2TaPy4CYJLNCvM9TkgCD8JbbUi5wrvhkxww= -golang.org/x/tools v0.0.0-20190905035308-adb45749da8e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190130214255-bb1329dc71a0 h1:iRpjPej1fPzmfoBhMFkp3HdqzF+ytPmAwiQhJGV0zGw= +golang.org/x/tools v0.0.0-20190130214255-bb1329dc71a0/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180608181217-32ee49c4dd80/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181004005441-af9cb2a35e7f/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190108161440-ae2f86662275 h1:9oFlwfEGIvmxXTcY53ygNyxIQtWciRHjrnUvZJCYXYU= +google.golang.org/genproto v0.0.0-20190108161440-ae2f86662275/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/grpc v0.0.0-20180607172857-7a6a684ca69e/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/gometalinter.v2 v2.0.12/go.mod h1:NDRytsqEZyolNuAgTzJkZMkSQM7FIKyzVzGhjB/qfYo= gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c/go.mod h1:3HH7i1SgMqlzxCcBmUHW657sD4Kvv9sC3HpL3YukzwA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -344,8 +315,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= sourcegraph.com/sourcegraph/appdash v0.0.0-20180531100431-4c381bd170b4 h1:VO9oZbbkvTwqLimlQt15QNdOOBArT2dw/bvzsMZBiqQ= sourcegraph.com/sourcegraph/appdash v0.0.0-20180531100431-4c381bd170b4/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 h1:e1sMhtVq9AfcEy8AXNb8eSg6gbzfdpYhoNqnPJa+GzI= From a7d9bdab9b313420338713477137d88db40359eb Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Thu, 5 Sep 2019 17:04:11 +0800 Subject: [PATCH 10/13] address comment --- store/mockstore/mocktikv/mock_tikv_test.go | 6 +++--- store/tikv/lock_test.go | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/store/mockstore/mocktikv/mock_tikv_test.go b/store/mockstore/mocktikv/mock_tikv_test.go index 69c3f9854fd7e..ee459b5e022d1 100644 --- a/store/mockstore/mocktikv/mock_tikv_test.go +++ b/store/mockstore/mocktikv/mock_tikv_test.go @@ -157,10 +157,10 @@ func (s *testMockTiKVSuite) mustRangeReverseScanOK(c *C, start, end string, limi } func (s *testMockTiKVSuite) mustPrewriteOK(c *C, mutations []*kvrpcpb.Mutation, primary string, startTS uint64) { - s.mustPrewriteOK1(c, mutations, primary, startTS, 0) + s.mustPrewriteWithTTLOK(c, mutations, primary, startTS, 0) } -func (s *testMockTiKVSuite) mustPrewriteOK1(c *C, mutations []*kvrpcpb.Mutation, primary string, startTS uint64, ttl uint64) { +func (s *testMockTiKVSuite) mustPrewriteWithTTLOK(c *C, mutations []*kvrpcpb.Mutation, primary string, startTS uint64, ttl uint64) { req := &kvrpcpb.PrewriteRequest{ Mutations: mutations, PrimaryLock: []byte(primary), @@ -656,7 +656,7 @@ func (s *testMVCCLevelDB) TestErrors(c *C) { } func (s *testMVCCLevelDB) TestTxnHeartBeat(c *C) { - s.mustPrewriteOK1(c, putMutations("pk", "val"), "pk", 5, 666) + s.mustPrewriteOKWithTTL(c, putMutations("pk", "val"), "pk", 5, 666) // Update the ttl ttl, err := s.store.TxnHeartBeat([]byte("pk"), 5, 888) diff --git a/store/tikv/lock_test.go b/store/tikv/lock_test.go index d15ace9ab6abd..3f712885a1621 100644 --- a/store/tikv/lock_test.go +++ b/store/tikv/lock_test.go @@ -213,6 +213,10 @@ func (s *testLockSuite) TestTxnHeartBeat(c *C) { c.Assert(err, IsNil) c.Assert(newTTL, Equals, uint64(666)) + newTTL, err = sendTxnHeartBeat(bo, s.store, []byte("key"), txn.StartTS(), 555) + c.Assert(err, IsNil) + c.Assert(newTTL, Equals, uint64(666)) + // The getTxnStatus API is confusing, it really means rollback! status, err := newLockResolver(s.store).getTxnStatus(bo, txn.StartTS(), []byte("key")) c.Assert(err, IsNil) From 5938ccff44566f2207c1a56cd0986d910f190329 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Thu, 5 Sep 2019 17:04:44 +0800 Subject: [PATCH 11/13] go mod tidy --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index 7230900a87171..4e6d74a3a274f 100644 --- a/go.sum +++ b/go.sum @@ -162,8 +162,6 @@ github.com/pingcap/failpoint v0.0.0-20190512135322-30cc7431d99c/go.mod h1:DNS3Qg github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e h1:P73/4dPCL96rGrobssy1nVy2VaVpNCuLpCbr+FEaTA8= github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= github.com/pingcap/kvproto v0.0.0-20190516013202-4cf58ad90b6c/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= -github.com/pingcap/kvproto v0.0.0-20190821201150-798d27658fae h1:WR4d5ga8zXT+QDWYFzzyA+PJMMszR0kQxyYMh6dvHPg= -github.com/pingcap/kvproto v0.0.0-20190821201150-798d27658fae/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/pingcap/kvproto v0.0.0-20190904075355-9a1bd6a31da2 h1:wBORZD4gvEKK0tGP4g1Rv0Y7f2cNnObzI/ckPhsU11M= github.com/pingcap/kvproto v0.0.0-20190904075355-9a1bd6a31da2/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY= github.com/pingcap/log v0.0.0-20190214045112-b37da76f67a7/go.mod h1:xsfkWVaFVV5B8e1K9seWfyJWFrIhbtUTAD8NV1Pq3+w= From 2e368252b659e5ddfc4e992d5fa8360940b5d38b Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Thu, 5 Sep 2019 17:30:24 +0800 Subject: [PATCH 12/13] address comment --- store/mockstore/mocktikv/mvcc_leveldb.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/store/mockstore/mocktikv/mvcc_leveldb.go b/store/mockstore/mocktikv/mvcc_leveldb.go index af280b01257da..d8162f24f42d5 100644 --- a/store/mockstore/mocktikv/mvcc_leveldb.go +++ b/store/mockstore/mocktikv/mvcc_leveldb.go @@ -933,6 +933,9 @@ func (mvcc *MVCCLevelDB) Cleanup(key []byte, startTS uint64) error { // TxnHeartBeat implements the MVCCStore interface. func (mvcc *MVCCLevelDB) TxnHeartBeat(key []byte, startTS uint64, adviseTTL uint64) (uint64, error) { + mvcc.mu.Lock() + defer mvcc.mu.Unlock() + startKey := mvccEncode(key, lockVer) iter := newIterator(mvcc.db, &util.Range{ Start: startKey, From c05f9cb5f5c5e34b75eb233555e4e4db093eff50 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Thu, 5 Sep 2019 19:13:36 +0800 Subject: [PATCH 13/13] fix integration test --- store/tikv/tikvrpc/tikvrpc.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/store/tikv/tikvrpc/tikvrpc.go b/store/tikv/tikvrpc/tikvrpc.go index ce04ce522b397..ccb7b88761644 100644 --- a/store/tikv/tikvrpc/tikvrpc.go +++ b/store/tikv/tikvrpc/tikvrpc.go @@ -430,6 +430,8 @@ func FromBatchCommandsResponse(res *tikvpb.BatchCommandsResponse_Response) *Resp return &Response{Resp: res.PessimisticRollback} case *tikvpb.BatchCommandsResponse_Response_Empty: return &Response{Resp: res.Empty} + case *tikvpb.BatchCommandsResponse_Response_TxnHeartBeat: + return &Response{Resp: res.TxnHeartBeat} } return nil } @@ -633,6 +635,10 @@ func GenRegionErrorResp(req *Request, e *errorpb.Error) (*Response, error) { RegionError: e, } case CmdEmpty: + case CmdTxnHeartBeat: + p = &kvrpcpb.TxnHeartBeatResponse{ + RegionError: e, + } default: return nil, fmt.Errorf("invalid request type %v", req.Type) }