Skip to content

Commit 9dd1b8e

Browse files
authored
region_cache: support fall back to leader handle when using ScanRegions/BatchScanRegions (#1794)
close #1793 Signed-off-by: okjiang <819421878@qq.com>
1 parent 80fad8c commit 9dd1b8e

File tree

1 file changed

+41
-8
lines changed

1 file changed

+41
-8
lines changed

internal/locate/region_cache.go

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)