Sql-Server

如何根據 SQL Server 上預設未列出的驗證創建全新警報?

  • April 27, 2022

我想創建一個警報,就像 Brent Ozar 的How to Configure SQL Server Agent Alerts中的警報一樣,但是我找不到與我想在 sys.messages 上監視的錯誤相關的消息,正如sp_add_alert文件所說的那樣,我想要的問題監控沒有產生任何記錄的錯誤。如果我只使用sp_addmessage,我相信我仍然缺少觸發錯誤的驗證。如果我創建一個作業來進行驗證,我不需要警報,因為該作業可以自己發送電子郵件。

創建新警報的正確方法是什麼?

背景

最近,我環境中的應用程序開始無法在 SQL Server 上連接,我們花了一些時間才注意到問題是由於實例達到了實例的 32k 限制(SQL Server 最多允許 32,767 個使用者連接)。連接吞噬者是一個配置錯誤的應用程序,開發人員現在已經糾正了它,但我不想再次感到驚訝,因為其他一些應用程序導致了同樣的情況,因此需要警報。當連接數達到 10K 之類的限制時發出警報會很好,但如果達到 32K 限制就發出警報會有所幫助。

你沒有錯過任何東西。代理事件警報需要事件日誌中的 sql server 實例出錯。代理每 20 秒輪詢一次事件日誌。非常簡單直接。

因此,如果您需要自己產生該錯誤(如在本例中),您不妨從該程式碼發送電子郵件,而不是繞過事件警報。

按照AMtwoTibor Karaszi的指示,我決定創建一個 Agent 作業來驗證是否超過了門檻值,如果是,將報告消耗最多連接的前 10 個應用程序。我可以得到我需要的資訊:

--The number of connections to be considered abnormal for your environment.
--It should be bellow SQL Server max supported 32,767 user connections
DECLARE @ConnectionThreshold int = 1000;

IF @ConnectionThreshold < (SELECT COUNT(*) FROM sys.dm_exec_connections)

--List the top 10 apps using connections
SELECT TOP(10)
   s.login_name    AS [Login name],
   s.host_name     AS [Host name],
   d.name          AS [Database name],
   s.program_name  AS [Program name],
   COUNT(*)        AS [Connections]
FROM sys.dm_exec_connections AS c  
   INNER JOIN sys.dm_exec_sessions AS s  
       ON c.session_id = s.session_id
   INNER JOIN sys.databases AS d
       ON s.database_id = d.database_id
GROUP BY s.login_name,
   s.host_name,
   d.name,
   s.program_name
ORDER BY COUNT(*) DESC;

為了生成內容更豐富、格式更佳的電子郵件,我從 AMtwo 的SQL Server Blocking 警報中藉鑑了一些想法(不是說大部分程式碼),結果如下:

--The number of connections to be considered abnormal for the environment.
--It should be bellow SQL Server max supported 32,767 user connections
DECLARE @ConnectionThreshold int = 1000;

IF @ConnectionThreshold < (SELECT COUNT(*) FROM sys.dm_exec_connections)
BEGIN
   DECLARE @EmailBody nvarchar(4000);
   SELECT @EmailBody = dbo.EmailCSS_Get();

   SELECT @EmailBody = @EmailBody + N'<h2>Top 10 apps connected:</h2>' + CHAR(10) +
           N'<table><tr>' +
           N'<th>Login name</th>' +
           N'<th>Host name</th>' +
           N'<th>Database name</th>' +
           N'<th>Program name</th>' +
           N'<th>Connections</th>' +
           N'</tr>' +
           CAST(( SELECT TOP(10)
                       td = s.login_name, '',
                       td = s.host_name, '',
                       td = d.name, '',
                       td = s.program_name, '',
                       td = COUNT(*), ''
                   FROM sys.dm_exec_connections AS c  
                       INNER JOIN sys.dm_exec_sessions AS s  
                           ON c.session_id = s.session_id
                       INNER JOIN sys.databases AS d
                           ON s.database_id = d.database_id
                   GROUP BY s.login_name,
                       s.host_name,
                       d.name,
                       s.program_name
                   ORDER BY COUNT(*) DESC
                   FOR XML PATH ('tr'), ELEMENTS
                   ) AS nvarchar(max)) +
           N'</table>';

   SELECT @EmailBody = @EmailBody + '<hr>' + dbo.EmailServerInfo_Get();

   EXEC msdb.dbo.sp_send_dbmail  
       @profile_name = 'YourMailProfile',  
       @recipients = 'yourEmail@job.com',
       @subject = 'Number of connections above defined threshold',  
       @body = @EmailBody,
       @body_format = 'HTML';
END

此程式碼已添加到每隔一段時間執行的作業中,並在需要時以格式化的電子郵件發送警報。它成功了。


引用內容:

dbo.EmailCSS_Get()

dbo.EmailServerInfo_Get()

引用自:https://dba.stackexchange.com/questions/311360