Repository navigation
Custom Views Query Store panels read the per-interval table instead of re-sorting raw snapshots (#4605) - #4617
Merged
Merged
Conversation
…of deduping raw Part of #4605.
…4605) Adds ComposeQueryStoreWideExactnessLiveTests, a live-Postgres test that seeds two servers with Query Store rows through the real collector write path (hour-spanning intervals, mixed Regular/Aborted/Exception outcomes, a re-fetched open interval, module names for a LIKE filter), then compiles and runs the same Compose panel twice through the real compiler -- once forced to raw, once forced to the query_store_interval_wide route -- and asserts the rows come back identical across a ranked SUM, a minute-grain time series, an hour-grain LIKE filter, the MAX measure, and a scalar. A second test proves a pending batch and a literal end before applied_through both stay on raw. The class fails to compile against dev (the branch's own eligibility flag does not exist there), so the compile failure itself is the RED for this proof. Also fixes a real diagnostic-trace bug the branch had already introduced: the eligibility check's catch arm logged the exception's own message text into a web-surface trace, which the exception-text census forbids. The trace now logs only the exception's type name. Confirmed the MCP custom-view tool and the web endpoint share the same compose runner and therefore the same eligibility decision; the custom alert evaluator builds its own run context and defaults to raw, which is unchanged and named in the PR body.
erikdarlingdata
marked this pull request as ready for review
September 28, 2026 18:18
This was referenced Sep 28, 2026
Closed
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.
Part of #4605 (the routing half; the role-level
temp_file_limitis #4610).Why
A composed Custom Views panel over
query_store_statsdedupes the raw slice on every run:ROW_NUMBER() OVER (PARTITION BY server_id, server_name, database_name, query_id, plan_id, runtime_stats_interval_id, first_execution_time, execution_type_desc, replica_role …)over every raw snapshot in the window, before it aggregates (ComposeCompiler.BuildFactRelation). On a fleet store that sort spilled about 1.8 GB per call and ran to the 60 s read ceiling, and the I/O pushed the collector's own writes past their sweep deadline (#4605). The per-interval tablecollect.query_store_interval_wide(V145, #3953/#4382) already holds exactly what that dedupe computes: the latest snapshot per interval.What changes
The eligibility check.
ComposeRunContextgainsQueryStoreWideEligible(defaultfalse). The shared composed-panel runner (DarlingWebEndpoints.RunComposedPanelAsync, behind both the web composer and the MCPrun_custom_view_paneltool) decides it before compiling. It's true only when ALL of these hold:query_store_stats;ComposeQueryStoreWideMinWindow(12 h);QueryStoreIntervalWide.ReadsTableAsyncpasses for every enabled server in scope. That's the same rule the grid and the MCP Query Store reads already use, including "no legacy row in the window" and the literal-end refusal: a literal window end earlier thanapplied_throughstays raw.Any fault, pre-V145 schema or failed clause gives
false, so the panel stays raw.The relation. When the flag is set,
BuildFactRelationreads(SELECT w.*, s.server_name FROM collect.query_store_interval_wide AS w JOIN collect.servers AS s ON s.server_id = w.server_id WHERE w.collection_time >= $1 AND w.collection_time <= $2) AS f.server_nameaside.collect.servers(aserver_idprimary key with a NOT NULLserver_name) restores that name 1:1.Custom alerts stay raw.
CustomAlertEvaluatorbuilds its own run context and never sets the flag, so a custom alert over Query Store keeps reading raw.A diagnostic fix found on the way: the eligibility check's catch arm no longer puts
ex.Messageinto a trace line (WebExceptionTextCensusTests); it logs the exception type only.Exactness
Custom Views numbers must not move.
ComposeQueryStoreWideExactnessLiveTestschecks that.module_namevalues for aLIKEfilter.ComposeCompiler, forced raw and forced wide, and asserts the rows are identical, with values compared exactly (no tolerance).query_hash;module_name LIKE;qs_max_duration_usMAX;applied_throughboth route to raw.ComposeRunContexthas noQueryStoreWideEligible.The 12-hour minimum
ComposeQueryStoreWideMinWindowadopts the #4382 grid's measuredQueryStoreIntervalWide.GridWideMinWindow(12 h). Below it, a panel stays raw: the eligibility round trips cost more than they save on a short window. A composer-specific measurement is part of #4605's remaining work.Tests
ComposeQueryStoreWideExactnessLiveTests(new, live) plusDarlingComposeTests(3 new compile pins: the eligible relation's text;module_name LIKEcompiles againstf.module_name; the non-eligible case is today's raw text),StorageCommandTimeoutTests,StartupCommandTimeoutTestsandWebExceptionTextCensusTests: Total 362, Failed 0 on a TimescaleDB 2.30.1 / PG 18 rig.CHANGELOG
SECTION: Changed
ENTRY: - Custom Views Query Store panels over a recent window read the per-interval table instead of re-sorting raw snapshots ([#4617]) - A Query Store panel of 12 hours or more, whose window the store's per-interval table fully covers, now reads that table, with the same numbers, instead of deduplicating every raw snapshot in the window. On a large fleet that dedupe spilled gigabytes of temporary files and could run to the 60-second read timeout.
REF: [#4617]: #4617