1. 程式人生 > >SQL:查找被鎖的表,以及鎖表的SQL語句(重點推薦)

SQL:查找被鎖的表,以及鎖表的SQL語句(重點推薦)

內存 結果 dea 但我 使用 相同 以及 serve 釋放

技術分享
--死鎖檢測 
use master 
Select * from sysprocesses where blocked<>0 
--找到SPID   
exec sp_lock 
--根據SPID找到OBJID 
select object_name(85575343) 
--根據OBJID找到表名
技術分享

1.DatabaseName 同於你要監測的數據庫名(不過這個好像不起作用,我的電腦上設置無效)
2.DatabaseID 同於你要檢測的數據庫的dbid,可以用 selectdb_id(N‘你要監測的庫名‘)得到dbid
3.ObjectName 同於你要監測的對象名,例如表名,視圖名等
4.ObjectID 同於你要監測的對象的id,可以用 select object_id(N‘你要監測的對象名‘)得到id
5.Error 同於錯誤,如果經常出現某個編號的錯誤,則針對此錯誤號
6.Seccess 同於0,失敗,1,成功,如果是排錯,就過濾掉成功的處理

select db_id(N‘ChinaHNDB_2013‘) --得到dbid
select object_name(1813581499) 

//*****************以下為SQL進行跟蹤,並得到跟蹤日誌,再結合SQL Server Profiler 分析 *******************************

declare @rc int
declare @TraceID int
declare @FileName sysname
declare @maxfilesize bigint
set @maxfilesize = 5
SELECT @FileName = ‘E:\lock2‘

-- 初始化跟蹤
exec @rc = sp_trace_create @TraceID output, 0, @FileName, @maxfilesize, NULL
--此處的e:/dblog/deadlockdetect是文件名(可自行修改),SQL會自動在後面加上.trc的擴展名
if (@rc != 0) goto error

-- 設置跟蹤事件
declare @on bit
set @on = 1
--下述語句中的148指的是locks:deadlock graph事件(參見sys.trace_events),12指的是spid列(參見sys.trace_columns)
exec sp_trace_setevent @TraceID, 148, 12, @on
exec sp_trace_setevent @TraceID, 148, 11, @on
exec sp_trace_setevent @TraceID, 148, 4, @on
exec sp_trace_setevent @TraceID, 148, 14, @on
exec sp_trace_setevent @TraceID, 148, 26, @on
exec sp_trace_setevent @TraceID, 148, 64, @on
exec sp_trace_setevent @TraceID, 148, 1, @on

-- 啟動跟蹤
exec sp_trace_setstatus @TraceID, 1

-- 記錄下跟蹤ID,以備後面使用
select TraceID = @TraceID
goto finish

error:
select [email protected]

finish:
go


exec sp_trace_setstatus 2, 0
exec sp_trace_setstatus 2, 2

select * from fn_trace_gettable(‘E:\lock2.trc‘,1)

/*
如果要暫停上面的服務器端跟蹤,可運行下面的語句:
exec sp_trace_setstatus 3, 0 --第一個參數表示TraceID,即步驟1中的輸出參數。第二個參數表示將狀態改為0,即暫停

如果要停止上面的服務器端跟蹤,可運行下面的語句:
exec sp_trace_setstatus 3, 2 --第一個參數表示TraceID,即步驟1中的輸出參數。第二個參數表示將狀態改為2,即停止


對於上面生成的跟蹤文件(e:/DbLog/deadlockdetect.trc),可通過兩種方法查看:
1.
select * from fn_trace_gettable(‘e:/DbLog/deadlockdetect.trc‘,1)
結果中的TextData列即以XML的形式返回死鎖的詳細信息。

2.
在SQL Server Profiler中打開。
依次 進入Profiler -> 打開跟蹤文件 ->選擇e:/DbLog/deadlockdetect.trc,就可以看到以圖形形式展現的死鎖信息了。

//*****************************************************************************************************

方法二: 用SQL Server Profiler分析死鎖(重點推薦,2014-4-3編輯)

1. 打開 SQL Server Management Studio >>工具 >> SQL Server Profiler

2.創建一個新的跟蹤

3.在事件選擇頁中,先勾選顯示所有事件,再選擇“死鎖圖形”事件、 “鎖定:死鎖”和“鎖定:死鎖鏈” (Deadlock graph,Lock:Deadlock;Lock:Deadlock Chain )如下圖所示:

技術分享

,最後 取消其它默認事件選項((Deadlock graph,Lock:Deadlock;Lock:Deadlock Chain 以外事件) ,並運行。

4. 跟蹤一段時間,事務執行中止結束,選擇Deadlock graph,我們可以直觀查看到事務之間發生死鎖的原因:

技術分享

上圖的橢圓形有一個叉,表示事務被SQL Server選擇為死鎖犧牲品,如果我們把鼠標指針移動到該叉橢圓中會出現一個提示。被鎖定Object 為Proc存儲過程(可以根據ID ,select object_id(N‘ID)

二個矩形框稱為資源節點,它們代表的數據庫對象,如表,行或索引。

由於事務A和B在擁有各自資源時試圖獲得對方資源的一個獨占鎖,使得進程相互等待對方釋放資源從而導致死鎖。

解決死鎖

這裏有幾個方法可以幫助我們解決死鎖問題。

優化查詢

我們在寫查詢語句時,要考慮一下查詢是否Join了沒有必要的表?是否返回數據太多(太多的列或行)?查詢是否執行表掃描?是否能通過調整查詢次序來避免死鎖?是否應該使用Join的地方使用了Left Join?Not In語句是否考慮周到?

我們在寫查詢語句可以根據以上準則來考慮查詢是否應該做出優化。

慎用With(NoLock)

默認情況下SELECT語句會對查詢到的資源加S鎖(共享鎖),由於S鎖與X鎖(排他鎖)不兼容,在加上With(NoLock)後,SELECT不對查詢到的資源加鎖(或者加Sch-S鎖,Sch-S鎖可以與任何鎖兼容);從而使得查詢語句可以更好和其他語句並發執行,適用於表數據更新不頻繁的情況。

也許有些人會提出質疑With(NoLock),可能會導致臟讀,首先我們要考慮查詢的表是否頻繁進行更新操作,而且是否要讀回來的數據會被修改,所以衡量是否使用With(NoLock)還是要根據具體實際出發。

優化索引

是否有任何缺失或多余的索引?是否有任何重復的索引?

處理死鎖

我們不能時刻都觀察死鎖的發生,但我們可以通過日誌來記錄系統發生的死鎖,我們可以把系統的死鎖錯誤寫入到表中,從而方便分析死鎖原因。

緩存

也許我們正在執行許多相同的查詢非常頻繁,如果我們把這些頻繁的操作都放到Cache中,執行查詢的次數將減少發生死鎖的機會。我們可以在數據庫的臨時表或表,或內存,或磁盤上應用Cache,或是磁盤文件。

SQL:查找被鎖的表,以及鎖表的SQL語句(重點推薦)