Skip to content

The wide-grid short-window pin flushes pending table stats before it counts reads - #4449

Merged
erikdarlingdata merged 2 commits into
devfrom
test/qsiw-short-window-read-count-deflake
Sep 26, 2026
Merged

erikdarlingdata merged 2 commits into
devfrom
test/qsiw-short-window-read-count-deflake

Conversation

@erikdarlingdata

Copy link
Copy Markdown
Owner

Refs #4310. Test-only; no product code touched.

Why

QueryStoreIntervalWideGridLiveTests.ShortWindowRead_IssuesNoRoundTripAgainstTheWideTable proves that a
short-window Query Store grid read issues zero round trips against collect.query_store_interval_wide, by
snapshotting pg_stat_user_tables.seq_scan/idx_scan before and after the read under test. It failed once in
CI with Expected (0, 9), Actual (1, 9) and passed on a re-run with no code change.

PostgreSQL throttles a backend's cumulative-stats report to at most once per second
(PGSTAT_MIN_INTERVAL). The test's own setup issues real scans against the wide table from a different
backend (the seed runner's own connection). If that backend's pending report has not flushed yet when the
test takes its "before" snapshot, and flushes moments later, the "after" snapshot picks up a scan the test
under test never issued — a stats-visibility race, not a defect in the code the test exercises.

What changes

Darling/Darling.Tests/QueryStoreIntervalWideGridLiveTests.cs:

  • Before the "before" snapshot, force every backend that touched the wide table during setup
    (this test's own connection and the seed runner's pooled data source) to report its pending stats
    immediately with pg_stat_force_next_flush(), so "before" reflects setup's scans completely rather than
    a partially-flushed view of them.
  • Before the "after" snapshot, force this test's own connection's stats to report, so a real regression is
    still visible immediately.
  • The end-to-end read runs through the viewer's own pooled data source, which this test cannot call
    pg_stat_force_next_flush() on directly. A short delay (1.1s, longer than the once-per-second throttle)
    stands in for a flush on that connection — the documented fallback shape for this class of flake when the
    product read doesn't go through an instrumentable data source.
  • No product code changes. The doc comment above the test now explains the flush ordering and why it is
    needed.

Test plan

  • Both Darling.Tests and Lite.Tests build 0 errors / 0 warnings.
  • ShortWindowRead_IssuesNoRoundTripAgainstTheWideTable run 20 times in a loop against a fresh
    timescale/timescaledb:2.30.1-pg18 container: 20/20 green.
  • The whole QueryStoreIntervalWideGridLiveTests class plus DocCommentHygieneTests: 81/81 green.
  • A real mutation: temporarily replaced the gate's minimum-window refusal
    (windowEnd - windowStart < minWindow) with false, forcing a short window to route to the table. The
    pin went RED (Expected (1, 9), Actual (1, 10)), proving it still catches the bug it exists for. Reverted;
    clean diff confirmed against the committed source; rebuilt 0 errors.

CHANGELOG entry

SECTION: None
ENTRY: None: test-only de-flake, no user-visible effect.

…h timing

ShortWindowRead_IssuesNoRoundTripAgainstTheWideTable counts reads with
pg_stat_user_tables.seq_scan before and after the call under test.
PostgreSQL throttles a backend's cumulative-stats report to once per
second (PGSTAT_MIN_INTERVAL), so a seed backend's own scan against the
wide table can still be pending when the "before" snapshot is taken and
land only after it, producing a spurious (0,9) vs (1,9) mismatch with
nothing wrong in the code under test.

Force every backend that touched the table during setup to report its
pending stats (pg_stat_force_next_flush()) before the "before" snapshot,
and this test's own backend again before the "after" snapshot. The
viewer's read runs on its own pooled data source this test cannot flush
directly, so a short delay stands in for a flush there, long enough to
clear the once-per-second throttle.
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review September 26, 2026 20:59
@erikdarlingdata
erikdarlingdata merged commit 33252ff into dev Sep 26, 2026
15 of 16 checks passed
@erikdarlingdata
erikdarlingdata deleted the test/qsiw-short-window-read-count-deflake branch September 26, 2026 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant