From 3f7860f109599a7149665e842eab9974478353f5 Mon Sep 17 00:00:00 2001 From: Yongbo Jiang Date: Thu, 2 Mar 2023 13:40:57 +0800 Subject: [PATCH] region_request: handle resource group error before Backoff (#719) Signed-off-by: Cabinfever_B Co-authored-by: disksing --- .github/workflows/test.yml | 2 +- config/config.go | 3 - error/error.go | 2 +- go.mod | 4 +- go.sum | 8 +-- integration_tests/go.mod | 8 +-- integration_tests/go.sum | 12 ++-- integration_tests/split_test.go | 13 +++++ internal/locate/region_request.go | 14 ++++- internal/locate/region_request_test.go | 9 +++ internal/mockstore/mocktikv/pd.go | 13 +++++ kv/key.go | 8 +-- tikv/gc.go | 4 +- tikvrpc/interceptor/interceptor.go | 76 ++++++++++++++------------ util/codec/bytes.go | 18 +++--- 15 files changed, 126 insertions(+), 68 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a83875db6d..43edee567a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -47,5 +47,5 @@ jobs: - name: Lint uses: golangci/golangci-lint-action@v2.5.2 with: - version: v1.47.3 + version: v1.51.2 diff --git a/config/config.go b/config/config.go index a4af5bd7b8..b4f0d6d31e 100644 --- a/config/config.go +++ b/config/config.go @@ -44,7 +44,6 @@ import ( "github.com/tikv/client-go/v2/internal/logutil" "github.com/tikv/client-go/v2/oracle" "github.com/tikv/client-go/v2/util" - resourceControlClient "github.com/tikv/pd/client/resource_group/controller" "go.uber.org/zap" ) @@ -79,7 +78,6 @@ type Config struct { TxnScope string EnableAsyncCommit bool Enable1PC bool - ResourceControl resourceControlClient.RequestUnitConfig } // DefaultConfig returns the default configuration. @@ -97,7 +95,6 @@ func DefaultConfig() Config { TxnScope: "", EnableAsyncCommit: false, Enable1PC: false, - ResourceControl: *resourceControlClient.DefaultRequestUnitConfig(), } } diff --git a/error/error.go b/error/error.go index 165130bdd2..761ebef6da 100644 --- a/error/error.go +++ b/error/error.go @@ -246,7 +246,7 @@ type ErrAssertionFailed struct { *kvrpcpb.AssertionFailed } -// ErrLockOnlyIfExistsNoReturnValue is used when the flag `LockOnlyIfExists` of `LockCtx` is set, but `ReturnValues`` is not. +// ErrLockOnlyIfExistsNoReturnValue is used when the flag `LockOnlyIfExists` of `LockCtx` is set, but `ReturnValues“ is not. type ErrLockOnlyIfExistsNoReturnValue struct { StartTS uint64 ForUpdateTs uint64 diff --git a/go.mod b/go.mod index 968af4e218..ddce58c230 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989 - github.com/pingcap/kvproto v0.0.0-20230216153817-c6df78cc9dea + github.com/pingcap/kvproto v0.0.0-20230228041042-1e9aca94bab6 github.com/pingcap/log v1.1.1-0.20221110025148-ca232912c9f3 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 @@ -22,7 +22,7 @@ require ( github.com/stathat/consistent v1.0.0 github.com/stretchr/testify v1.8.1 github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a - github.com/tikv/pd/client v0.0.0-20230224101107-b2f2a8219a40 + github.com/tikv/pd/client v0.0.0-20230301094509-c82b237672a0 github.com/twmb/murmur3 v1.1.3 go.etcd.io/etcd/api/v3 v3.5.2 go.etcd.io/etcd/client/v3 v3.5.2 diff --git a/go.sum b/go.sum index 94e1e22b4e..800367b642 100644 --- a/go.sum +++ b/go.sum @@ -145,8 +145,8 @@ github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c h1:CgbKAHto5CQgW github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c/go.mod h1:4qGtCB0QK0wBzKtFEGDhxXnSnbQApw1gc9siScUl8ew= github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989 h1:surzm05a8C9dN8dIUmo4Be2+pMRb6f55i+UIYrluu2E= github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= -github.com/pingcap/kvproto v0.0.0-20230216153817-c6df78cc9dea h1:Qt8xe4CWgA/pPfYLHwCl8Mz0g7Mbnbhx4l0gVf9eH1w= -github.com/pingcap/kvproto v0.0.0-20230216153817-c6df78cc9dea/go.mod h1:+on3Lfk/fb1lXkud3XvskJumhSIEEgN2TTbMObUlrxE= +github.com/pingcap/kvproto v0.0.0-20230228041042-1e9aca94bab6 h1:bgLRG7gPJCq6aduA65ZV7xWQBThTcuarBB9VdfAzV4g= +github.com/pingcap/kvproto v0.0.0-20230228041042-1e9aca94bab6/go.mod h1:KUrW1FGoznGMMTssYBu0czfAhn6vQcIrHyZoSC6T990= github.com/pingcap/log v1.1.1-0.20221110025148-ca232912c9f3 h1:HR/ylkkLmGdSSDaD8IDP+SZrdhV1Kibl9KrHxJ9eciw= github.com/pingcap/log v1.1.1-0.20221110025148-ca232912c9f3/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -202,8 +202,8 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a h1:J/YdBZ46WKpXsxsW93SG+q0F8KI+yFrcIDT4c/RNoc4= github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a/go.mod h1:h4xBhSNtOeEosLJ4P7JyKXX7Cabg7AVkWCK5gV2vOrM= -github.com/tikv/pd/client v0.0.0-20230224101107-b2f2a8219a40 h1:wZVfR5IsFod5Lym9lgjAaZ9TFsOqZ1iUaxockPacai8= -github.com/tikv/pd/client v0.0.0-20230224101107-b2f2a8219a40/go.mod h1:j94ECCo0drzB/GsMFaUjESjLXNvIbed5PWJXcd8eggo= +github.com/tikv/pd/client v0.0.0-20230301094509-c82b237672a0 h1:1fomIvN2iiKT5uZbe2E6uNHZnRzmS6O47D/PJ9BAuPw= +github.com/tikv/pd/client v0.0.0-20230301094509-c82b237672a0/go.mod h1:4wjAY2NoMn4wx5+hZrEhrSGBs3jvKb+lxfUt+thHFQ4= github.com/twmb/murmur3 v1.1.3 h1:D83U0XYKcHRYwYIpBKf3Pks91Z0Byda/9SJ8B6EMRcA= github.com/twmb/murmur3 v1.1.3/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/integration_tests/go.mod b/integration_tests/go.mod index ba24358955..7034c05a18 100644 --- a/integration_tests/go.mod +++ b/integration_tests/go.mod @@ -6,13 +6,13 @@ require ( github.com/ninedraft/israce v0.0.3 github.com/pingcap/errors v0.11.5-0.20221009092201-b66cddb77c32 github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c - github.com/pingcap/kvproto v0.0.0-20230216153817-c6df78cc9dea + github.com/pingcap/kvproto v0.0.0-20230228041042-1e9aca94bab6 github.com/pingcap/tidb v1.1.0-beta.0.20230207083958-f1d450ff7aa4 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.8.1 github.com/tidwall/gjson v1.14.1 - github.com/tikv/client-go/v2 v2.0.6-0.20230227032358-40a82457ebaa - github.com/tikv/pd/client v0.0.0-20230224101107-b2f2a8219a40 + github.com/tikv/client-go/v2 v2.0.6-0.20230228091502-e2da5527026f + github.com/tikv/pd/client v0.0.0-20230301094509-c82b237672a0 go.uber.org/goleak v1.2.1 ) @@ -100,4 +100,4 @@ require ( replace github.com/tikv/client-go/v2 => ../ -replace github.com/pingcap/tidb => github.com/CabinfeverB/tidb v1.1.0-beta.0.20230228083604-3891a5cff370 +replace github.com/pingcap/tidb => github.com/CabinfeverB/tidb v1.1.0-beta.0.20230301105538-509b40bfd931 diff --git a/integration_tests/go.sum b/integration_tests/go.sum index e6d6990499..a581ad4acd 100644 --- a/integration_tests/go.sum +++ b/integration_tests/go.sum @@ -13,8 +13,8 @@ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.2.0 h1:62Ew5xXg5UCGIXDOM github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/CabinfeverB/tidb v1.1.0-beta.0.20230228083604-3891a5cff370 h1:StesKnCfpo0f8mOLGarim2u2k2Rcx0wLqW8QeVZBWc8= -github.com/CabinfeverB/tidb v1.1.0-beta.0.20230228083604-3891a5cff370/go.mod h1:M4EDri6W+nVYo/Ed+XY80kalq2xM8auH5aRBkfpD3SY= +github.com/CabinfeverB/tidb v1.1.0-beta.0.20230301105538-509b40bfd931 h1:aNr1SbxZMbOs8/Zb2c6oMVdkkIoe8uQtJ9uSVNX8WOc= +github.com/CabinfeverB/tidb v1.1.0-beta.0.20230301105538-509b40bfd931/go.mod h1:IVEQd1UKHbQReFP6vC4tCi0Byhz8SWPSDTmhpZdSU1g= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= @@ -336,8 +336,8 @@ github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c/go.mod h1:4qGtCB github.com/pingcap/fn v0.0.0-20200306044125-d5540d389059 h1:Pe2LbxRmbTfAoKJ65bZLmhahmvHm7n9DUxGRQT00208= github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989 h1:surzm05a8C9dN8dIUmo4Be2+pMRb6f55i+UIYrluu2E= github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= -github.com/pingcap/kvproto v0.0.0-20230216153817-c6df78cc9dea h1:Qt8xe4CWgA/pPfYLHwCl8Mz0g7Mbnbhx4l0gVf9eH1w= -github.com/pingcap/kvproto v0.0.0-20230216153817-c6df78cc9dea/go.mod h1:+on3Lfk/fb1lXkud3XvskJumhSIEEgN2TTbMObUlrxE= +github.com/pingcap/kvproto v0.0.0-20230228041042-1e9aca94bab6 h1:bgLRG7gPJCq6aduA65ZV7xWQBThTcuarBB9VdfAzV4g= +github.com/pingcap/kvproto v0.0.0-20230228041042-1e9aca94bab6/go.mod h1:KUrW1FGoznGMMTssYBu0czfAhn6vQcIrHyZoSC6T990= github.com/pingcap/log v1.1.0/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= github.com/pingcap/log v1.1.1-0.20221116035753-734d527bc87c h1:crhkw6DD+07Bg1wYhW5Piw+kYNKZqFQqfC2puUf6gMI= github.com/pingcap/log v1.1.1-0.20221116035753-734d527bc87c/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= @@ -440,8 +440,8 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tikv/pd/client v0.0.0-20230224101107-b2f2a8219a40 h1:wZVfR5IsFod5Lym9lgjAaZ9TFsOqZ1iUaxockPacai8= -github.com/tikv/pd/client v0.0.0-20230224101107-b2f2a8219a40/go.mod h1:j94ECCo0drzB/GsMFaUjESjLXNvIbed5PWJXcd8eggo= +github.com/tikv/pd/client v0.0.0-20230301094509-c82b237672a0 h1:1fomIvN2iiKT5uZbe2E6uNHZnRzmS6O47D/PJ9BAuPw= +github.com/tikv/pd/client v0.0.0-20230301094509-c82b237672a0/go.mod h1:4wjAY2NoMn4wx5+hZrEhrSGBs3jvKb+lxfUt+thHFQ4= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= diff --git a/integration_tests/split_test.go b/integration_tests/split_test.go index eb18b8827f..89e01b3098 100644 --- a/integration_tests/split_test.go +++ b/integration_tests/split_test.go @@ -41,6 +41,7 @@ import ( "testing" "github.com/pingcap/kvproto/pkg/keyspacepb" + "github.com/pingcap/kvproto/pkg/meta_storagepb" "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/kvproto/pkg/pdpb" "github.com/pkg/errors" @@ -353,3 +354,15 @@ func (c *mockPDClient) GetLocalTSWithinKeyspace(ctx context.Context, dcLocation func (c *mockPDClient) GetLocalTSWithinKeyspaceAsync(ctx context.Context, dcLocation string, keyspaceID uint32) pd.TSFuture { return nil } + +func (c *mockPDClient) Watch(ctx context.Context, key []byte, opts ...pd.OpOption) (chan []*meta_storagepb.Event, error) { + return nil, nil +} + +func (c *mockPDClient) Get(ctx context.Context, key []byte, opts ...pd.OpOption) (*meta_storagepb.GetResponse, error) { + return nil, nil +} + +func (c *mockPDClient) Put(ctx context.Context, key []byte, value []byte, opts ...pd.OpOption) (*meta_storagepb.PutResponse, error) { + return nil, nil +} diff --git a/internal/locate/region_request.go b/internal/locate/region_request.go index 00e2f043e4..d3bd89c970 100644 --- a/internal/locate/region_request.go +++ b/internal/locate/region_request.go @@ -63,6 +63,7 @@ import ( "github.com/tikv/client-go/v2/metrics" "github.com/tikv/client-go/v2/tikvrpc" "github.com/tikv/client-go/v2/util" + pderr "github.com/tikv/pd/client/errs" ) // shuttingDown is a flag to indicate tidb-server is exiting (Ctrl+C signal @@ -462,7 +463,6 @@ func (state *accessByKnownProxy) onNoLeader(selector *replicaSelector) { // tryNewProxy is the state where we try to find a node from followers as proxy. type tryNewProxy struct { - stateBase leaderIdx AccessIndex } @@ -1470,6 +1470,18 @@ func (s *RegionRequestSender) onSendFail(bo *retry.Backoffer, ctx *RPCContext, e } } + // don't need to retry for ResourceGroup error + if errors.Is(err, pderr.ErrClientResourceGroupThrottled) { + return err + } + if errors.Is(err, pderr.ErrClientResourceGroupConfigUnavailable) { + return err + } + var errGetResourceGroup *pderr.ErrClientGetResourceGroup + if errors.As(err, &errGetResourceGroup) { + return err + } + // Retry on send request failure when it's not canceled. // When a store is not available, the leader of related region should be elected quickly. // TODO: the number of retry time should be limited:since region may be unavailable diff --git a/internal/locate/region_request_test.go b/internal/locate/region_request_test.go index b34eb43335..14edffd915 100644 --- a/internal/locate/region_request_test.go +++ b/internal/locate/region_request_test.go @@ -44,6 +44,7 @@ import ( "unsafe" "github.com/pingcap/kvproto/pkg/coprocessor" + "github.com/pingcap/kvproto/pkg/disaggregated" "github.com/pingcap/kvproto/pkg/errorpb" "github.com/pingcap/kvproto/pkg/kvrpcpb" "github.com/pingcap/kvproto/pkg/metapb" @@ -471,6 +472,14 @@ func (s *mockTikvGrpcServer) GetLockWaitHistory(ctx context.Context, request *kv return nil, errors.New("unreachable") } +func (s *mockTikvGrpcServer) TryAddLock(context.Context, *disaggregated.TryAddLockRequest) (*disaggregated.TryAddLockResponse, error) { + return nil, errors.New("unreachable") +} + +func (s *mockTikvGrpcServer) TryMarkDelete(context.Context, *disaggregated.TryMarkDeleteRequest) (*disaggregated.TryMarkDeleteResponse, error) { + return nil, errors.New("unreachable") +} + func (s *mockTikvGrpcServer) KvFlashbackToVersion(context.Context, *kvrpcpb.FlashbackToVersionRequest) (*kvrpcpb.FlashbackToVersionResponse, error) { return nil, errors.New("unreachable") } diff --git a/internal/mockstore/mocktikv/pd.go b/internal/mockstore/mocktikv/pd.go index 2e9cf417c1..d5ac75ad5a 100644 --- a/internal/mockstore/mocktikv/pd.go +++ b/internal/mockstore/mocktikv/pd.go @@ -42,6 +42,7 @@ import ( "time" "github.com/pingcap/kvproto/pkg/keyspacepb" + "github.com/pingcap/kvproto/pkg/meta_storagepb" "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/kvproto/pkg/pdpb" rmpb "github.com/pingcap/kvproto/pkg/resource_manager" @@ -341,3 +342,15 @@ func (c *pdClient) GetLocalTSWithinKeyspace(ctx context.Context, dcLocation stri func (c *pdClient) GetLocalTSWithinKeyspaceAsync(ctx context.Context, dcLocation string, keyspaceID uint32) pd.TSFuture { return nil } + +func (c *pdClient) Watch(ctx context.Context, key []byte, opts ...pd.OpOption) (chan []*meta_storagepb.Event, error) { + return nil, nil +} + +func (c *pdClient) Get(ctx context.Context, key []byte, opts ...pd.OpOption) (*meta_storagepb.GetResponse, error) { + return nil, nil +} + +func (c *pdClient) Put(ctx context.Context, key []byte, value []byte, opts ...pd.OpOption) (*meta_storagepb.PutResponse, error) { + return nil, nil +} diff --git a/kv/key.go b/kv/key.go index 3cd57608c1..11c6edc1eb 100644 --- a/kv/key.go +++ b/kv/key.go @@ -51,10 +51,10 @@ func NextKey(k []byte) []byte { // // Assume there are keys like: // -// rowkey1 -// rowkey1_column1 -// rowkey1_column2 -// rowKey2 +// rowkey1 +// rowkey1_column1 +// rowkey1_column2 +// rowKey2 // // If we seek 'rowkey1' NextKey, we will get 'rowkey1_column1'. // If we seek 'rowkey1' PrefixNextKey, we will get 'rowkey2'. diff --git a/tikv/gc.go b/tikv/gc.go index e6111b2354..d448815ed8 100644 --- a/tikv/gc.go +++ b/tikv/gc.go @@ -37,7 +37,9 @@ import ( // GC does garbage collection (GC) of the TiKV cluster. // GC deletes MVCC records whose timestamp is lower than the given `safepoint`. We must guarantee -// that all transactions started before this timestamp had committed. We can keep an active +// +// that all transactions started before this timestamp had committed. We can keep an active +// // transaction list in application to decide which is the minimal start timestamp of them. // // For each key, the last mutation record (unless it's a deletion) before `safepoint` is retained. diff --git a/tikvrpc/interceptor/interceptor.go b/tikvrpc/interceptor/interceptor.go index 30555d0ce7..9d7e551595 100644 --- a/tikvrpc/interceptor/interceptor.go +++ b/tikvrpc/interceptor/interceptor.go @@ -32,29 +32,33 @@ import ( // // We can implement an RPCInterceptor like this: // ``` -// func LogInterceptor(next InterceptorFunc) RPCInterceptorFunc { -// return func(target string, req *tikvrpc.Request) (*tikvrpc.Response, error) { -// log.Println("before") -// resp, err := next(target, req) -// log.Println("after") -// return resp, err -// } -// } +// +// func LogInterceptor(next InterceptorFunc) RPCInterceptorFunc { +// return func(target string, req *tikvrpc.Request) (*tikvrpc.Response, error) { +// log.Println("before") +// resp, err := next(target, req) +// log.Println("after") +// return resp, err +// } +// } +// // txn.SetRPCInterceptor(LogInterceptor) // ``` // // Or you want to inject some dependent modules: // ``` -// func GetLogInterceptor(lg *log.Logger) RPCInterceptor { -// return func(next RPCInterceptorFunc) RPCInterceptorFunc { -// return func(target string, req *tikvrpc.Request) (*tikvrpc.Response, error) { -// lg.Println("before") -// resp, err := next(target, req) -// lg.Println("after") -// return resp, err -// } -// } -// } +// +// func GetLogInterceptor(lg *log.Logger) RPCInterceptor { +// return func(next RPCInterceptorFunc) RPCInterceptorFunc { +// return func(target string, req *tikvrpc.Request) (*tikvrpc.Response, error) { +// lg.Println("before") +// resp, err := next(target, req) +// lg.Println("after") +// return resp, err +// } +// } +// } +// // txn.SetRPCInterceptor(GetLogInterceptor()) // ``` // @@ -62,8 +66,9 @@ import ( // This is because there may be some exceptions, such as: request batched, no // valid connection etc. If you have questions about the execution location of // RPCInterceptor, please refer to: -// tikv/kv.go#NewKVStore() -// internal/client/client_interceptor.go#SendRequest. +// +// tikv/kv.go#NewKVStore() +// internal/client/client_interceptor.go#SendRequest. type RPCInterceptor func(next RPCInterceptorFunc) RPCInterceptorFunc // RPCInterceptorFunc is a callable function used to initiate a request to TiKV. @@ -77,20 +82,23 @@ type RPCInterceptorFunc func(target string, req *tikvrpc.Request) (*tikvrpc.Resp // // We can use RPCInterceptorChain like this: // ``` -// func Interceptor1(next InterceptorFunc) RPCInterceptorFunc { -// return func(target string, req *tikvrpc.Request) (*tikvrpc.Response, error) { -// fmt.Println("begin-interceptor-1") -// defer fmt.Println("end-interceptor-1") -// return next(target, req) -// } -// } -// func Interceptor2(next InterceptorFunc) RPCInterceptorFunc { -// return func(target string, req *tikvrpc.Request) (*tikvrpc.Response, error) { -// fmt.Println("begin-interceptor-2") -// defer fmt.Println("end-interceptor-2") -// return next(target, req) -// } -// } +// +// func Interceptor1(next InterceptorFunc) RPCInterceptorFunc { +// return func(target string, req *tikvrpc.Request) (*tikvrpc.Response, error) { +// fmt.Println("begin-interceptor-1") +// defer fmt.Println("end-interceptor-1") +// return next(target, req) +// } +// } +// +// func Interceptor2(next InterceptorFunc) RPCInterceptorFunc { +// return func(target string, req *tikvrpc.Request) (*tikvrpc.Response, error) { +// fmt.Println("begin-interceptor-2") +// defer fmt.Println("end-interceptor-2") +// return next(target, req) +// } +// } +// // txn.SetRPCInterceptor(NewRPCInterceptorChain().Link(Interceptor1).Link(Interceptor2).Build()) // ``` // diff --git a/util/codec/bytes.go b/util/codec/bytes.go index 2ba443e076..6282e32922 100644 --- a/util/codec/bytes.go +++ b/util/codec/bytes.go @@ -53,14 +53,18 @@ var ( // EncodeBytes guarantees the encoded value is in ascending order for comparison, // encoding with the following rule: -// [group1][marker1]...[groupN][markerN] -// group is 8 bytes slice which is padding with 0. -// marker is `0xFF - padding 0 count` +// +// [group1][marker1]...[groupN][markerN] +// group is 8 bytes slice which is padding with 0. +// marker is `0xFF - padding 0 count` +// // For example: -// [] -> [0, 0, 0, 0, 0, 0, 0, 0, 247] -// [1, 2, 3] -> [1, 2, 3, 0, 0, 0, 0, 0, 250] -// [1, 2, 3, 0] -> [1, 2, 3, 0, 0, 0, 0, 0, 251] -// [1, 2, 3, 4, 5, 6, 7, 8] -> [1, 2, 3, 4, 5, 6, 7, 8, 255, 0, 0, 0, 0, 0, 0, 0, 0, 247] +// +// [] -> [0, 0, 0, 0, 0, 0, 0, 0, 247] +// [1, 2, 3] -> [1, 2, 3, 0, 0, 0, 0, 0, 250] +// [1, 2, 3, 0] -> [1, 2, 3, 0, 0, 0, 0, 0, 251] +// [1, 2, 3, 4, 5, 6, 7, 8] -> [1, 2, 3, 4, 5, 6, 7, 8, 255, 0, 0, 0, 0, 0, 0, 0, 0, 247] +// // Refer: https://github.com/facebook/mysql-5.6/wiki/MyRocks-record-format#memcomparable-format func EncodeBytes(b []byte, data []byte) []byte { // Allocate more space to avoid unnecessary slice growing.