Repository navigation
Query Store reads on the stored interval tables no longer miss an interval that began just before the table's floor (#5541) - #5543
Merged
Conversation
…margin before reading the table (#5541)
…and the table floor always comes from the per-server minimum (#5541) The Wide raw read counts a snapshot by collection_time alone, so a snapshot collected at or after the window start can belong to an interval that began down to S - 26 h. Clause 3b used S - 1 day and left a one-hour hole; it now uses S - PurgeEdgeMargin. Neither interval table is a hypertable in production (retention purges both with a sliced DELETE), and a catalog chunk floor would sit far below the real one because emptied chunks stay listed. Both rules now always read H as the per-server MIN(first_execution_time); the chunk-catalog read keeps only raw's floor. Stale one-day wording in the docs now says 26 h.
erikdarlingdata
marked this pull request as ready for review
October 8, 2026 07:03
12 of 14 tasks
This was referenced Oct 8, 2026
erikdarlingdata
added a commit
that referenced
this pull request
Oct 8, 2026
Adds the changelog entries for the 3.10.0 PRs that merged after the first splice: #5528, #5532, #5537, #5542, #5543, #5552 and #5553. Each full entry goes into docs/changelog/3.10.md and its title-only line into the CHANGELOG.md index. The archive census row for 3.10.0 moves from 257 to 265 entries. Changelog entries for the 3.10.0 PRs merged after the first splice.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5541
Why
The Query Store read gates for the plan regression / drill-down reads (
QueryStoreIntervalLatest.UseTable) and the grid / MCP top reads (QueryStoreIntervalWide.UseTable) took the stored interval table when raw's floor R was at or above the table's floor H. Raw purges a snapshot bycollection_time; the interval tables purge an interval byfirst_execution_time. So raw could still hold a snapshot (collection_time >= R) of an interval that began below H and that the table had dropped. With R >= H the read used the table and left that interval out.What changes
R >= H + QueryStoreIntervalWide.PurgeEdgeMarginin both rules.PurgeEdgeMargin(26 h = one interval span of 1 day + the slowest below-floor cadence of 60 min + the collector catch-up cap of 1 h) is the bound the code already documents: the collector keeps only intervals withend_time > cutoff, the cutoff is at mostMaxCatchupbefore the row'scollection_time, backfill slices are capped, sofirst_execution_time > collection_time - (1 day + MaxCatchup). The Wide below-floor read already usesH + PurgeEdgeMarginfor the same reason. Both rules share the constant.S - IntervalSpanMargin(1 day). The Wide raw read filters oncollection_timeonly, so a snapshot collected at or after the window start S can belong to an interval that began down to S - 26 h, which left a one-hour hole. 3b now usesS - PurgeEdgeMargin. This case can happen on default retention (raw keeps 30 days, so 3a never passes there and 3b decides): it needs a 1440-minute Query Store interval and a window start in a one-hour band just above the table's oldest data (the review's input: H = S - 24 h). The Latest rule's 3b is unchanged and sound: its raw read also filterslast_execution_time >= $2, which keeps every counted interval's first execution at or above B. A comment in that rule's doc now says so.MIN(first_execution_time)(PlainTableFloorSql) in both rules, including the Wide cached-inputs path. The chunk-catalog read (ChunkFloorsSql, renamedRawChunkFloorSql) returns only raw's floor; thetable_is_hypertablearm and the cached table-floor fields are gone. The earlier "Observed: the hypertable is by_range(first_execution_time)" claim came from test fixtures that convert the table by hand, not from production, and is withdrawn.QueryStoreIntervalWide(the ExactBelowFloorStart doc, the clamp note and theIntervalSpanMargindoc) and inDarlingRetention(two comments) now says 26 h / the purge-edge margin. Test comments that named the old one-day floor were updated too.Test plan
QueryStoreIntervalWideGateTests:Clause3_TableFloorShortOfThePurgeEdgeMargin_ReadsRaw,Clause3_ReviewFailingInput_...(the review's input),Clause3_TableFloorAtOrBeyondThePurgeEdgeMargin_ReadsTheTable. The old one-day pins are replaced; the 3a tests from round 1 stay.S - IntervalSpanMargin(the previous head's rule) and the new tests in place,Clause3_ReviewFailingInput_...andClause3_TableFloorShortOfThePurgeEdgeMargin_ReadsRawfail (Total 33, Failed 2); with the fix they pass.UseTable,PlainTableFloorSql, the floor SQL,PurgeEdgeMarginorResolveReadAsync, plus*QueryStoreIntervalWide*,*PlanRegression*,*QueryStoreTop*,*RawWindowFloor*,*ReadScope*,*DarlingMcpQueryStoreHistory*,*QueryStoreIntervalLatest*: Total 619, Failed 0, Skipped 1.*Census*,*Ratchet*,*Hygiene*,*Pin*,*Guard*,*Scan*,*DocComment*,RepoFileAdoptionTests,FleetIdentifierScrubTests,RegisteredServerSettingDriftTests,TsqlConventionGuardTests: Total 1690, Failed 0, Skipped 2.raw_floortext only now (the hypertable column is gone from that statement); they still count one read per check.Measurements
None from a store. On the default store (raw 30 days, table 9 to 15 days) 3a never passes, so the Wide read decides on 3b, which is where the one-hour hole was.
Changelog
SECTION: Fixed
ENTRY:
REF:
[Query Store reads on the stored interval tables no longer miss an interval that began just before the table's floor (#5541) #5543]: Query Store reads on the stored interval tables no longer miss an interval that began just before the table's floor (#5541) #5543