mirror of https://github.com/tikv/client-go.git
				
				
				
			region_request: handle resource group error before Backoff (#719)
Signed-off-by: Cabinfever_B <cabinfeveroier@gmail.com> Co-authored-by: disksing <i@disksing.com>
This commit is contained in:
		
							parent
							
								
									e2da552702
								
							
						
					
					
						commit
						3f7860f109
					
				| 
						 | 
				
			
			@ -47,5 +47,5 @@ jobs:
 | 
			
		|||
      - name: Lint
 | 
			
		||||
        uses: golangci/golangci-lint-action@v2.5.2
 | 
			
		||||
        with:
 | 
			
		||||
          version: v1.47.3
 | 
			
		||||
          version: v1.51.2
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										4
									
								
								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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										8
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										8
									
								
								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=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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")
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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'.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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())
 | 
			
		||||
// ```
 | 
			
		||||
//
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue