#20068·tikv

load-base split: DESC ranges can be swapped twice; delayed ReadStats windows over-count QPS

Author: lhy1024Created Sep 8, 2026Updated Sep 8, 2026

Background

Found while reviewing the CSE port of load-base split. Both issues exist on TiKV master as well; they are not CSE-specific.

1. DESC / reverse scan key ranges can be reversed twice

build_key_range(start, end, reverse_scan=true) swaps start and end:

https://github.com/tikv/tikv/blob/master/components/raftstore/src/store/util.rs

Callers then pass reverse_scan again even when the bounds are already [low, high):

  • Coprocessor tracker uses ReqContext.lower_bound / upper_bound (first range start / last range end) together with is_desc_scan.
  • KV reverse scan may already normalize CPU tags to (end, start) and then call build_key_range(..., reverse_scan).

If the producer already has ordered bounds, the second swap stores start > end in sampled KeyRanges. Scoring (left / right / contained) then treats the span backwards.

Fixing this needs per-producer tests (cop DESC vs KV reverse scan, empty end = unbounded). Do not blindly swap whenever start > end.

2. Delayed ReadStats windows over-count per-second QPS/bytes

Each RegionInfo converts its counters to a per-second rate using report_interval. AutoSplitController::flush then sums those rates across every RegionInfo for the Region (all threads, and any delayed windows drained in the same tick).

On-time 1s reports from N threads: summing rates is approximately store-wide QPS (correct).

If two 1s windows from the same TLS pile up and flush together, both already-normalized rates are added, so the Region looks ~2x as hot.

Dividing by the number of reports is wrong (thread count and delayed windows are mixed). A real fix needs wall-clock window union or timestamps on each ReadStats, not a one-line average.

Ask

Track these as follow-up load-base split correctness issues. They should not block CSE-only hardening.