Lite: an Azure SQL Database master target is scoped from the first alert sweep after a start - #4933
Merged
Merged
Conversation
…ert sweep after a start The master scope read the engine edition from the live connection status only. The first sweep after a start runs before any connection check has read it, and a failed check or an edit blanks the status, so in those sweeps a master target counted the blocking and deadlocks of the databases that alert on their own targets. KnownEngineEditions now gives the alert sweep and the analysis provider one rule: a live edition wins and is remembered; without one, the stored edition, seeded in one grouped read before anything that reads the scope starts; with neither, unscoped as before.
…ts at most 10 seconds Collection, the alert engine, MCP and the server list start after the seed, so a read that stalls (a held lock, a slow Parquet scan) no longer holds them up. A read past the limit is logged as a warning and the start goes on. A late result still seeds, and never replaces an edition that a live status reported meanwhile. A late failure is logged, so its exception is always observed.
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 changed
Lite's Azure SQL Database master scope (#4894) now uses the stored engine edition when the live connection status has none.
KnownEngineEditionsis new. It holds one engine edition per server, keyed by the storage server id. A live edition from the connection status wins, and the class keeps it. With no live edition, the class answers the edition that it last knew: an earlier live one in this run, else the stored one. With neither, the edition is unknown and the server stays unscoped, as before.MainWindow.AlertEngine.cs) and the provider behind analysis, the overview card, the daily summary and the MCP tools (MainWindow.xaml.cs) both callKnownEngineEditions. Before, each site readSqlEngineEdition == 5from the live status and built the target list itself. TheIsAzureSqlDbflag of the alert snapshot uses the same edition.LocalDataService.GetStoredEngineEditionsAsyncis new. It reads the stored edition of every server in one grouped read. Each edition comes from the newestv_server_propertiesrow, the row thatGetSqlEngineEditionAsyncreads for one server.MainWindow_Loadedawaits the seed right after the database is initialized. It waits at most 10 seconds for the read, inKnownEngineEditions.SeedFromStoreAsync.Why
On an Azure SQL Database master target, the Blocking and Deadlocks alerts fired in the first sweep after every start. They counted the events of the databases that are monitored as their own targets.
The first alert sweep after a start runs before any connection check has read the engine edition. Without the edition,
AzureMasterScope.SeparatelyMonitoredDatabasesreturns an empty list, so the master was unscoped in that sweep. A failed connection check or an edit also writes a blank status inServerManager, with the same result. Analysis, the card, the daily summary and the MCP tools read the same live status through the provider.The Lite master scope has not shipped yet.
PerformanceMonitor.Alerting/AzureMasterScope.csis absent in v3.8.0. With this change, the #4894 CHANGELOG entry is true from the first sweep after a start.The startup order
MainWindow_LoadedawaitsSeedKnownEngineEditionsAsync()right after_databaseInitializer.InitializeAsync(). Everything that reads the scope starts later in the same method, in this order:new CollectionBackgroundService(, and its start. Its scheduled analysis reads the provider._alertEngine = new AlertEngine(.CheckPerformanceAlertsreturns at once while_alertEngineis null, so no sweep can run before this line.StartMcpServerAsync().RefreshServerList(),_statusTimer.Start()and the firstRefreshOverviewAsync().Before
MainWindow_Loadedruns, nothing reads the provider. The constructor only assigns it.AzureMasterLiteWiringTestspins this order. So when the stored editions are read within the limit below, no sweep runs before them.A server that is added while Lite runs is not in the seed. Its first connection check reads its edition, as before.
The startup wait is bounded
Everything in the list above waits for the seed. So the seed waits at most 10 seconds for the read (
KnownEngineEditions.StartupSeedLimit). A held lock or a slow scan of the Parquet archive can delay the start by no more than that. The start covers collection, the alert engine, the MCP server and the server list.KnownEngineEditions.SeedFromStoreAsyncholds this wait, so the tests can drive it without a window. It waits onTask.WhenAnyof the read and aTask.Delayof the limit. A read that finishes at the same moment as the limit is still seeded or logged.Timing
The seed is one grouped read, not one read per server, because
v_server_propertiesreads the Parquet archive and each read scans it again. The table below is from DuckDB 1.5.5, over a copy of a store's archive folder with three monthlyserver_propertiesParquet files. The view returned 137 rows for 9 servers. Theserver_propertiestable came from an earlier copy of the same store, because Lite held the current file open.Both reads returned the same edition for every server.
The grouped read uses
arg_max_null, notarg_max. On DuckDB 1.5.5,arg_maxskips a NULL edition and returns the edition of an older row. A row that was archived before the column existed reads as NULL through the view.GetSqlEngineEditionAsyncreturns the newest row, so the grouped read must do the same.Tests
New and changed tests:
KnownEngineEditionsTestsis new, with 9 tests. They cover the edition rule, the target list, the provider, the grouped read over a real store, and the overview card through the provider.KnownEngineEditionsSeedLimitTestsis new, with 7 tests. A read within the limit seeds before the start goes on. A read that stalls returns at the limit and logs a warning. A late result seeds and keeps a live edition. A late failure and a failed read are each logged as a warning. The limit stays between 1 and 30 seconds.LiteAlertForwardingTests.AzureMasterEdition.csis new, with 2 tests. Each builds the snapshot asCheckPerformanceAlertsbuilds it in a first sweep. The configured server has a blank status, and the store holds edition 5 under its storage id. Through the shared alert engine, blocking and deadlocks in the sibling databases do not fire. The events of the master's own database count 1 each.AzureMasterLiteWiringTestsis rewritten, with 4 tests. Both sites callKnownEngineEditions, and neither readsSqlEngineEdition ==itself.MainWindow_Loadedseeds before each start listed above, and the seed waits at mostStartupSeedLimit.The pins:
Each pin can fail:
KnownEngineEditions.Resolve, fails 9 tests. They are pins 1 and 2, the provider test, the seed test, both alert-path tests, and the two seed-limit tests that seed an edition. Pin 3 passes under it, as a guard must.MainWindow.AlertEngine.csfails the wiring test for the alert site. The dev copy ofMainWindow.xaml.csfails the wiring test for the provider and the order test.arg_maxorarg_min_nullin the grouped readnew AlertEngine(MainWindow.AlertEngine.csRuns, on the branch:
KnownEngineEditionsSeedLimitTests,KnownEngineEditionsTests,LiteAlertForwardingTests,AzureMasterLiteWiringTestsandSeparatelyMonitoredListNoteTests.CHANGELOG
None of its own. The #4894 entry describes the master scope, and this change makes it true from the first sweep after a start.