[zt] sql server 死鎖總結
deadlocks(死鎖)
所謂死鎖
由於資源佔用是互斥的,當某個程式提出申請資源後,使得有關程式在無外力協助下,永遠分配不到必需的資源而無法繼續執行,這就產生了一種特殊現象死鎖。
一種情形,此時執行程式中兩個或多個執行緒發生永久堵塞(等待),每個執行緒都在等待被其他執行緒佔用並堵塞了的資源。例如,如果執行緒A鎖住了記錄1並等待記錄2,而執行緒B鎖住了記錄2並等待記錄1,這樣兩個執行緒就發生了死鎖現象。
計算機系統中,如果系統的資源分配策略不當,更常見的可能是程式設計師寫的程式有錯誤等,則會導致程式因競爭資源不當而產生死鎖的現象。
產生死鎖的原因主要是:
(1) 因為系統資源不足。
(2) 程式執行推進的順序不合適。
(3) 資源分配不當等。
如果系統資源充足,程式的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則就會因爭奪有限的資源而陷入死鎖。其次,程式執行推進順序與速度不同,也可能產生死鎖
產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個程式使用。
(2) 請求與保持條件:一個程式因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:程式已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 迴圈等待條件:若干程式之間形成一種頭尾相接的迴圈等待資源關係。這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之 一不滿足,就不會發生死鎖。
死鎖的解決:預防和解除
1。死鎖的預防:1)一次封鎖法:就是要求每個事務必須一次將所有要使用的資料全部加鎖,否則就不能繼續執行。但是出現這樣的問題:因為一次給全部資料加鎖,從而降低系統的併發度,同時資料庫中資料是不斷變化的,原來不要求封鎖的資料在執行過程中可能會變成封鎖物件。2)順序封鎖法,預先對資料物件規定一個封鎖順序,所有事務都按這個順序實行封鎖,問題:資料庫中資料物件多,且不斷的變化,維護困難,成本高;事務的封鎖請求可以隨著事務的執行而動態的決定。
2。檢測死鎖
企業管理器->可以在[管理]->[當前活動] 裡看到阻塞資訊(有時SQL Server企業管理器會因為鎖太多而沒有響應).
設定跟蹤1204:
USE MASTER
DBCC TRACEON (1204,-1)
顯示當前啟用的所有跟蹤標記的狀態:
DBCC TRACESTATUS(-1)
取消跟蹤1204:
DBCC TRACEOFF (1204,-1)
在設定跟蹤1204後,會在資料庫的日誌檔案裡顯示SQL Server資料庫死鎖時一些資訊。但那些資訊很難看懂,需要對照SQL Server聯機叢書仔細來看。根據PAG鎖要找到相關資料庫表的方法:
DBCC TRACEON (3604)
DBCC PAGE (db_id,file_id,page_no)
DBCC TRACEOFF (3604)
可以使用以下儲存過程來檢測,就可以查出引起死鎖的程式和SQL語句。
寫了一個系統儲存過程sp_who_lock.sql。程式碼如下:
if exists (select * from dbo.sysobjects
where id = object_id(N'[dbo].[sp_who_lock]')
and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_who_lock]
GO
/**//********************************************************
// 說明 : 檢視資料庫裡阻塞和死鎖情況
********************************************************/
use master
go
create procedure sp_who_lock
as
begin
declare @spid int,@bl int,
@intTransactionCountOnEntry int,
@intRowcount int,
@intCountProperties int,
@intCounter int
create table #tmp_lock_who (
id int identity(1,1),
spid smallint,
bl smallint)
IF @@ERROR<>0 RETURN @@ERROR
insert into #tmp_lock_who(spid,bl) select 0 ,blocked
from (select * from sysprocesses where blocked>0 ) a
where not exists(select * from (select * from sysprocesses
where blocked>0 ) b
where a.blocked=spid)
union select spid,blocked from sysprocesses where blocked>0
IF @@ERROR<>0 RETURN @@ERROR
-- 找到臨時表的記錄數
select @intCountProperties = Count(*),@intCounter = 1
from #tmp_lock_who
IF @@ERROR<>0 RETURN @@ERROR
if @intCountProperties=0
select '現在沒有阻塞和死鎖資訊' as message
-- 迴圈開始
while @intCounter <= @intCountProperties
begin
-- 取第一條記錄
select @spid = spid,@bl = bl
from #tmp_lock_who where Id = @intCounter
begin
if @spid =0
select '引起資料庫死鎖的是: '+ CAST(@bl AS VARCHAR(10))
+ '程式號,其執行的SQL語法如下'
else
select '程式號SPID:'+ CAST(@spid AS VARCHAR(10))+ '被'
+ '程式號SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其當前程式執行的SQL語法如下'
DBCC INPUTBUFFER (@bl )
end
-- 迴圈指標下移
set @intCounter = @intCounter + 1
end
drop table #tmp_lock_who
return 0
end
需要的時候直接呼叫:
sp_who_lock
就可以查出引起死鎖的程式和SQL語句.
我們還可以設定鎖的超時時間(單位是毫秒), 來縮短死鎖可能影響的時間範圍:
例如:
use master
seelct @@lock_timeout
set lock_timeout 900000
-- 15分鐘
seelct @@lock_timeout
*********************************************************************************************************
常看到死鎖的問題,一般都是KILL程式,但如果不查出引起死鎖的原因,死鎖會時常發生
可以透過查詢引起死鎖的的操作,就可以方便的解決死鎖,現將日常解決問題的方法總結,也許對大家有幫助
1\死鎖發生時,透過如下語法,查詢出引起死鎖的操作
use master
go
declare @spid int,@bl int
DECLARE s_cur CURSOR FOR
select 0 ,blocked
from (select * from sysprocesses where blocked>0 ) a
where not exists(select * from (select * from sysprocesses where blocked>0 ) b
where a.blocked=spid)
union select spid,blocked from sysprocesses where blocked>0
OPEN s_cur
FETCH NEXT FROM s_cur INTO @spid,@bl
WHILE @@FETCH_STATUS = 0
begin
if @spid =0
select '引起資料庫死鎖的是: '+ CAST(@bl AS VARCHAR(10)) + '程式號,其執行的SQL語法如下'
else
select '程式號SPID:'+ CAST(@spid AS VARCHAR(10))+ '被' + '程式號SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其當前程式執行的SQL語法如下'
DBCC INPUTBUFFER (@bl )
FETCH NEXT FROM s_cur INTO @spid,@bl
end
CLOSE s_cur
DEALLOCATE s_cur
exec sp_who2
2\查詢程式/資料庫,此t_sql語法在什麼地方使用
3\分析找到的,並解決問題
EG:
/*
-------------------------------------------------------
引起資料庫死鎖的是: 71程式號,其執行的SQL語法如下
EventType Parameters EventInfo
-------------- ---------- ------------------------------------------------
Language Event 0
select * from test
insert test values(1,2)
(所影響的行數為 1 行)
DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯絡。
------------------------------------------------------------------------------
程式號SPID:64被程式號SPID:71阻塞,其當前程式執行的SQL語法如下
EventType Parameters EventInfo
-------------- ---------- ------------------------------------------------
Language Event 0
select * from test
insert test values(1,2)
(所影響的行數為 1 行)
DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯絡。
------------------------------------------------------------------------------
程式號SPID:65被程式號SPID:64阻塞,其當前程式執行的SQL語法如下
EventType Parameters EventInfo
-------------- ---------- --------------------------------------------------------------------------------------------------
Language Event 0 begin tran
select * from test with (holdlock)
waitfor time '12:00'
select * from test
commit
(所影響的行數為 1 行)
DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯絡。
------------------------------------------------------------------------------
程式號SPID:73被程式號SPID:64阻塞,其當前程式執行的SQL語法如下
EventType Parameters EventInfo
-------------- ---------- --------------------------------------------------------------------------------------------------
Language Event 0 begin tran
select * from test with (holdlock)
waitfor time '12:00'
select * from test
commit
(所影響的行數為 1 行)
DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯絡。
*/
***************************************************************************************************
解決方法:
讓使用者(即先讀後寫型別的操作),在select 時就是用Update lock
語法如下:
select * from table1 with(updlock) where ....
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-594879/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL Server 的死鎖SQLServer
- SQL SERVER死鎖查詢,死鎖分析,解鎖,查詢佔用SQLServer
- SQL Server 2005效能調整一(zt)SQLServer
- SQL Server 2005效能調整二(zt)SQLServer
- 在 SQL Server 中查詢活動連線和死鎖SQLServer
- SQL Server 資料庫查詢死鎖的處理步驟SQLServer資料庫
- 如何捕獲和記錄SQL Server中發生的死鎖SQLServer
- SQL Server自增列跳號總結SQLServer
- SYBASE優化總結(zt)優化
- 檢視oracle死鎖程式並結束死鎖Oracle
- [翻譯]:SQL死鎖-阻塞探測SQL
- 關於SQL Server中索引使用及維護簡介(zt)SQLServer索引
- SQL Access Advisor(zt)SQL
- SQL Server 索引結構SQLServer索引
- Sql Server關於indexed view索引檢視的總結SQLServerIndexView索引
- SqlServer鎖的概述(zt)SQLServer
- Sql Server深入的探討鎖機制SQLServer
- SQL Server 遷移至MySQL 關鍵步驟的梳理總結ServerMySql
- SQL Server中GROUP BY(連結)SQLServer
- 死鎖
- 死月的二零二一總結
- 死月的二零二零總結
- [轉帖]SQL Server 鎖機制 悲觀鎖 樂觀鎖 實測解析SQLServer
- MySQL鎖總結MySql
- Oracle SQL optimization-2(zt)OracleSQL
- SQLServer 如何收集資料以排除 SQL 死鎖問題SQLServer
- 面試官:請用SQL模擬一個死鎖面試SQL
- 什麼是死鎖?如何解決死鎖?
- 基於Sql server資料庫的四種分頁方式總結SQLServer資料庫
- 死月的二零二二總結
- 面試官:什麼是死鎖?怎麼排查死鎖?怎麼避免死鎖?面試
- 死鎖概述
- Microsoft SQL Server 2005中查詢優化器使用的統計資訊二(zt)ROSSQLServer優化
- Microsoft SQL Server 2005中查詢優化器使用的統計資訊一(zt)ROSSQLServer優化
- Microsoft SQL Server 2005中查詢優化器使用的統計資訊三(zt)ROSSQLServer優化
- 分散式鎖總結分散式
- SQL優化器探討(zt)SQL優化
- 作業系統(5) 死鎖的概念 死鎖產生的必要條件 死鎖的處理策略 預防死鎖 避免死鎖 死鎖的檢測和解除 銀行家演算法作業系統演算法
- 例項詳解 Java 死鎖與破解死鎖Java