Skip to content

Commit c437185

Browse files
Merge pull request #292 from erikdarlingdata/worktree-issue-287-qs-detection
Issue #287: Use database_query_store_options for QS detection
2 parents 822eba3 + 482f4ef commit c437185

2 files changed

Lines changed: 127 additions & 23 deletions

File tree

Lite/Services/RemoteCollectorService.QueryStore.cs

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,69 @@ public partial class RemoteCollectorService
2626
/// </summary>
2727
private async Task<int> CollectQueryStoreAsync(ServerConnection server, CancellationToken cancellationToken)
2828
{
29-
/* First, get databases with Query Store enabled */
29+
/* First, get databases with Query Store actually enabled.
30+
Uses sys.database_query_store_options.actual_state instead of
31+
sys.databases.is_query_store_on, which can be out of sync on Azure SQL DB. */
3032
const string dbQuery = @"
33+
SET NOCOUNT ON;
3134
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
3235
33-
SELECT /* PerformanceMonitorLite */
34-
d.name
35-
FROM sys.databases AS d
36-
WHERE d.is_query_store_on = 1
37-
AND d.database_id > 4
38-
AND d.database_id < 32761
39-
AND d.state_desc = N'ONLINE'
40-
AND d.name <> N'PerformanceMonitor'
41-
ORDER BY d.name
42-
OPTION(RECOMPILE);";
36+
DECLARE
37+
@result TABLE (name sysname);
38+
39+
DECLARE
40+
@db sysname,
41+
@sql NVARCHAR(500);
42+
43+
DECLARE db_check CURSOR LOCAL FAST_FORWARD FOR
44+
SELECT /* PerformanceMonitorLite */
45+
d.name
46+
FROM sys.databases AS d
47+
WHERE d.database_id > 4
48+
AND d.database_id < 32761
49+
AND d.state_desc = N'ONLINE'
50+
AND d.name <> N'PerformanceMonitor'
51+
OPTION(RECOMPILE);
52+
53+
OPEN db_check;
54+
55+
FETCH NEXT
56+
FROM db_check
57+
INTO @db;
58+
59+
WHILE @@FETCH_STATUS = 0
60+
BEGIN
61+
BEGIN TRY
62+
SET @sql =
63+
N'USE ' + QUOTENAME(@db) + N';
64+
SELECT ' + QUOTENAME(@db, '''') + N'
65+
WHERE EXISTS
66+
(
67+
SELECT
68+
1
69+
FROM sys.database_query_store_options
70+
WHERE actual_state > 0
71+
);';
72+
73+
INSERT @result (name)
74+
EXEC(@sql);
75+
END TRY
76+
BEGIN CATCH
77+
END CATCH;
78+
79+
FETCH NEXT
80+
FROM db_check
81+
INTO @db;
82+
END;
83+
84+
CLOSE db_check;
85+
DEALLOCATE db_check;
86+
87+
SELECT
88+
name
89+
FROM @result
90+
ORDER BY
91+
name;";
4392

4493
var serverId = GetServerId(server);
4594
var collectionTime = DateTime.UtcNow;

install/09_collect_query_store.sql

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -265,33 +265,88 @@ BEGIN
265265
);
266266

267267
/*
268-
Loop through databases where Query Store is enabled
268+
Build list of databases where Query Store is actually enabled.
269+
Uses sys.database_query_store_options.actual_state instead of
270+
sys.databases.is_query_store_on, which can be out of sync on Azure SQL DB.
269271
*/
270272
DECLARE
271-
@database_name sysname;
272-
273-
DECLARE @database_cursor CURSOR
274-
275-
SET @database_cursor =
276-
CURSOR
277-
LOCAL
278-
FAST_FORWARD
273+
@database_name sysname,
274+
@qs_check_sql NVARCHAR(500);
275+
276+
DECLARE
277+
@qs_databases TABLE (name sysname);
278+
279+
DECLARE @db_check_cursor CURSOR
280+
281+
SET @db_check_cursor =
282+
CURSOR
283+
LOCAL
284+
FAST_FORWARD
279285
FOR
280286
SELECT
281287
d.name
282288
FROM sys.databases AS d
283289
WHERE d.state_desc = N'ONLINE'
284290
AND d.database_id > 4
285291
AND d.is_read_only = 0
286-
AND d.is_query_store_on = 1
287292
AND d.name <> N'PerformanceMonitor'
288293
AND d.database_id < 32761 /*exclude contained AG system databases*/
289294
OPTION(RECOMPILE);
290295

296+
OPEN @db_check_cursor;
297+
298+
FETCH NEXT
299+
FROM @db_check_cursor
300+
INTO @database_name;
301+
302+
WHILE @@FETCH_STATUS = 0
303+
BEGIN
304+
BEGIN TRY
305+
SET @qs_check_sql =
306+
N'USE ' + QUOTENAME(@database_name) + N';
307+
SELECT ' + QUOTENAME(@database_name, '''') + N'
308+
WHERE EXISTS
309+
(
310+
SELECT
311+
1
312+
FROM sys.database_query_store_options
313+
WHERE actual_state > 0
314+
);';
315+
316+
INSERT @qs_databases (name)
317+
EXEC(@qs_check_sql);
318+
END TRY
319+
BEGIN CATCH
320+
END CATCH;
321+
322+
FETCH NEXT
323+
FROM @db_check_cursor
324+
INTO @database_name;
325+
END;
326+
327+
CLOSE @db_check_cursor;
328+
DEALLOCATE @db_check_cursor;
329+
330+
/*
331+
Loop through databases where Query Store is enabled
332+
*/
333+
DECLARE @database_cursor CURSOR
334+
335+
SET @database_cursor =
336+
CURSOR
337+
LOCAL
338+
FAST_FORWARD
339+
FOR
340+
SELECT
341+
q.name
342+
FROM @qs_databases AS q
343+
ORDER BY
344+
q.name;
345+
291346
OPEN @database_cursor;
292347

293-
FETCH NEXT
294-
FROM @database_cursor
348+
FETCH NEXT
349+
FROM @database_cursor
295350
INTO @database_name;
296351

297352
WHILE @@FETCH_STATUS = 0

0 commit comments

Comments
 (0)