mirror of https://github.com/tikv/client-go.git
error: handle bucket version not match (#918)
This commit is contained in:
parent
1ea3d66418
commit
ff39b4af09
2
go.mod
2
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-20230720094213-a3b4a77b4333
|
||||
github.com/pingcap/kvproto v0.0.0-20230818065851-7b612d935bf9
|
||||
github.com/pingcap/log v1.1.1-0.20221110025148-ca232912c9f3
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.15.1
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -136,8 +136,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-20230720094213-a3b4a77b4333 h1:A6Wqgq0uMw51UiRAH27TVN0QlzVR5CVtV6fTQSAmvKM=
|
||||
github.com/pingcap/kvproto v0.0.0-20230720094213-a3b4a77b4333/go.mod h1:r0q/CFcwvyeRhKtoqzmWMBebrtpIziQQ9vR+JKh1knc=
|
||||
github.com/pingcap/kvproto v0.0.0-20230818065851-7b612d935bf9 h1:VDoZ18CAXoTUNTCxfl4BjQSD5rJQri8QlH8nu0ZuHeg=
|
||||
github.com/pingcap/kvproto v0.0.0-20230818065851-7b612d935bf9/go.mod h1:r0q/CFcwvyeRhKtoqzmWMBebrtpIziQQ9vR+JKh1knc=
|
||||
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=
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ 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-20230720094213-a3b4a77b4333
|
||||
github.com/pingcap/kvproto v0.0.0-20230818065851-7b612d935bf9
|
||||
github.com/pingcap/tidb v1.1.0-beta.0.20230619015310-8b1006f1af04
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
|
|
|
|||
|
|
@ -363,8 +363,8 @@ github.com/pingcap/fn v1.0.0 h1:CyA6AxcOZkQh52wIqYlAmaVmF6EvrcqFywP463pjA8g=
|
|||
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-20191211054548-3c6b38ea5107/go.mod h1:WWLmULLO7l8IOcQG+t+ItJ3fEcrL5FxF0Wu+HrMy26w=
|
||||
github.com/pingcap/kvproto v0.0.0-20230720094213-a3b4a77b4333 h1:A6Wqgq0uMw51UiRAH27TVN0QlzVR5CVtV6fTQSAmvKM=
|
||||
github.com/pingcap/kvproto v0.0.0-20230720094213-a3b4a77b4333/go.mod h1:r0q/CFcwvyeRhKtoqzmWMBebrtpIziQQ9vR+JKh1knc=
|
||||
github.com/pingcap/kvproto v0.0.0-20230818065851-7b612d935bf9 h1:VDoZ18CAXoTUNTCxfl4BjQSD5rJQri8QlH8nu0ZuHeg=
|
||||
github.com/pingcap/kvproto v0.0.0-20230818065851-7b612d935bf9/go.mod h1:r0q/CFcwvyeRhKtoqzmWMBebrtpIziQQ9vR+JKh1knc=
|
||||
github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7/go.mod h1:8AanEdAHATuRurdGxZXBz0At+9avep+ub7U1AGYLIMM=
|
||||
github.com/pingcap/log v1.1.0/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4=
|
||||
github.com/pingcap/log v1.1.1-0.20230317032135-a0d097d16e22 h1:2SOzvGvE8beiC1Y4g9Onkvu6UmuBBOeWRGQEjJaT/JY=
|
||||
|
|
|
|||
|
|
@ -627,16 +627,17 @@ func (c *RegionCache) SetPDClient(client pd.Client) {
|
|||
|
||||
// RPCContext contains data that is needed to send RPC to a region.
|
||||
type RPCContext struct {
|
||||
Region RegionVerID
|
||||
Meta *metapb.Region
|
||||
Peer *metapb.Peer
|
||||
AccessIdx AccessIndex
|
||||
Store *Store
|
||||
Addr string
|
||||
AccessMode accessMode
|
||||
ProxyStore *Store // nil means proxy is not used
|
||||
ProxyAddr string // valid when ProxyStore is not nil
|
||||
TiKVNum int // Number of TiKV nodes among the region's peers. Assuming non-TiKV peers are all TiFlash peers.
|
||||
Region RegionVerID
|
||||
Meta *metapb.Region
|
||||
Peer *metapb.Peer
|
||||
AccessIdx AccessIndex
|
||||
Store *Store
|
||||
Addr string
|
||||
AccessMode accessMode
|
||||
ProxyStore *Store // nil means proxy is not used
|
||||
ProxyAddr string // valid when ProxyStore is not nil
|
||||
TiKVNum int // Number of TiKV nodes among the region's peers. Assuming non-TiKV peers are all TiFlash peers.
|
||||
BucketVersion uint64
|
||||
|
||||
contextPatcher contextPatcher // kvrpcpb.Context fields that need to be overridden
|
||||
}
|
||||
|
|
@ -1947,6 +1948,26 @@ func (c *RegionCache) getStoresByLabels(labels []*metapb.StoreLabel) []*Store {
|
|||
return s
|
||||
}
|
||||
|
||||
// OnBucketVersionNotMatch removes the old buckets meta if the version is stale.
|
||||
func (c *RegionCache) OnBucketVersionNotMatch(ctx *RPCContext, version uint64, keys [][]byte) {
|
||||
r := c.GetCachedRegionWithRLock(ctx.Region)
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
|
||||
buckets := r.getStore().buckets
|
||||
if buckets == nil || buckets.GetVersion() < version {
|
||||
oldStore := r.getStore()
|
||||
store := oldStore.clone()
|
||||
store.buckets = &metapb.Buckets{
|
||||
Version: version,
|
||||
Keys: keys,
|
||||
RegionId: r.meta.GetId(),
|
||||
}
|
||||
r.compareAndSwapStore(oldStore, store)
|
||||
}
|
||||
}
|
||||
|
||||
// OnRegionEpochNotMatch removes the old region and inserts new regions into the cache.
|
||||
// It returns whether retries the request because it's possible the region epoch is ahead of TiKV's due to slow appling.
|
||||
func (c *RegionCache) OnRegionEpochNotMatch(bo *retry.Backoffer, ctx *RPCContext, currentRegions []*metapb.Region) (bool, error) {
|
||||
|
|
|
|||
|
|
@ -1646,6 +1646,15 @@ func (s *testRegionCacheSuite) TestShouldNotRetryFlashback() {
|
|||
shouldRetry, err = reqSend.onRegionError(s.bo, ctx, nil, &errorpb.Error{FlashbackNotPrepared: &errorpb.FlashbackNotPrepared{}})
|
||||
s.Error(err)
|
||||
s.False(shouldRetry)
|
||||
|
||||
shouldRetry, err = reqSend.onRegionError(s.bo, ctx, nil, &errorpb.Error{BucketVersionNotMatch: &errorpb.BucketVersionNotMatch{Keys: [][]byte{[]byte("a")}, Version: 1}})
|
||||
s.Nil(err)
|
||||
s.False(shouldRetry)
|
||||
ctx.Region.GetID()
|
||||
key, err := s.cache.LocateKey(s.bo, []byte("a"))
|
||||
s.Nil(err)
|
||||
s.Equal(key.Buckets.Keys, [][]byte{[]byte("a")})
|
||||
s.Equal(key.Buckets.Version, uint64(1))
|
||||
}
|
||||
|
||||
func (s *testRegionCacheSuite) TestBackgroundCacheGC() {
|
||||
|
|
|
|||
|
|
@ -2038,6 +2038,17 @@ func (s *RegionRequestSender) onRegionError(
|
|||
return retry, err
|
||||
}
|
||||
|
||||
if bucketVersionNotMatch := regionErr.GetBucketVersionNotMatch(); bucketVersionNotMatch != nil {
|
||||
logutil.Logger(bo.GetCtx()).Debug(
|
||||
"tikv reports `BucketVersionNotMatch` retry later",
|
||||
zap.Stringer("bucketVersionNotMatch", bucketVersionNotMatch),
|
||||
zap.Stringer("ctx", ctx),
|
||||
)
|
||||
// bucket version is not match, we should split this cop request again.
|
||||
s.regionCache.OnBucketVersionNotMatch(ctx, bucketVersionNotMatch.Version, bucketVersionNotMatch.Keys)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if serverIsBusy := regionErr.GetServerIsBusy(); serverIsBusy != nil {
|
||||
if s.replicaSelector != nil && strings.Contains(serverIsBusy.GetReason(), "deadline is exceeded") {
|
||||
s.replicaSelector.onDeadlineExceeded()
|
||||
|
|
|
|||
Loading…
Reference in New Issue