Wait with spin backoff instead of a one-shot trylock in the deleted page skip check

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Major - P3
    • WT12.0.0
    • Affects Version/s: None
    • Component/s: Btree
    • None
    • Storage Engines - Transactions
    • 20.697
    • SE Transactions - 2026-08-14
    • 3

      Summary

      WT-17802 replaced the blocking WT_REF_LOCK in __wt_btcur_skip_page with a one-shot WT_REF_TRYLOCK, abandoning the deleted-page skip whenever the ref was momentarily held. That fixed a sched_yield storm (HELP-94648) but introduced a 95th percentile latency regression (BF-44998, +8.89% on FindNotThere in mass_delete_regression_locust).

      This ticket restores always-acquire semantics using __wt_spin_backoff rather than WT_REF_LOCK, and adds two statistics so contention on this path is visible in future.

      Why the storm does not come back

      WT_REF_LOCK is implemented as for (;; __wt_yield()) — it issues a sched_yield syscall on every iteration, from the first. That is the storm mechanism itself.

      __wt_spin_backoff is three-tiered: the first 10 iterations are pure spin with no syscall, iterations 10-999 yield, and beyond that it sleeps in increments capped at 1000us, which takes the thread off the runqueue rather than leaving it competing for CPU. The waiting strategy is mechanically different from the reverted code, not merely bounded.

      Change

      skip_sleep_usecs = skip_yield_count = 0;
      while (WT_REF_TRYLOCK(session, ref, &previous_state) != 0)
          __wt_spin_backoff(&skip_yield_count, &skip_sleep_usecs);
      

      Statistics

      Two new cursor statistics, aggregated through the existing WT_PAGE_WALK_SKIP_STATS structure so no statistics macro is touched inside the wait loop:

      • skips that had to wait for the lock at all (event count)
      • total backoff iterations across those waits

      Their ratio is the average number of backoff iterations per contended skip. Because the backoff ladder is deterministic, that ratio also indicates which tier is being reached: a ratio approaching 1000 means the sleep tier is in use, which is the early signal of the condition HELP-94648 reported. One pair of counters therefore covers both failure modes — the latency regression and the CPU storm.

       

            Assignee:
            Shoufu Du
            Reporter:
            Shoufu Du
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: