Skip to content

Commit f2da0cd

Browse files
committed
handle mismatch peer id
Signed-off-by: you06 <you1474600@gmail.com>
1 parent 44f5025 commit f2da0cd

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

internal/locate/region_request.go

+14
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,8 @@ func regionErrorToLabel(e *errorpb.Error) string {
18821882
return "peer_is_witness"
18831883
} else if isDeadlineExceeded(e) {
18841884
return "deadline_exceeded"
1885+
} else if e.GetMismatchPeerId() != nil {
1886+
return "mismatch_peer_id"
18851887
}
18861888
return "unknown"
18871889
}
@@ -2173,6 +2175,18 @@ func (s *RegionRequestSender) onRegionError(
21732175
s.replicaSelector.onDeadlineExceeded()
21742176
}
21752177

2178+
if mismatch := regionErr.GetMismatchPeerId(); mismatch != nil {
2179+
logutil.Logger(bo.GetCtx()).Warn(
2180+
"tikv reports `MismatchPeerId`, invalidate region cache",
2181+
zap.Uint64("req peer id", mismatch.GetRequestPeerId()),
2182+
zap.Uint64("store peer id", mismatch.GetStorePeerId()),
2183+
)
2184+
if s.replicaSelector != nil {
2185+
s.replicaSelector.invalidateRegion()
2186+
}
2187+
return false, nil
2188+
}
2189+
21762190
logutil.Logger(bo.GetCtx()).Debug(
21772191
"tikv reports region failed",
21782192
zap.Stringer("regionErr", regionErr),

internal/locate/region_request3_test.go

+49
Original file line numberDiff line numberDiff line change
@@ -1376,3 +1376,52 @@ func (s *testRegionRequestToThreeStoresSuite) TestStaleReadFallback2Follower() {
13761376
}
13771377
}
13781378
}
1379+
1380+
func (s *testRegionRequestToThreeStoresSuite) TestReplicaReadFallbackToLeaderRegionError() {
1381+
regionLoc, err := s.cache.LocateRegionByID(s.bo, s.regionID)
1382+
s.Nil(err)
1383+
s.NotNil(regionLoc)
1384+
1385+
s.regionRequestSender.client = &fnClient{fn: func(ctx context.Context, addr string, req *tikvrpc.Request, timeout time.Duration) (response *tikvrpc.Response, err error) {
1386+
select {
1387+
case <-ctx.Done():
1388+
return nil, errors.New("timeout")
1389+
default:
1390+
}
1391+
// Return `mismatch peer id` when accesses the leader.
1392+
if addr == s.cluster.GetStore(s.storeIDs[0]).Address {
1393+
return &tikvrpc.Response{Resp: &kvrpcpb.GetResponse{RegionError: &errorpb.Error{
1394+
MismatchPeerId: &errorpb.MismatchPeerId{
1395+
RequestPeerId: 1,
1396+
StorePeerId: 2,
1397+
},
1398+
}}}, nil
1399+
}
1400+
return &tikvrpc.Response{Resp: &kvrpcpb.GetResponse{RegionError: &errorpb.Error{
1401+
DataIsNotReady: &errorpb.DataIsNotReady{},
1402+
}}}, nil
1403+
}}
1404+
1405+
region := s.cache.getRegionByIDFromCache(regionLoc.Region.GetID())
1406+
s.True(region.isValid())
1407+
1408+
req := tikvrpc.NewReplicaReadRequest(tikvrpc.CmdGet, &kvrpcpb.GetRequest{Key: []byte("key")}, kv.ReplicaReadLeader, nil)
1409+
req.ReadReplicaScope = oracle.GlobalTxnScope
1410+
req.TxnScope = oracle.GlobalTxnScope
1411+
req.EnableStaleRead()
1412+
req.ReplicaReadType = kv.ReplicaReadFollower
1413+
1414+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
1415+
defer cancel()
1416+
bo := retry.NewBackoffer(ctx, -1)
1417+
s.Nil(err)
1418+
resp, _, _, err := s.regionRequestSender.SendReqCtx(bo, req, regionLoc.Region, time.Second, tikvrpc.TiKV)
1419+
s.Nil(err)
1420+
regionErr, err := resp.GetRegionError()
1421+
s.Nil(err)
1422+
s.Equal(regionErrorToLabel(regionErr), "mismatch_peer_id")
1423+
// return non-epoch-not-match region error and the upper layer can auto retry.
1424+
s.Nil(regionErr.GetEpochNotMatch())
1425+
// after region error returned, the region should be invalidated.
1426+
s.False(region.isValid())
1427+
}

0 commit comments

Comments
 (0)