Sql-Server
我可以在事件發生時收到通知嗎?
SQL Servers 有 Traces 和 XEvents。這些用於擷取和分析我們的 SQL Server 實例的情況。事件儲存在堆棧中以供以後分析。例如,如果我決定監視數據庫中的任何死鎖,我只需查詢跟踪文件以查看一段時間內的死鎖歷史記錄。這是我的問題:
當事件發生時,在我們的範例死鎖事件中,有沒有辦法使用 msdb.dbo.xp_send_dbmail 獲取電子郵件通知?
是的,您可以使用事件通知來處理死鎖/阻塞/創建數據庫/刪除數據庫,以及此處概述的更多事件。
下面是幫助您實時檢測死鎖和發送電子郵件的腳本:
它將創建一個警報以及一個 TSQL 作業來觸發,並將所有詳細資訊通過電子郵件發送給 DBA 團隊。在此處尋找更改以替換所需的東西。
use dba_db ---- change HERE use find and replace as per your database name !! go /******************************************************************** Job Name : Monitoring - Deadlock Detector Created by : Kin for dba.stackexchange.com Version : V1.0 Funtionality: 1. Real time Deadlock detection using WMI 2. Send email out when deadlock occurs along with Deadlock Graph attached. 3. Logs all the deadlocks in a central Table dba_db.dbo.Deadlock 4. Does not require trace flags 1204 and 1222 enabled *********************************************************************/ IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[Deadlock]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1) Print ' *** Table Deadlock Table Already Exists... moving Further *** ' ELSE create table Deadlock ( RecordId int identity (1,1) primary key not null, AlertTime datetime not null, DeadlockGraph xml, Notified int not null constraint [DF_deadlock_flag] default (0) ) go create index deadlock_idx on Deadlock (AlertTime) with fillfactor = 100 go USE [msdb] GO -- No need to enable deadlock trace flags --dbcc traceon (1204,1222,-1) --go -- enable replace runtime tokens for sql agent to respond to WMI alets USE [msdb] GO EXEC msdb.dbo.sp_set_sqlagent_properties @alert_replace_runtime_tokens=1 GO -- create the job USE [msdb] GO BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) BEGIN EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback END DECLARE @jobId BINARY(16) EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'Monitoring - Deadlock Detector', @enabled=1, @notify_level_eventlog=0, @notify_level_email=0, @notify_level_netsend=0, @notify_level_page=0, @delete_level=0, @description=N'Job Name : Monitoring - Deadlock Detector Created by : Kin for dba.stackexchange.com Version : V1.0 Funtionality: 1. Real time Deadlock detection using WMI 2. Send email out when deadlock occurs along with Deadlock Graph attached. 3. Logs all the deadlocks in a central Table dba_db.dbo.Deadlock 4. Does not require trace flags 1204 and 1222 enabled', @category_name=N'[Uncategorized (Local)]', @owner_login_name=N'sa', @job_id = @jobId OUTPUT IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Insert Deadlock info', @step_id=1, @cmdexec_success_code=0, @on_success_action=3, @on_success_step_id=0, @on_fail_action=2, @on_fail_step_id=0, @retry_attempts=0, @retry_interval=0, @os_run_priority=0, @subsystem=N'TSQL', @command=N'INSERT INTO Deadlock ( AlertTime, DeadlockGraph ) VALUES ( GETDATE(), ''$(ESCAPE_NONE(WMI(TextData)))'' )', @database_name=N'dba_db', @flags=0 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback /****** Object: Step [Send Email with Deadlock Graph] Script Date: 10/01/2010 12:01:45 ******/ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Send Email with Deadlock Graph', @step_id=2, @cmdexec_success_code=0, @on_success_action=1, @on_success_step_id=0, @on_fail_action=2, @on_fail_step_id=0, @retry_attempts=0, @retry_interval=0, @os_run_priority=0, @subsystem=N'TSQL', @command=N'if exists (select 1 from dba_db.dbo.Deadlock where notified = 0 ) begin declare @tableHTML nvarchar(max) set @tableHTML =N''<H3><FONT SIZE="3" FACE="Tahoma">Deadlock Has occured on ''+@@servername+'' .. Please Investigate Immediately </FONT></H3>'' set @tableHTML = @tableHTML+ N''<table border="1">'' + N''<FONT SIZE="2" FACE="Calibri">'' + N''<tr><th align="center">RecordId</th>'' + N''<th align="center">AlertTime</th>'' + N''<th align="center">DeadlockGraph</th>'' + N''</tr>'' + ISNULL(CAST ( ( select td = '''', td = RecordId,'''', td = AlertTime,'''', td = DeadlockGraph,'''' from dba_db.dbo.Deadlock where notified = 0 FOR XML PATH(''tr''), TYPE ) AS NVARCHAR(MAX) ),'''') + N''</FONT>'' + N''</table>'' ; -- bcp out as .xdl file. This is the deadlock graph that will be emailed. Note that it will be overwritten everytime !! exec master..xp_cmdshell ''BCP.exe "SELECT [Deadlockgraph].query(''''/TextData/deadlock-list'''') FROM dba_db.dbo.Deadlock where Notified = 0" queryout "d:\logs\deadlock.xdl" -c -q -T -Slocalhost''; ---- change localhost ..with the servername\instance or servername !! -- send email out with the graph attached declare @subject1 varchar(50) set @subject1 = ''Deadlock Has Occured on ''+@@servername EXEC msdb.dbo.sp_send_dbmail @profile_name = ''DBMAIL PROFILE'', ---- change HERE db mail profile !! @recipients=''DBAcompanyGroup@companyName.com'', ---- change HERE email group!! @subject = @subject1, @body = @tableHTML, @body_format = ''HTML'', @file_attachments = ''D:\logs\Deadlock.xdl''; ---- change HERE deadlock graph location!! end go -- update the Deadlock table so that when the job runs it wont send out previous alert update dba_db.dbo.Deadlock set Notified = 1 where notified = 0 --SELECT * FROM dba_db.dbo.Deadlock', @database_name=N'dba_db', @flags=0 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback COMMIT TRANSACTION GOTO EndSave QuitWithRollback: IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION EndSave: -- create an WMI alert to respond to deadlocks IF EXISTS (SELECT name FROM msdb.dbo.sysalerts WHERE name = N'Respond to Deadlock') EXEC msdb.dbo.sp_delete_alert @name=N'Respond to Deadlock' GO DECLARE @server_namespace varchar(255) IF ISNULL(CHARINDEX('\', @@SERVERNAME), 0) > 0 SET @server_namespace = N'\\.\root\Microsoft\SqlServer\ServerEvents\' + SUBSTRING(@@SERVERNAME, ISNULL(CHARINDEX('\', @@SERVERNAME), 0) + 1, LEN(@@SERVERNAME) - ISNULL(CHARINDEX('/', @@SERVERNAME), 0)) ELSE SET @server_namespace = N'\\.\root\Microsoft\SqlServer\ServerEvents\MSSQLSERVER' EXEC msdb.dbo.sp_add_alert @name=N'Respond to Deadlock', @wmi_namespace=@server_namespace, @wmi_query=N'SELECT * FROM DEADLOCK_GRAPH', @job_name='Monitoring - Deadlock Detector' ; GO
是的,您可以監視此事件。有許多方法可以做到這一點,許多第三方應用程序都可以做到這一點,但您可以在 SQL Server 中處理所有這些。
您將需要創建一個儲存過程來讀取錯誤日誌並擷取您感興趣的事件,並使用該 sp 通過 dbmail 將它們發送出去。然後,您需要創建一個 SQL 代理作業,以您確定的任何時間間隔呼叫此儲存過程。
有很多很好的例子來說明如何做到這一點,創建儲存過程和 SQL 代理作業,所以我不會進入編碼。這是來自 MSSQLTIPS錯誤日誌監控的人們的一個很好的入門文章