Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CHANGELOG.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Darling/Darling.Tests/DarlingPeerDisclosureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ private static JsonElement RenderedServerList(DarlingPeerDirectory.Snapshot peer
{
var rows = new List<DarlingDataReader.ServerListRow>
{
new(1, "prod-sql-use1-beta-01", "ayr", 16, new DateTime(2026, 8, 19, 12, 0, 0, DateTimeKind.Utc)),
new(1, "prod-sql-use1-beta-01", "omega", 16, new DateTime(2026, 8, 19, 12, 0, 0, DateTimeKind.Utc)),
};

return JsonDocument
Expand Down Expand Up @@ -410,7 +410,7 @@ public void ListServers_CarriesThePeerFleetsSummary()
/* The existing payload is untouched — the disclosure is additive here too. */
var server = Assert.Single(root.GetProperty("servers").EnumerateArray());
Assert.Equal("prod-sql-use1-beta-01", server.GetProperty("server_name").GetString());
Assert.Equal("ayr", server.GetProperty("display_name").GetString());
Assert.Equal("omega", server.GetProperty("display_name").GetString());
}

[Fact]
Expand Down
5 changes: 3 additions & 2 deletions Darling/Darling.Tests/FleetIdentifierScrubTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ spelled in capitals.
*/
public sealed class FleetIdentifierScrubTests
{
/* Greek letters and role words -- nothing here names a real customer. */
/* Greek letters and role words -- nothing here names a real customer. pgmonitor is a role
word too: it names one of the maintainer's own monitoring hosts, the same as monitor. */
private static readonly HashSet<string> SyntheticSlugs = new(StringComparer.OrdinalIgnoreCase)
{
"alpha", "beta", "gamma", "delta", "epsilon", "zeta", "omega",
"monitor", "multi", "primary", "replica", "secondary", "reporting",
"monitor", "pgmonitor", "multi", "primary", "replica", "secondary", "reporting",
"test", "sample", "example", "demo", "fake", "dummy", "placeholder",
};

Expand Down
4 changes: 2 additions & 2 deletions Darling/Darling.Tests/QueryStorePlanFetchTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ public void CandidatePlanCount_SitsJustPastTheBudget_AtEveryMeasuredFleetPlanSiz
/// <summary>
/// The smallest measured fleet quartile (15 KB) wants ~1229 plans at a 12 MB budget — past the flat
/// 512 ceiling (#2683/#2685's adaptive runaway detector was retired in favor of this: it failed to
/// engage during the 2026-08-29 AYR peak precisely because "wanted" stayed just under the old 2048
/// engage during the 2026-08-29 OMEGA peak precisely because "wanted" stayed just under the old 2048
/// ceiling, so the throttle never armed). A flat ceiling applies unconditionally, so this database-shape
/// now converges over more cycles instead of fewer — the accepted trade for query_store, which serves
/// historical analysis rather than in-the-moment troubleshooting.
Expand Down Expand Up @@ -438,7 +438,7 @@ private static string LiveSql(CollectorContext context) =>

/* ---------------------------------------------------------------------------------------------
#2791: the fetch statements read TVF-backed Query Store views, for which the optimizer has no
statistics and uses a fixed guess (1,000 estimated against 14,633 actual on AYR, 1,463% off).
statistics and uses a fixed guess (1,000 estimated against 14,633 actual on OMEGA, 1,463% off).
That guess put QUERY_STORE_PLAN_IN_MEM on the INNER side of a Nested Loops join, re-executed
once per candidate id up to MaxCandidatePlans = 512, at 55,000-61,000ms CPU per fetch. The
query-level hint is the only lever - the joins live inside the view definition.
Expand Down
2 changes: 1 addition & 1 deletion Darling/Darling.Tests/QueryStorePlanSizeLearnTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public void TheDefaultEstimateMeansNeverLearned()
/// <summary>
/// #2683/#2685 tried an adaptive runaway detector here (a streak of clamped passes armed a reduced
/// ceiling, with hysteresis to survive oscillation) and it failed at the moment it mattered: the
/// 2026-08-29 peak verification on AYR showed zero clamped passes and zero runaway arms while
/// 2026-08-29 peak verification on OMEGA showed zero clamped passes and zero runaway arms while
/// plan_fetch still ran 38-73s across twelve straight passes, because the learned average happened to
/// keep "wanted" just under the ceiling. MaxCandidatePlans is now a flat 512 instead, so the throttle
/// applies unconditionally and cannot fail to engage. This pins that the ceiling used by
Expand Down
2 changes: 1 addition & 1 deletion Darling/Darling.Tests/StatementSplitTimingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void EveryPhaseAccountedFor_ThePartsNeverExceedTheWhole()

/// <summary>
/// #2312: the separate plan-XML and text fetches run INSIDE the driver's <c>sql:</c> stopwatch but are
/// their own queries against the Query Store catalogs — on ayr-01 a 0-row closed-only cycle still cost
/// their own queries against the Query Store catalogs — on omega-01 a 0-row closed-only cycle still cost
/// 298s and the blended number could not say where. They must come out of drain exactly like the
/// watermark phase, or drain silently absorbs the one cost this investigation needs isolated.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4905,7 +4905,7 @@ surfacing as an unobserved task exception. */
/* #2717: plan_correction gets the identical treatment for the identical reason. Its own
SQL is already correctly seek-based (#2687) and averages ~1 second, but on a server
whose Query Store carries the same leaflogix-class distinct-plan-population signature
already root-caused for query_store on multi-03/AYR, it can spike to 20+ seconds — the
already root-caused for query_store on multi-03/OMEGA, it can spike to 20+ seconds — the
same bimodal shape, just a smaller worst case. Detached the same way, through the
generic DetachedCollectorGate (#2717) rather than query_store's own gate, which has an
orthogonal second job (excluding the backfill loop) this collector does not share.
Expand Down
2 changes: 1 addition & 1 deletion PerformanceMonitor.Collectors/CollectorContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ public long PerDatabaseOtherMsFrom(long databaseSqlMs) =>
/// runs one (Darling; Lite has no separate fetch and leaves it zero). The fetch is INSIDE the driver's
/// per-item <c>sql:</c> stopwatch but is neither open nor drain — it is its own query against
/// <c>sys.query_store_plan</c>, and on a database with a huge Query Store catalog it can dominate the
/// whole item (ayr-01: a 0-row closed-only cycle still cost 298s, and the blended number could not say
/// whole item (omega-01: a 0-row closed-only cycle still cost 298s, and the blended number could not say
/// where). Measured so drain stops absorbing it, exactly the #2164 argument one seam further down.
/// </summary>
public long PerItemPlanFetchMs { get; set; }
Expand Down
4 changes: 2 additions & 2 deletions PerformanceMonitor.Collectors/QueryStoreCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1270,7 +1270,7 @@ scope exit regardless.
HASH JOIN on the fetch statement (#2791), and it is the whole fix rather than a tuning knob.
sys.query_store_plan's view definition unions the on-disk table with the in-memory TVF
QUERY_STORE_PLAN_IN_MEM, and the optimizer has NO statistics for that TVF - it uses a fixed guess.
Measured on AYR the guess is 1,000 rows against 14,633 actual, 1,463% off, which is what makes
Measured on OMEGA the guess is 1,000 rows against 14,633 actual, 1,463% off, which is what makes
Nested Loops look cheap: the TVF lands on the INNER side and is re-executed once per candidate
plan_id, up to MaxCandidatePlans = 512 times, each execution scanning the whole in-memory Query
Store before a single plan is decompressed. sp_QuickieStore put this statement at 55,000-61,000ms
Expand Down Expand Up @@ -1416,7 +1416,7 @@ SET NOCOUNT ON so the SELECT INTO emits no result set. #temp is scoped to this s
out in the open: sys.query_store_query and sys.query_store_query_text are BOTH TVF-backed unions
over their in-memory halves, driven by an IN list, which is exactly the shape that put the plan
fetch on the inner side of a loop 512 times over. The plan fetch is the variant that carries the
AYR measurement; this one is the same defect treated the same way, and that distinction is stated
OMEGA measurement; this one is the same defect treated the same way, and that distinction is stated
rather than blurred - the join-strategy change and the identical-rowset property are verified
here, the 60s->0.5s number is not this statement's and is not claimed for it.

Expand Down
2 changes: 1 addition & 1 deletion PerformanceMonitor.Collectors/QueryStorePlanXmlState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static class QueryStorePlanXmlState
/// issues detected a "runaway" store (one whose plan population churns faster than any pass can drain)
/// by watching for 24 CONSECUTIVE passes clamped at a high ceiling (2048), then dropping to a low one
/// (512) with hysteresis to survive the estimator's oscillation. Verified against the 2026-08-29 peak
/// window on AYR — the pathological store the detector was built for: the log showed ZERO "candidate cap
/// window on OMEGA — the pathological store the detector was built for: the log showed ZERO "candidate cap
/// clamped" lines and ZERO RUNAWAY/Holding lines during a stretch where plan_fetch still ran 38–73s
/// across twelve straight passes. The learned average happened to keep "wanted" just under the 2048
/// ceiling, so no pass ever clamped, the streak never advanced, and the throttle that existed
Expand Down
Loading