@@ -1376,3 +1376,52 @@ func (s *testRegionRequestToThreeStoresSuite) TestStaleReadFallback2Follower() {
1376
1376
}
1377
1377
}
1378
1378
}
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