Repository navigation
Perfmon trend charts and get_perfmon_trend set aside a one-sample Wait Statistics spike instead of plotting it (#4476) - #4490
Merged
Conversation
) PerformanceMonitor.Common.WaitStatisticsArtifact.IsIsolatedSingleSampleArtifact is the shared test for a Wait Statistics gauge row whose value is a one-sample cumulative-count artifact: both neighbours present, value >= 1,000,000, and > 1,000x the larger neighbour, scoped to gauge rows whose object name ends in ":Wait Statistics". The read-path wiring (Viewer perfmon chart, MCP get_perfmon_stats) and pins are not yet in this commit; see the PR body for what remains.
…s from the per-collection SUM (#4476)
…-artifact' into lane-4476e-work
…for the artifact check (#4476) PerfmonTrendsSql opened its lag/lead artifact-detection window over every raw row it scanned, even though the isolated single-sample artifact can only occur on a SQLServer:Wait Statistics object. Split the raw layer into a UNION ALL: non-Wait-Statistics rows carry a plain false AS is_artifact with no window; only Wait Statistics rows open the lag/lead window. Mirrors the shape the MCP trend read already has.
erikdarlingdata
marked this pull request as ready for review
September 27, 2026 18:53
erikdarlingdata
deleted the
fix/4476-waitstats-single-sample-artifact
branch
September 27, 2026 18:53
erikdarlingdata
added a commit
that referenced
this pull request
Sep 27, 2026
…t Statistics spike (#4492) Lite's perfmon chart and get_perfmon_trend set aside a one-sample Wait Statistics spike, and say how many they set aside. This is the same rule the Darling Viewer and Darling's get_perfmon_trend use since #4490. - LocalDataService.Perfmon.cs (the chart read) and LocalDataService.TrendBuckets.cs (GetPerfmonBucketsAsync) apply the shared WaitStatisticsArtifact predicate in their DuckDB SQL, so a sample is set aside under the same conditions: - a Wait Statistics gauge; - both neighbours present; - at least 1,000,000; - more than 1,000 times the larger neighbour. A bucket holding only artifacts is dropped. - Lite's chart reports the count, and Lite's get_perfmon_trend reports artifacts_set_aside through the shared payload, which had always read 0 on Lite. - The stored values are unchanged. - Tests: - LitePerfmonWaitStatisticsArtifactSourceTests (Darling.Tests; runs on every platform) checks that Lite's two SQL builders use the shared predicate; - LitePerfmonWaitStatisticsArtifactLiveTests (Lite.Tests; Windows) reads a planted spike through GetPerfmonTrendsByCountersAsync. The spike is set aside, the neighbours are unchanged, and a collection holding only artifacts is dropped. Refs #4476
erikdarlingdata
added a commit
that referenced
this pull request
Sep 27, 2026
…tract # Conflicts: # Darling/Darling.Tests/ViewerPerfmonRunningJobsTests.cs # Darling/PerformanceMonitor.Darling.Viewer/ViewerDataService.Perfmon.cs
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 #4476.
Why
SQL Server occasionally returns a cumulative-sized value for ONE sample of a
SQLServer:Wait Statistics"per second" instance, which is stored as a gauge (cntr_type65792).get_perfmon_trendreports it as the peak.The stored value stays what SQL Server returned. The READ path recognises the isolated sample and sets it aside visibly.
What changes
PerformanceMonitor.Common/WaitStatisticsArtifact: one rule, in C# (IsIsolatedSingleSampleArtifact) and as a SQL twin (ArtifactPredicateSql) built from the same constants. A sample is set aside when all of these hold::Wait Statistics(so a named instance'sMSSQL$X:Wait Statisticsis included);ViewerDataService.PerfmonTrendsSqland MCP'sDarlingTrendReader.PerfmonTrendSql/PerfmonTrendBucketedSql, read the raw rows as aUNION ALL:is_artifact = falseand open no window;lag/leadand the predicate.FILTER (WHERE NOT is_artifact), so the peak, average and last value exclude the sample.artifacts_set_asidecolumn counts them, and existing ordinals don't move.get_perfmon_trendreportsartifacts_set_asideand a notes line when it's non-zero.PerfmonBucketPointgainsArtifactsSetAside, appended with a default of 0, so Lite compiles unchanged. Lite's own reads get the same treatment in a follow-up PR stacked on this one.get_perfmon_statsis unchanged. It returns the latest sample, which never has a next neighbour, so the rule can't judge it.Cost
EXPLAIN (ANALYZE, BUFFERS), warm, 6 runs averaged, on a rig with 7 days of data: 12 non-Wait-Statistics counters (120,960 rows) plus one Wait Statistics counter with 4 instances (40,320 rows), hourly buckets.Test plan
WaitStatisticsArtifactTests(pure, 12/12) andWaitStatisticsArtifactSqlEquivalenceLiveTests(the SQL twin against the C# rule over the same 12 rows, 12/12). The rows are:PerfmonWaitStatisticsArtifactViewerLiveTests, throughGetPerfmonTrendsByCountersAsync, on a plant of 4 instances × 5 collections with the 214,396,451 spike:dev:Expected: 62, Actual: 214396513;ArtifactsSetAside= 1;PerfmonWaitStatisticsArtifactMcpLiveTests, through theget_perfmon_trendtool: the peak is < 10,000,artifacts_set_aside= 1, and the notes carry the caption. RED ondevat runtime (the spike's bucket publishes:Expected: 4, Actual: 5).PerfmonChartArtifactSummaryTests(the title helper).PerfmonCounterTypeRungTestsis updated for both SQL shapes.false→ the Viewer and MCP pins RED;McpPayloadContractCensusTests,McpToolsListBudgetTestsand the trend tool classes) is 222/222.Darling.TestsandLite.Testsbuild with 0 warnings.CHANGELOG
SECTION: Fixed
ENTRY:
get_perfmon_trendnow set such a sample aside and say how many, and the stored value is unchanged.REF:
[Perfmon trend charts and get_perfmon_trend set aside a one-sample Wait Statistics spike instead of plotting it (#4476) #4490]: Perfmon trend charts and get_perfmon_trend set aside a one-sample Wait Statistics spike instead of plotting it (#4476) #4490