Repository navigation
Fleet overview, daily summary and server summary: an Azure master counts only its own blocking and deadlocks, and its lists say where its databases' events are counted - #4925
Merged
Conversation
…gain for its own databases The reader gains the optional resolver parameter (not yet used), so the pins compile and fail on their assertions.
… monitored on their own
…monitored on their own
…; one engine-edition rule; the registry is read only for masters
…et_server_summary counts an Azure master once
…tored databases' events are counted under those servers
… deadlocks; a failed lookup reads unscoped
…bases' rows stay; the note's lookup fails safe
…nd deadlocks, as the service does
…ine-edition rule The fleet sweep read a master with no runtime unscoped, so its earlier events counted twice in the sweep band; it now asks the stored edition and the registry. StoredEngineEditionSql also requires servers.sql_engine_edition = 5, because the connect probe and the server_properties collector are separate writers and can disagree. The server summary's scoped read ends a day ahead like the Viewer's, the scope fallbacks log the exception, and table()'s doc names moreNoteKeys.
erikdarlingdata
marked this pull request as ready for review
October 2, 2026 00:25
erikdarlingdata
added a commit
that referenced
this pull request
Oct 2, 2026
…wn databases, and the Viewer card shows no sibling's Last (#4932) #4925 scoped an Azure SQL Database master's blocking and deadlock counts to its own databases but left the last-seen times alone, so a master whose own databases had no deadlocks showed "0 deadlocks, last seen minutes ago" on the fleet card from a separately monitored database's deadlock, and the Darling Viewer's Overview card read "Last: N ago" from a sibling's event under 0/0. The fleet card's deadlock_last_seen now comes from the same single pass as the scoped count, by the count's own rule, so the two can't disagree and a failure keeps that master's whole unscoped row; get_server_summary makes one graph pass instead of two. In the Viewer, a master with separately monitored databases shows no "Last" on its Overview card for blocking or deadlocks, because an own-database newest over all stored history would need an all-history read or a cache on every refresh; its counts stay scoped and its lists keep every row with their note. Every other server keeps its "Last".
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.
What a user saw
On a fleet with an Azure SQL Database logical server registered at master and its databases registered on their own, Darling counted the databases' blocking events and deadlocks twice. The Fleet Overview header showed Blocking 96 (master 48 + GP 25 + HS 23) and Deadlocks 91 (46 + 23 + 22), and master sat in "Needs attention" as Critical on those same events. Master's daily summary, the Performance Calendar, the fleet sweep's band, MCP
get_server_summaryand the Darling Viewer's fleet totals and per-server summary did the same. Master's Blocking, Deadlocks and Locking lists showed those rows with nothing saying why the card disagreed.Why
A master registration reads server-wide blocked-process reports and deadlocks, which include the separately monitored databases' events. Alerts and analysis already skip those databases' events on a master target. These reads didn't: they grouped every stored event by server.
What changed
Every read below takes the separately monitored list analysis uses (
AzureMasterScope.SeparatelyMonitoredDatabases). It applies only to an Azure SQL Database master: the server's registration (servers.sql_engine_edition, stamped on every connect) AND its newest storedserver_properties.engine_editionmust both be 5, on every surface. The service's stored-edition read (DarlingWorker.StoredEngineEditionSql) now tests both, so a pair that disagrees reads unscoped everywhere and #4906's scoped SQL (PgFactCollector.BlockingSqlSkippingSeparate,CountDeadlocksSkippingSeparateAsync: a deadlock counts on master unless every process in its graph is in the list). The DMV blocking arm is unchanged (master's DMV sees only its own sessions).DarlingFleetReader.GetFleetOverviewAsync:/api/fleet, the web read mirror, MCPget_fleet_overview): master's blocked-process count and max wait and its deadlock count come from the scoped reads. The cards, header totals, bands and "Needs attention" follow.get_server_summary(DarlingHealthReader.GetServerSummaryAsync): the same scoped reads over its one-hour window.DailySummarySql.RangeSqlviaDailySummaryAzureMasterScope: MCPget_daily_summary/get_daily_summary_range, the read mirror, the fleet sweep's band throughGetWindowSignalsAsync, and the Viewer's Performance Calendar; a master that is disconnected when the sweep fires gets its list from the stored edition and the registry, as MCP does): the deadlock and blocked-process steps count with aFILTER, and master's graph-carrying deadlocks are counted per day with the every-process rule. The windows, day bucketing and DMV arm are byte-identical. Those steps read the raw tables on every retention tier, so every retained day is scoped. The range cache key carries the list. A day whose only events are siblings' is still a present day, with a count of 0.get_blockingandget_deadlocksreturn it asseparately_monitored_note, with the list asseparately_monitored_databases;get_object_lockingreturns the note. The note shows only when the list is non-empty.get_server_summary's scoped read ends a day ahead of now, as the Viewer's does, so a row stamped ahead by clock skew counts the same in both.Pins
FleetOverviewAzureMasterScopeLiveTests: master + GP + HS on one host: master's card shows Blocking 3 and Deadlocks 1 and the header counts each event once; a sibling's longer wait leaves master's max wait at master's own; a non-Azure server and a sibling-less master are unchanged; with no resolver, a resolver that throws, or a scoped read that throws, the old counts and every card;get_server_summarymatches the card, and an edition pair that disagrees either way round reads unscoped.ViewerFleetAzureMasterScopeLiveTests: the same arrange through the Viewer's summary and fleet totals, the two-edition rule, a failed scoped read falling back, and the registry read only for masters and once per fleet refresh.DailySummaryAzureMasterScopeTests,DailySummaryAzureMasterScopeLiveTests,ViewerDailySummaryAzureMasterScopeLiveTests: the scoped SQL keeps the windows and the DMV arm, every tier is scoped, the cache key carries the list, master's days exclude sibling events, the service and the Viewer agree, and a throwing scoped read falls back.SeparatelyMonitoredListNoteTests: the sentence, and when it shows on each surface.AzureMasterAnalysisScopeLiveTests: the stored-edition rule (including a registration of 8 with a newest stored edition of 5), and a source pin that the sweep scopes a master with no runtime.ServerPageTabsTests:table()'s full signature, now withmoreNoteKeys.Tests run
FleetOverviewAzureMasterScopeLiveTests(9),AzureMasterAnalysisScopeLiveTests(21),DailySummaryAzureMasterScopeLiveTests(4),ViewerDailySummaryAzureMasterScopeLiveTests(3),ViewerFleetAzureMasterScopeLiveTests(8),DailySummaryAzureMasterScopeTests(6),SeparatelyMonitoredListNoteTests(7),ServerPageTabsTests(19),PgIndexBloatCoverageTests(16),FleetSweepSignalReadLivePostgresTests,FleetSweepCadenceKnobRungTests,DarlingMcpHealthToolsLivePostgresTests,DarlingSelfAlertTests,CollectorMemoryKnobTests, and the T-SQL, doc-comment, repo-file and deadline-scanner guards.CHANGELOG
None as its own line: this widens the existing Fixed entry for the fleet overview's Azure master count (#4894) to name the daily summaries, calendars, the sweep band,
get_server_summaryand the list notes. The double count was present in v3.8.0.