@@ -2370,6 +2370,7 @@ func (c *RegionCache) scanRegions(bo *retry.Backoffer, startKey, endKey []byte,
23702370 ctx = opentracing .ContextWithSpan (ctx , span1 )
23712371 }
23722372
2373+ pdOpts := []opt.GetRegionOption {opt .WithAllowFollowerHandle ()}
23732374 var backoffErr error
23742375 for {
23752376 if backoffErr != nil {
@@ -2380,7 +2381,7 @@ func (c *RegionCache) scanRegions(bo *retry.Backoffer, startKey, endKey []byte,
23802381 }
23812382 start := time .Now ()
23822383 // TODO: ScanRegions has been deprecated in favor of BatchScanRegions.
2383- regionsInfo , err := c .pdClient .ScanRegions (withPDCircuitBreaker (ctx ), startKey , endKey , limit , opt . WithAllowFollowerHandle () )
2384+ regionsInfo , err := c .pdClient .ScanRegions (withPDCircuitBreaker (ctx ), startKey , endKey , limit , pdOpts ... )
23842385 metrics .LoadRegionCacheHistogramWithRegions .Observe (time .Since (start ).Seconds ())
23852386 if err != nil {
23862387 if apicodec .IsDecodeError (err ) {
@@ -2399,10 +2400,18 @@ func (c *RegionCache) scanRegions(bo *retry.Backoffer, startKey, endKey []byte,
23992400
24002401 if len (regionsInfo ) == 0 {
24012402 backoffErr = errors .Errorf ("PD returned no region, limit: %d" , limit )
2403+ metrics .TiKVStaleRegionFromPDCounter .Inc ()
2404+ if len (pdOpts ) > 0 {
2405+ pdOpts = nil
2406+ }
24022407 continue
24032408 }
24042409 if regionsHaveGapInRanges ([]router.KeyRange {{StartKey : startKey , EndKey : endKey }}, regionsInfo , limit ) {
24052410 backoffErr = errors .Errorf ("PD returned regions have gaps, limit: %d" , limit )
2411+ metrics .TiKVStaleRegionFromPDCounter .Inc ()
2412+ if len (pdOpts ) > 0 {
2413+ pdOpts = nil
2414+ }
24062415 continue
24072416 }
24082417 validRegions , err := c .handleRegionInfos (bo , regionsInfo , true )
@@ -2414,6 +2423,10 @@ func (c *RegionCache) scanRegions(bo *retry.Backoffer, startKey, endKey []byte,
24142423 // Retry if there is no valid regions with leaders.
24152424 if len (validRegions ) == 0 {
24162425 backoffErr = errors .Errorf ("All returned regions have no leaders, limit: %d" , limit )
2426+ metrics .TiKVStaleRegionFromPDCounter .Inc ()
2427+ if len (pdOpts ) > 0 {
2428+ pdOpts = nil
2429+ }
24172430 continue
24182431 }
24192432 return validRegions , nil
@@ -2435,23 +2448,31 @@ func (c *RegionCache) batchScanRegions(bo *retry.Backoffer, keyRanges []router.K
24352448 for _ , op := range opts {
24362449 op (& batchOpt )
24372450 }
2451+ needFollowerHandle := true
2452+ initPdOpts := func () []opt.GetRegionOption {
2453+ pdOpts := []opt.GetRegionOption {
2454+ opt .WithOutputMustContainAllKeyRange (),
2455+ }
2456+ if needFollowerHandle {
2457+ pdOpts = append (pdOpts , opt .WithAllowFollowerHandle ())
2458+ }
2459+ if batchOpt .needBuckets {
2460+ pdOpts = append (pdOpts , opt .WithBuckets ())
2461+ }
2462+ return pdOpts
2463+ }
24382464 // TODO: return start key and end key after redact is introduced.
24392465 var backoffErr error
24402466 for {
2467+ pdOpts := initPdOpts ()
2468+
24412469 if backoffErr != nil {
24422470 err := bo .Backoff (retry .BoPDRPC , backoffErr )
24432471 if err != nil {
24442472 return nil , errors .WithStack (err )
24452473 }
24462474 }
24472475 start := time .Now ()
2448- pdOpts := []opt.GetRegionOption {
2449- opt .WithAllowFollowerHandle (),
2450- opt .WithOutputMustContainAllKeyRange (),
2451- }
2452- if batchOpt .needBuckets {
2453- pdOpts = append (pdOpts , opt .WithBuckets ())
2454- }
24552476 regionsInfo , err := c .pdClient .BatchScanRegions (withPDCircuitBreaker (ctx ), keyRanges , limit , pdOpts ... )
24562477 metrics .LoadRegionCacheHistogramWithBatchScanRegions .Observe (time .Since (start ).Seconds ())
24572478 if err != nil {
@@ -2477,13 +2498,21 @@ func (c *RegionCache) batchScanRegions(bo *retry.Backoffer, keyRanges []router.K
24772498 "PD returned no region, range num: %d, limit: %d" ,
24782499 len (keyRanges ), limit ,
24792500 )
2501+ metrics .TiKVStaleRegionFromPDCounter .Inc ()
2502+ if needFollowerHandle {
2503+ needFollowerHandle = false
2504+ }
24802505 continue
24812506 }
24822507 if regionsHaveGapInRanges (keyRanges , regionsInfo , limit ) {
24832508 backoffErr = errors .Errorf (
24842509 "PD returned regions have gaps, range num: %d, limit: %d" ,
24852510 len (keyRanges ), limit ,
24862511 )
2512+ metrics .TiKVStaleRegionFromPDCounter .Inc ()
2513+ if needFollowerHandle {
2514+ needFollowerHandle = false
2515+ }
24872516 continue
24882517 }
24892518 validRegions , err := c .handleRegionInfos (bo , regionsInfo , batchOpt .needRegionHasLeaderPeer )
@@ -2495,6 +2524,10 @@ func (c *RegionCache) batchScanRegions(bo *retry.Backoffer, keyRanges []router.K
24952524 // Retry if there is no valid regions with leaders.
24962525 if len (validRegions ) == 0 {
24972526 backoffErr = errors .Errorf ("All returned regions have no leaders, limit: %d" , limit )
2527+ metrics .TiKVStaleRegionFromPDCounter .Inc ()
2528+ if needFollowerHandle {
2529+ needFollowerHandle = false
2530+ }
24982531 continue
24992532 }
25002533 return validRegions , nil
0 commit comments