diff --git a/internal/locate/region_request.go b/internal/locate/region_request.go index 12c036809..0f29bb4ac 100644 --- a/internal/locate/region_request.go +++ b/internal/locate/region_request.go @@ -785,6 +785,12 @@ func (state *accessFollower) next(bo *retry.Backoffer, selector *replicaSelector } return nil, stateChanged{} } + for _, r := range selector.replicas { + if r.deadlineErrUsingConfTimeout { + // when meet deadline exceeded error, do fast retry without invalidate region cache. + return nil, nil + } + } metrics.TiKVReplicaSelectorFailureCounter.WithLabelValues("exhausted").Inc() selector.invalidateRegion() return nil, nil diff --git a/internal/locate/replica_selector_test.go b/internal/locate/replica_selector_test.go index 30bffb081..4a9f17b3d 100644 --- a/internal/locate/replica_selector_test.go +++ b/internal/locate/replica_selector_test.go @@ -184,6 +184,28 @@ func TestReplicaReadAccessPathByCase(t *testing.T) { } s.True(s.runCaseAndCompare(ca)) + // Don't invalid region in accessFollower, since leader meets deadlineExceededErr. + ca = replicaSelectorAccessPathCase{ + reqType: tikvrpc.CmdGet, + readType: kv.ReplicaReadMixed, + staleRead: false, + timeout: time.Second, + label: nil, + accessErr: []RegionErrorType{ServerIsBusyErr, ServerIsBusyErr, DeadLineExceededErr}, + expect: &accessPathResult{ + accessPath: []string{ + "{addr: store1, replica-read: true, stale-read: false}", + "{addr: store2, replica-read: true, stale-read: false}", + "{addr: store3, replica-read: true, stale-read: false}"}, + respErr: "", + respRegionError: fakeEpochNotMatch, + backoffCnt: 0, + backoffDetail: []string{}, + regionIsValid: true, + }, + } + s.True(s.runCaseAndCompare(ca)) + // Don't invalid region in tryFollowers, since leader meets deadlineExceededErr. ca = replicaSelectorAccessPathCase{ reqType: tikvrpc.CmdGet,