SQL Server 死鎖的告警監控

2021-09-19 21:51:46 字數 3753 閱讀 2180

原文:

sql server 死鎖的告警監控

今天這篇文章總結一下如何監控sql server的死鎖,其實以前寫過ms sql 監控錯誤日誌的告警資訊,這篇文章著重介紹如何監控資料庫的死鎖,當然這篇文章不分析死鎖產生的原因、以及如何解決死鎖。死鎖(dead lock)的錯誤資訊在sys.messages中的message_id為1205,可以使用下面sql檢視。

select

*from

sys.

messages

where

message_id

=1205

那麼接下來,我們來設定一下死鎖(dead lock)告警吧, 如下所示,當然你可以使用ui介面設定。

use [msdb]
go
if

notexists(select 1 from msdb.dbo.syscategories where name='dba_monitoring'

and category_class=2)

begin
exec msdb.dbo.sp_add_category
@class=n'alert',
@type=n'none',
@name=n'dba_monitoring' ;
end
go
if

exists(select 1 from msdb.dbo.sysalerts where name='sql server dead lock detected')

begin
exec msdb.dbo.sp_delete_alert @name=n'sql server dead lock detected';
end
go
if

notexists(select 1 from msdb.dbo.sysalerts where name='sql server dead lock detected')

begin
exec msdb.dbo.sp_add_alert @name=n'sql server dead lock detected',
@message_id=1205,
@severity=0,
@enabled=1,
@delay_between_responses=0,
@include_event_description_in=1,
@category_name=n'dba_monitoring',
@job_id=n'00000000-0000-0000-0000-000000000000'
end
go
if

notexists ( select  *

from    msdb.dbo.sysnotifications
where   alert_id = ( select id
from   msdb.dbo.sysalerts
where  name = 'sql server dead lock detected'
) )
begin
exec msdb.dbo.sp_add_notification @alert_name = n'sql server dead lock detected',
@operator_name = n'yoursqldba_operator', @notification_method = 1;
end;
go
執行上面指令碼後,就會在sql server的告警裡面新增乙個名為sql server dead lock detected'的告警,那麼現在是否ok了呢?當然不是,我們來測試驗證一下吧,首先準備測試的表和資料。  

useyoursqldba;

gocreate

table

deadlock1

(id

intdefault(0

));

create

table

deadlock2

(id

intdefault(0

));

insert

into

deadlock1

values(1

); insert

into

deadlock2

values(1

); go   

如下所示,在兩個會話視窗執行下面指令碼,構造死鎖出現的場景。 --

會話視窗1執行下面

sqlbegin

tran

update

deadlock1

setid=id

+1;

waitfor

delay

'00:00:20';

select

*from

deadlock2

rollback

tran;

exec

master

..sp_altermessage

1205

,'with_log'

,true;

go--

會話建立2執行下面

sqlbegin

tran

update

deadlock2

setid=id

+1;

waitfor

delay

'00:00:20';

select

*from

deadlock1

rollback

tran;

如下截圖所示,當死鎖出現後,那麼這個告警設定是否會傳送郵件出來呢? 答案是否定的,你可以檢查告警的歷史情況,如下所示:

從history介面,我們可以看到這個告警沒有被觸發,那麼這個是什麼原因呢?原因其實很簡單,因為message_id為1205的訊息欄位is_event_logged預設是0,這意味著出現錯誤訊息將不會記入事件日誌。我們可以使用小sql將其值設定為1 

go執行上面指令碼後,message_id為1205的記錄的is_event_logged字段值將被設定為1,當資料庫出現死鎖時,就會被記錄到錯誤日誌,當然這個只是簡單訊息的記錄,如果你要跟蹤、解決死鎖問題,就需要記錄死鎖的詳細資訊,需要在服務端針對所有的session開啟trace flag 1222。

SQL Server 中的死鎖

在兩個或多個任務中,如果每個任務鎖定了其他的任務試圖鎖定的資源,會造成這些任務永久阻塞,從而出現死鎖。此時系統處於死鎖狀態。死鎖的原因 在多使用者環境下,死鎖的發生是由於兩個事物都鎖定了不同的資源而又都在申請對方鎖定的資源,即一組程序中的各個程序均占有不會釋放的資源,但因相互申請其他程序占用的不會釋...

sqlserver死鎖阻塞

create proc p lockinfo kill lock spid bit 1,是否殺掉死鎖的程序,1 殺掉,0 僅顯示 show spid if nolock bit 1 如果沒有死鎖的程序,是否顯示正常程序資訊,1 顯示,0 不顯示 as declare count int,s nvar...

SQL Server清除死鎖

1 首先需要判斷是哪個使用者鎖住了哪張表.查詢被鎖表 select request session id spid,object name resource associated entity id tablenamefrom sys.dm tran locks where resource typ...