Skip to content

Commit

Permalink
avoid dataIsNotReady error while retrying stale read on the leader
Browse files Browse the repository at this point in the history
Signed-off-by: artem_danilov <artem_danilov@airbnb.com>
  • Loading branch information
artem_danilov committed Apr 12, 2023
1 parent f3e8703 commit b6dc236
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
6 changes: 6 additions & 0 deletions internal/locate/region_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,12 @@ func (s *RegionRequestSender) SendReqCtx(
}
}

if retryTimes > 0 && s.replicaSelector != nil && s.replicaSelector.regionStore != nil &&
s.replicaSelector.targetIdx == s.replicaSelector.regionStore.workTiKVIdx {
// retry on the leader should not use stale read to avoid possible DataIsNotReady error as it always can serve any read
req.StaleRead = false
}

var retry bool
resp, retry, err = s.sendReqToRegion(bo, rpcCtx, req, timeout)
if err != nil {
Expand Down
9 changes: 8 additions & 1 deletion internal/locate/region_request3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -909,8 +909,8 @@ func (s *testRegionRequestToThreeStoresSuite) TestSendReqWithReplicaSelector() {
req = tikvrpc.NewRequest(tikvrpc.CmdGet, &kvrpcpb.GetRequest{Key: []byte("key")})
req.ReadReplicaScope = oracle.GlobalTxnScope
req.TxnScope = oracle.GlobalTxnScope
req.EnableStaleRead()
for i := 0; i < 5; i++ {
req.EnableStaleRead()
// The request may be sent to the leader directly. We have to distinguish it.
failureOnFollower := false
s.regionRequestSender.client = &fnClient{fn: func(ctx context.Context, addr string, req *tikvrpc.Request, timeout time.Duration) (response *tikvrpc.Response, err error) {
Expand All @@ -929,6 +929,13 @@ func (s *testRegionRequestToThreeStoresSuite) TestSendReqWithReplicaSelector() {
totalAttempts += replica.attempts
if idx == int(state.leaderIdx) {
s.Equal(1, replica.attempts)
if failureOnFollower {
// retry always goes to the leader as an ordinary read,not a stale one
s.True(!req.StaleRead)
} else {
// if the first request goes directly to the leader then it keeps stale read flag
s.True(req.StaleRead)
}
} else {
s.True(replica.attempts <= 1)
}
Expand Down

0 comments on commit b6dc236

Please sign in to comment.