diff --git a/error/error.go b/error/error.go index 3d7272d4..82a8c3d8 100644 --- a/error/error.go +++ b/error/error.go @@ -91,6 +91,8 @@ var ( ErrRegionRecoveryInProgress = errors.New("region is being online unsafe recovered") // ErrRegionFlashbackInProgress is the error when a region in the flashback progress receive any other request. ErrRegionFlashbackInProgress = errors.New("region is in the flashback progress") + // ErrRegionFlashbackNotPrepared is the error when a region is not prepared for the flashback first. + ErrRegionFlashbackNotPrepared = errors.New("region is not prepared for the flashback") // ErrUnknown is the unknow error. ErrUnknown = errors.New("unknow") // ErrResultUndetermined is the error when execution result is unknown. diff --git a/go.mod b/go.mod index f6d0c533..6991a556 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 github.com/pingcap/failpoint v0.0.0-20210918120811-547c13e3eb00 github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989 - github.com/pingcap/kvproto v0.0.0-20220929075948-06e08d5ed64c + github.com/pingcap/kvproto v0.0.0-20221014081430-26e28e6a281a github.com/pingcap/log v0.0.0-20211215031037-e024ba4eb0ee github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.11.0 diff --git a/go.sum b/go.sum index c975e110..4ab28467 100644 --- a/go.sum +++ b/go.sum @@ -157,6 +157,8 @@ github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989/go.mod h1:O17Xtb github.com/pingcap/kvproto v0.0.0-20220510035547-0e2f26c0a46a/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= github.com/pingcap/kvproto v0.0.0-20220929075948-06e08d5ed64c h1:ceg4xjEEXNgPsScTQ5dtidiltLF4h17Y/jUqfyLAy9E= github.com/pingcap/kvproto v0.0.0-20220929075948-06e08d5ed64c/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= +github.com/pingcap/kvproto v0.0.0-20221014081430-26e28e6a281a h1:McYxPhA8SHqfUtLfQHHN0fQl4dy93IkhlX4Pp2MKIFA= +github.com/pingcap/kvproto v0.0.0-20221014081430-26e28e6a281a/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= github.com/pingcap/log v0.0.0-20211215031037-e024ba4eb0ee h1:VO2t6IBpfvW34TdtD/G10VvnGqjLic1jzOuHjUb5VqM= github.com/pingcap/log v0.0.0-20211215031037-e024ba4eb0ee/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/integration_tests/go.mod b/integration_tests/go.mod index 1bddb8b1..cd9768a8 100644 --- a/integration_tests/go.mod +++ b/integration_tests/go.mod @@ -6,7 +6,7 @@ require ( github.com/ninedraft/israce v0.0.3 github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c github.com/pingcap/failpoint v0.0.0-20220423142525-ae43b7f4e5c3 - github.com/pingcap/kvproto v0.0.0-20220929075948-06e08d5ed64c + github.com/pingcap/kvproto v0.0.0-20221014081430-26e28e6a281a github.com/pingcap/tidb v1.1.0-beta.0.20220902042024-0482b2e83ed2 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.8.0 diff --git a/integration_tests/go.sum b/integration_tests/go.sum index 733a8b68..6366cb17 100644 --- a/integration_tests/go.sum +++ b/integration_tests/go.sum @@ -301,8 +301,8 @@ github.com/pingcap/fn v0.0.0-20200306044125-d5540d389059 h1:Pe2LbxRmbTfAoKJ65bZL 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-20220510035547-0e2f26c0a46a/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= -github.com/pingcap/kvproto v0.0.0-20220929075948-06e08d5ed64c h1:ceg4xjEEXNgPsScTQ5dtidiltLF4h17Y/jUqfyLAy9E= -github.com/pingcap/kvproto v0.0.0-20220929075948-06e08d5ed64c/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= +github.com/pingcap/kvproto v0.0.0-20221014081430-26e28e6a281a h1:McYxPhA8SHqfUtLfQHHN0fQl4dy93IkhlX4Pp2MKIFA= +github.com/pingcap/kvproto v0.0.0-20221014081430-26e28e6a281a/go.mod h1:OYtxs0786qojVTmkVeufx93xe+jUgm56GUYRIKnmaGI= github.com/pingcap/log v0.0.0-20200511115504-543df19646ad/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= github.com/pingcap/log v0.0.0-20211215031037-e024ba4eb0ee/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= github.com/pingcap/log v1.1.0 h1:ELiPxACz7vdo1qAvvaWJg1NrYFoY6gqAh/+Uo6aXdD8= diff --git a/internal/locate/region_cache_test.go b/internal/locate/region_cache_test.go index 342e07df..3e92ac94 100644 --- a/internal/locate/region_cache_test.go +++ b/internal/locate/region_cache_test.go @@ -1593,7 +1593,7 @@ func (s *testRegionCacheSuite) TestRemoveIntersectingRegions() { s.checkCache(1) } -func (s *testRegionCacheSuite) TestShouldNotRetryFlashbackInProgress() { +func (s *testRegionCacheSuite) TestShouldNotRetryFlashback() { loc, err := s.cache.LocateKey(s.bo, []byte("a")) s.NotNil(loc) s.NoError(err) @@ -1604,4 +1604,7 @@ func (s *testRegionCacheSuite) TestShouldNotRetryFlashbackInProgress() { shouldRetry, err := reqSend.onRegionError(s.bo, ctx, nil, &errorpb.Error{FlashbackInProgress: &errorpb.FlashbackInProgress{}}) s.Error(err) s.False(shouldRetry) + shouldRetry, err = reqSend.onRegionError(s.bo, ctx, nil, &errorpb.Error{FlashbackNotPrepared: &errorpb.FlashbackNotPrepared{}}) + s.Error(err) + s.False(shouldRetry) } diff --git a/internal/locate/region_request.go b/internal/locate/region_request.go index 2b640cdb..8a1cc198 100644 --- a/internal/locate/region_request.go +++ b/internal/locate/region_request.go @@ -1391,6 +1391,8 @@ func regionErrorToLabel(e *errorpb.Error) string { return "recovery_in_progress" } else if e.GetFlashbackInProgress() != nil { return "flashback_in_progress" + } else if e.GetFlashbackNotPrepared() != nil { + return "flashback_not_prepared" } return "unknown" } @@ -1455,6 +1457,13 @@ func (s *RegionRequestSender) onRegionError(bo *retry.Backoffer, ctx *RPCContext logutil.BgLogger().Debug("tikv reports `FlashbackInProgress`", zap.Stringer("req", req), zap.Stringer("ctx", ctx)) return false, errors.Errorf("region %d is in flashback progress", regionErr.GetFlashbackInProgress().GetRegionId()) } + // This error means a second-phase flashback request is sent to a region that is not + // prepared for the flashback before, it should stop retrying immediately to avoid + // unnecessary backoff. + if regionErr.GetFlashbackNotPrepared() != nil { + logutil.BgLogger().Debug("tikv reports `FlashbackNotPrepared`", zap.Stringer("req", req), zap.Stringer("ctx", ctx)) + return false, errors.Errorf("region %d is not prepared for the flashback", regionErr.GetFlashbackNotPrepared().GetRegionId()) + } // This peer is removed from the region. Invalidate the region since it's too stale. if regionErr.GetRegionNotFound() != nil {