sqlinsight-pro/SQL Scripts/_collectors/DatabaseDiscovery.sql
Søren Eggert Lundsteen Olsen be039a6f73 Review 1.4: AX reads put the agent's session settings back
AxSql.Reset ran SET LOCK_TIMEOUT -1 and READ COMMITTED after every AX read
(and after the AX detection in discovery). The collectors of an instance
share one connection, so every collector after the AX ones waited on locks
without limit instead of the agent's 5 s, and no longer read uncommitted.
Reset now restores the agent's own settings, from one place
(Core.Instances.AgentSession) that SqlConnectionFactory.SessionSettings also
uses. The AX reads themselves are unchanged: READ COMMITTED (or SNAPSHOT)
with a 2 s lock timeout inside sp_executesql, never NOLOCK.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 14:14:24 +02:00

80 lines
5.8 KiB
Transact-SQL

-- ===================================================================================================================
-- Collector: DatabaseDiscovery (Servere og databaser, fra 1.3)
-- ===================================================================================================================
-- Hvad: Finder alle databaser på en instans med tilstand, størrelse, recovery model og compatibility level, om
-- agenten kan åbne dem, og om de er Dynamics AX-databaser (AX' systemtabeller, som AX-reglerne genkender).
-- Resultatet vises under Overvågning → Servere og databaser, hvor man vælger, hvilke databaser der overvåges.
-- Valget bruges af de databasespecifikke collectors (DatabaseCollector, IndexCollector, QueryStoreCollector,
-- CustomQueryCollector): de sorterer fravalgte databaser fra i koden; deres SQL er uændret.
-- Fil: src/SQLInsight.Collectors/Discovery/DatabaseDiscovery.cs
-- Interval: Når en server tilføjes, når der trykkes "Søg efter databaser nu", og ellers hver time pr. instans
-- (AgentRequestService.DiscoveryInterval)
-- Versioner: SQL Server 2000 (legacy ODBC-sti) og nyere
--
-- Rettigheder til agentens login (se db/permissions/grant-least-privilege.sql; [agent] = agentens login):
-- GRANT VIEW ANY DEFINITION TO [agent]; -- metadata; giver IKKE adgang til data
-- GRANT CONNECT ANY DATABASE TO [agent]; -- SQL Server 2014+; giver IKKE adgang til data
-- Før 2014 i stedet, i hver brugerdatabase: CREATE USER [agent] FOR LOGIN [agent];
-- Databaser, agenten ikke kan åbne (HAS_DBACCESS = 0), springes over i AX-genkendelsen.
--
-- Bruges af: Ingen regel direkte. Styrer, hvilke databaser de databasespecifikke regler vurderes i, og hvilke
-- AX-databaser der må sende AX-fund (COM-AX-*) til SQLInsight Hub.
-- Read-only: Ja: kun SELECT på metadata, via tre-delte navne og (fra 1.4, AX-genkendelsen på SQL Server 2005 og nyere)
-- [db].sys.sp_executesql under READ COMMITTED med SET LOCK_TIMEOUT 2000, aldrig NOLOCK. Sessionen skifter
-- aldrig database, og intet ændrer data, indstillinger eller objekter. AX-genkendelsen er den samme som i
-- _collectors/AxDatabaseDetector.sql (src/SQLInsight.Core/DynamicsAx/AxDetection.cs).
-- Kørsel: Kør i SSMS som agentens login. Hver variant er sin egen batch (GO); en variant for en anden SQL Server-version
-- end din kan fejle - det er forventet. Agenten kører altid med sessionsindstillingerne i _collectors/InstanceProbe.sql.
-- ===================================================================================================================
-- Variant: SQL Server 2005 og nyere: alle databaser
-- Kilde: DatabaseDiscovery.Databases2005Sql
-- Kode: src/SQLInsight.Collectors/Discovery/DatabaseDiscovery.cs : DatabaseDiscovery.Databases2005Sql
SELECT d.name, d.database_id, d.state_desc, d.recovery_model_desc, d.compatibility_level, d.is_read_only,
CASE WHEN d.source_database_id IS NULL THEN 0 ELSE 1 END,
HAS_DBACCESS(d.name),
(SELECT SUM(CAST(f.size AS bigint)) / 128 FROM sys.master_files f WHERE f.database_id = d.database_id)
FROM sys.databases d
ORDER BY d.name
GO
-- Variant: SQL Server 2000 (legacy ODBC-sti): alle databaser
-- Kilde: DatabaseDiscovery.Databases2000Sql
-- Kode: src/SQLInsight.Collectors/Discovery/DatabaseDiscovery.cs : DatabaseDiscovery.Databases2000Sql
SELECT d.name, d.dbid,
CAST(DATABASEPROPERTYEX(d.name, 'Status') AS nvarchar(60)),
CAST(DATABASEPROPERTYEX(d.name, 'Recovery') AS nvarchar(60)),
d.cmptlevel,
CASE WHEN DATABASEPROPERTYEX(d.name, 'Updateability') = 'READ_ONLY' THEN 1 ELSE 0 END,
0,
HAS_DBACCESS(d.name),
(SELECT SUM(CAST(f.size AS bigint)) / 128 FROM master.dbo.sysaltfiles f WHERE f.dbid = d.dbid)
FROM master.dbo.sysdatabases d
ORDER BY d.name
GO
-- Variant: SQL Server 2005 og nyere: Dynamics AX-genkendelse, én gang pr. online brugerdatabase, agenten kan åbne (vist for msdb)
-- Kilde: DatabaseDiscovery.DynamicsAxSql(2005)
-- Kode: src/SQLInsight.Collectors/Discovery/DatabaseDiscovery.cs : DatabaseDiscovery.DynamicsAxSql(database, version)
EXEC [msdb].sys.sp_executesql N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT s.name, UPPER(t.name), UPPER(c.name), TYPE_NAME(c.system_type_id), c.precision, c.max_length,
ISNULL(HAS_PERMS_BY_NAME(QUOTENAME(s.name) + N''.'' + QUOTENAME(t.name), N''OBJECT'', N''SELECT''), 0),
(SELECT TOP 1 p.name FROM sys.database_principals p WHERE p.sid = SUSER_SID())
FROM sys.tables t
JOIN sys.schemas s ON s.schema_id = t.schema_id
JOIN sys.columns c ON c.object_id = t.object_id
WHERE UPPER(t.name) IN (N''SQLDICTIONARY'', N''DATAAREA'', N''SYSCONFIG'', N''BATCH'', N''BATCHJOB'', N''BATCHJOBHISTORY'', N''BATCHGROUP'', N''NUMBERSEQUENCETABLE'', N''NUMBERSEQUENCESCOPE'', N''NUMBERSEQUENCEREFERENCE'', N''SYSTEMSEQUENCES'', N''MODELELEMENT'')
ORDER BY s.name, t.name, c.column_id';
SET LOCK_TIMEOUT 5000; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO
-- Variant: SQL Server 2000 (legacy ODBC-sti): Dynamics AX-genkendelse, én gang pr. online brugerdatabase (vist for msdb)
-- Kilde: DatabaseDiscovery.DynamicsAxSql(2000)
-- Kode: src/SQLInsight.Collectors/Discovery/DatabaseDiscovery.cs : DatabaseDiscovery.DynamicsAxSql(database, version)
SELECT u.name, UPPER(o.name), UPPER(c.name), TYPE_NAME(c.xtype), c.xprec, c.length, 0, NULL
FROM [msdb].dbo.sysobjects o
JOIN [msdb].dbo.sysusers u ON u.uid = o.uid
JOIN [msdb].dbo.syscolumns c ON c.id = o.id
WHERE o.xtype = 'U' AND UPPER(o.name) IN (N'SQLDICTIONARY', N'DATAAREA', N'SYSCONFIG', N'BATCH', N'BATCHJOB', N'BATCHJOBHISTORY', N'BATCHGROUP', N'NUMBERSEQUENCETABLE', N'NUMBERSEQUENCESCOPE', N'NUMBERSEQUENCEREFERENCE', N'SYSTEMSEQUENCES', N'MODELELEMENT')
ORDER BY u.name, o.name, c.colid
GO