Batch jobs: failed (001), longer than their own history (002), late or never started (003), stuck in Executing (004). Number sequences: running out with a forecast from SQLInsight's own samples (005), format shorter than HIGHEST (006), blocked but still referenced (007), continuous and not cleaned up (008). RecId running out, flagged far earlier for AX 3.0's 32-bit RecId (009). AX user behind blocking from CONTEXT_INFO, honest where AX 3.0 cannot tell (010). Subjects carry the database, so findings follow the hub opt-in. SQL Scripts/<rule>.sql (and _collectors/) for every AX rule added or changed in 1.4, incl. COM-AX-001..007: a Danish header plus the exact SQL SQLInsight sends, generated from the code and checked by SqlScriptTests (rewrite with SQLINSIGHT_UPDATE_SQL_SCRIPTS=1). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
137 lines
10 KiB
Transact-SQL
137 lines
10 KiB
Transact-SQL
/*
|
||
Delt collector-forespørgsel: Dynamics AX-batchjob (SQLI-AX-001, -002, -003, -004 og siden Dynamics AX → Batchjob)
|
||
|
||
Hvad
|
||
Hvert 5. minut, i hver genkendt og overvåget AX-database: de nyeste 1000 batchjob (højeste RECID først) og – i AX
|
||
2009 og senere – de afsluttede kørsler i BATCHJOBHISTORY efter seneste læste RECID (minus 2000, fordi AOS'er får
|
||
RecId i blokke). Axapta 3.0/4.0 har ingen historiktabel; der gemmer SQLInsight de kørsler, den selv ser blive
|
||
afsluttet. Kørslerne gemmes i SQLInsights repository (insight.AxBatchRuns, 90 dage) – aldrig i AX.
|
||
|
||
Collector: src/SQLInsight.Collectors/DynamicsAx/AxBatchCollector.cs – AxBatchCollector.CollectAsync.
|
||
SQL: src/SQLInsight.Core/DynamicsAx/AxSchemaAdapter.cs – BatchJobs og BatchHistory.
|
||
Rettigheder: Valgfri AX-læseadgang, kun SELECT (db/permissions/grant-dynamics-ax-read.sql):
|
||
Axapta 3.0: [bmssa].[BATCH]; AX 4.0: [dbo].[BATCH]; AX 2009/2012/F&O: [dbo].[BATCHJOB], [dbo].[BATCHJOBHISTORY].
|
||
Versioner: SQL Server 2005 og nyere. Axapta 3.0: verificeret mod en kundes skema (STATUS-værdierne dog ikke). AX 4.0,
|
||
AX 2009, AX 2012 og F&O: baseret på Microsofts dokumenterede skema – ikke verificeret mod kundedata.
|
||
Læsning: Kun SELECT med TOP, READ COMMITTED med SET LOCK_TIMEOUT 2000 (SNAPSHOT, når databasen tillader det), aldrig
|
||
NOLOCK, via [db].sys.sp_executesql. En låst tabel giver "ikke målt denne gang", ikke en fejl.
|
||
*/
|
||
-- >>> SQL, som SQLInsight kører – genereret fra koden (tests/SQLInsight.Collectors.Tests/SqlScriptTests.cs). Ret ikke herunder i hånden.
|
||
-- Variant: Axapta 3.0 (skema bmssa): batchjob (AxSchemaAdapter.BatchJobs)
|
||
DECLARE @Database sysname;
|
||
SET @Database = N'AXDB'; -- <== ret til AX-databasen
|
||
DECLARE @Schema sysname;
|
||
SET @Schema = N'bmssa'; -- <== ejeren af AX-tabellerne: bmssa i Axapta 3.0, ellers dbo
|
||
DECLARE @Sql nvarchar(max);
|
||
SET @Sql = N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (1000) CAST(b.[RECID] AS bigint), b.[CLASSNUM], CAST(NULL AS nvarchar(60)), b.[COMPANY], b.[GROUPID], b.[STATUS], b.[STARTDATE], b.[STARTTIME], CAST(NULL AS datetime), CAST(NULL AS int), b.[ENDDATE], b.[ENDTIME], DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [bmssa].[BATCH] b ORDER BY b.[RECID] DESC';
|
||
SET @Sql = REPLACE(@Sql, N'[bmssa].', QUOTENAME(@Schema) + N'.');
|
||
DECLARE @Procedure nvarchar(300);
|
||
SET @Procedure = QUOTENAME(@Database) + N'.sys.sp_executesql';
|
||
EXEC @Procedure @Sql;
|
||
SET LOCK_TIMEOUT -1; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||
GO
|
||
|
||
-- Variant: AX 4.0 (skema dbo) – ikke verificeret mod kundedata: batchjob (AxSchemaAdapter.BatchJobs)
|
||
DECLARE @Database sysname;
|
||
SET @Database = N'AXDB'; -- <== ret til AX-databasen
|
||
DECLARE @Schema sysname;
|
||
SET @Schema = N'dbo'; -- <== ejeren af AX-tabellerne: bmssa i Axapta 3.0, ellers dbo
|
||
DECLARE @Sql nvarchar(max);
|
||
SET @Sql = N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (1000) CAST(b.[RECID] AS bigint), b.[CLASSNUM], CAST(NULL AS nvarchar(60)), b.[COMPANY], b.[GROUPID], b.[STATUS], b.[STARTDATE], b.[STARTTIME], CAST(NULL AS datetime), CAST(NULL AS int), b.[ENDDATE], b.[ENDTIME], DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [dbo].[BATCH] b ORDER BY b.[RECID] DESC';
|
||
SET @Sql = REPLACE(@Sql, N'[dbo].', QUOTENAME(@Schema) + N'.');
|
||
DECLARE @Procedure nvarchar(300);
|
||
SET @Procedure = QUOTENAME(@Database) + N'.sys.sp_executesql';
|
||
EXEC @Procedure @Sql;
|
||
SET LOCK_TIMEOUT -1; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||
GO
|
||
|
||
-- Variant: AX 2009 – baseret på Microsofts dokumenterede skema, ikke verificeret mod kundedata: batchjob (AxSchemaAdapter.BatchJobs)
|
||
DECLARE @Database sysname;
|
||
SET @Database = N'AXDB'; -- <== ret til AX-databasen
|
||
DECLARE @Schema sysname;
|
||
SET @Schema = N'dbo'; -- <== ejeren af AX-tabellerne: bmssa i Axapta 3.0, ellers dbo
|
||
DECLARE @Sql nvarchar(max);
|
||
SET @Sql = N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (1000) CAST(j.[RECID] AS bigint), CAST(NULL AS int), j.[CAPTION], j.[COMPANY], CAST(NULL AS nvarchar(20)), j.[STATUS], j.[ORIGSTARTDATETIME], CAST(NULL AS int), j.[STARTDATETIME], CAST(NULL AS int), j.[ENDDATETIME], CAST(NULL AS int), DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [dbo].[BATCHJOB] j ORDER BY j.[RECID] DESC';
|
||
SET @Sql = REPLACE(@Sql, N'[dbo].', QUOTENAME(@Schema) + N'.');
|
||
DECLARE @Procedure nvarchar(300);
|
||
SET @Procedure = QUOTENAME(@Database) + N'.sys.sp_executesql';
|
||
EXEC @Procedure @Sql;
|
||
SET LOCK_TIMEOUT -1; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||
GO
|
||
|
||
-- Variant: AX 2009 – baseret på Microsofts dokumenterede skema, ikke verificeret mod kundedata: kørselshistorik, første læsning (AxSchemaAdapter.BatchHistory)
|
||
DECLARE @Database sysname;
|
||
SET @Database = N'AXDB'; -- <== ret til AX-databasen
|
||
DECLARE @Schema sysname;
|
||
SET @Schema = N'dbo'; -- <== ejeren af AX-tabellerne: bmssa i Axapta 3.0, ellers dbo
|
||
DECLARE @Sql nvarchar(max);
|
||
SET @Sql = N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (1000) CAST(h.[RECID] AS bigint), CAST(h.[BATCHJOBID] AS bigint), h.[CAPTION], h.[COMPANY], h.[STATUS], h.[STARTDATETIME], h.[ENDDATETIME], DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [dbo].[BATCHJOBHISTORY] h ORDER BY h.[RECID] DESC';
|
||
SET @Sql = REPLACE(@Sql, N'[dbo].', QUOTENAME(@Schema) + N'.');
|
||
DECLARE @Procedure nvarchar(300);
|
||
SET @Procedure = QUOTENAME(@Database) + N'.sys.sp_executesql';
|
||
EXEC @Procedure @Sql;
|
||
SET LOCK_TIMEOUT -1; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||
GO
|
||
|
||
-- Variant: AX 2009 – baseret på Microsofts dokumenterede skema, ikke verificeret mod kundedata: kørselshistorik, de næste læsninger fra seneste RECID minus 2000
|
||
DECLARE @Database sysname;
|
||
SET @Database = N'AXDB'; -- <== ret til AX-databasen
|
||
DECLARE @Schema sysname;
|
||
SET @Schema = N'dbo'; -- <== ejeren af AX-tabellerne: bmssa i Axapta 3.0, ellers dbo
|
||
DECLARE @FraRecId bigint;
|
||
SET @FraRecId = 0; -- <== SQLInsight bruger den højeste RECID, den har læst, minus 2000
|
||
DECLARE @Sql nvarchar(max);
|
||
SET @Sql = N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (1000) CAST(h.[RECID] AS bigint), CAST(h.[BATCHJOBID] AS bigint), h.[CAPTION], h.[COMPANY], h.[STATUS], h.[STARTDATETIME], h.[ENDDATETIME], DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [dbo].[BATCHJOBHISTORY] h WHERE h.[RECID] > 999999999 ORDER BY h.[RECID]';
|
||
SET @Sql = REPLACE(@Sql, N'[dbo].', QUOTENAME(@Schema) + N'.');
|
||
SET @Sql = REPLACE(@Sql, N'> 999999999', N'> ' + CAST(@FraRecId AS nvarchar(20)));
|
||
DECLARE @Procedure nvarchar(300);
|
||
SET @Procedure = QUOTENAME(@Database) + N'.sys.sp_executesql';
|
||
EXEC @Procedure @Sql;
|
||
SET LOCK_TIMEOUT -1; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||
GO
|
||
|
||
-- Variant: AX 2012 RTM/R2/R3 og F&O – baseret på Microsofts dokumenterede skema, ikke verificeret mod kundedata: batchjob (AxSchemaAdapter.BatchJobs)
|
||
DECLARE @Database sysname;
|
||
SET @Database = N'AXDB'; -- <== ret til AX-databasen
|
||
DECLARE @Schema sysname;
|
||
SET @Schema = N'dbo'; -- <== ejeren af AX-tabellerne: bmssa i Axapta 3.0, ellers dbo
|
||
DECLARE @Sql nvarchar(max);
|
||
SET @Sql = N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (1000) CAST(j.[RECID] AS bigint), CAST(NULL AS int), j.[CAPTION], j.[COMPANY], CAST(NULL AS nvarchar(20)), j.[STATUS], j.[ORIGSTARTDATETIME], CAST(NULL AS int), j.[STARTDATETIME], CAST(NULL AS int), j.[ENDDATETIME], CAST(NULL AS int), DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [dbo].[BATCHJOB] j ORDER BY j.[RECID] DESC';
|
||
SET @Sql = REPLACE(@Sql, N'[dbo].', QUOTENAME(@Schema) + N'.');
|
||
DECLARE @Procedure nvarchar(300);
|
||
SET @Procedure = QUOTENAME(@Database) + N'.sys.sp_executesql';
|
||
EXEC @Procedure @Sql;
|
||
SET LOCK_TIMEOUT -1; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||
GO
|
||
|
||
-- Variant: AX 2012 RTM/R2/R3 og F&O – baseret på Microsofts dokumenterede skema, ikke verificeret mod kundedata: kørselshistorik, første læsning (AxSchemaAdapter.BatchHistory)
|
||
DECLARE @Database sysname;
|
||
SET @Database = N'AXDB'; -- <== ret til AX-databasen
|
||
DECLARE @Schema sysname;
|
||
SET @Schema = N'dbo'; -- <== ejeren af AX-tabellerne: bmssa i Axapta 3.0, ellers dbo
|
||
DECLARE @Sql nvarchar(max);
|
||
SET @Sql = N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (1000) CAST(h.[RECID] AS bigint), CAST(h.[BATCHJOBID] AS bigint), h.[CAPTION], h.[COMPANY], h.[STATUS], h.[STARTDATETIME], h.[ENDDATETIME], DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [dbo].[BATCHJOBHISTORY] h ORDER BY h.[RECID] DESC';
|
||
SET @Sql = REPLACE(@Sql, N'[dbo].', QUOTENAME(@Schema) + N'.');
|
||
DECLARE @Procedure nvarchar(300);
|
||
SET @Procedure = QUOTENAME(@Database) + N'.sys.sp_executesql';
|
||
EXEC @Procedure @Sql;
|
||
SET LOCK_TIMEOUT -1; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||
GO
|
||
|
||
-- Variant: AX 2012 RTM/R2/R3 og F&O – baseret på Microsofts dokumenterede skema, ikke verificeret mod kundedata: kørselshistorik, de næste læsninger fra seneste RECID minus 2000
|
||
DECLARE @Database sysname;
|
||
SET @Database = N'AXDB'; -- <== ret til AX-databasen
|
||
DECLARE @Schema sysname;
|
||
SET @Schema = N'dbo'; -- <== ejeren af AX-tabellerne: bmssa i Axapta 3.0, ellers dbo
|
||
DECLARE @FraRecId bigint;
|
||
SET @FraRecId = 0; -- <== SQLInsight bruger den højeste RECID, den har læst, minus 2000
|
||
DECLARE @Sql nvarchar(max);
|
||
SET @Sql = N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (1000) CAST(h.[RECID] AS bigint), CAST(h.[BATCHJOBID] AS bigint), h.[CAPTION], h.[COMPANY], h.[STATUS], h.[STARTDATETIME], h.[ENDDATETIME], DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [dbo].[BATCHJOBHISTORY] h WHERE h.[RECID] > 999999999 ORDER BY h.[RECID]';
|
||
SET @Sql = REPLACE(@Sql, N'[dbo].', QUOTENAME(@Schema) + N'.');
|
||
SET @Sql = REPLACE(@Sql, N'> 999999999', N'> ' + CAST(@FraRecId AS nvarchar(20)));
|
||
DECLARE @Procedure nvarchar(300);
|
||
SET @Procedure = QUOTENAME(@Database) + N'.sys.sp_executesql';
|
||
EXEC @Procedure @Sql;
|
||
SET LOCK_TIMEOUT -1; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||
GO
|
||
-- <<< slut på genereret SQL
|