當前位置:首頁 » 編程語言 » sql查詢死鎖語句
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql查詢死鎖語句

發布時間: 2022-08-29 07:17:34

『壹』 如何排查sql死鎖的錯誤

1. 開啟死鎖日誌輸出(deadlock trace)

DBCC TRACEON(1204,1222)

Trace flag 1204 reports deadlock information formatted by each node involved in the deadlock.
Trace flag 1222 formats deadlock information, first by processes and then by resources.

開啟了上面的選項之後, SQL會輸出死鎖的細節信息到SQL Error Log中(默認位置Program Files\Microsoft SQL Server\MSSQL.n\MSSQL\LOG\ERRORLOG and ERRORLOG.n)

2. 開啟SQL Profiler.
Start SQL profiler
On the Trace Properties dialog box, on the General tab, check Save to file and specify a path to save the trace
Click the Events tab, only add Locks\Lock:deadlock and Locks\Lock:deadlock chain
Click the Data columns tab, add DatabaseID, IndexID, ObjectID
可以通過下面的語句把DatabaseID和ObjectID換成DatabaseName和ObjectName

SELECT database_name(DatabaseID)
SELECT object_name(ObjectID)

3. 使用下面的查詢語句來檢查那個進程被鎖住了.

SELECT * FROM sys.sysprocesses WHERE blocked <> 0
從Blocked列中得到SPID
DBCC inputbuffer (SPID)
sp_who2
sp_lock2

『貳』 如何查看SQL Server 2008的死鎖

在SQL Server 2008資料庫中,查看死鎖可以用存儲過程來實現,本文我們主要就介紹了SQL Server 2008查看死鎖的存儲過程的代碼示例,希望能夠對您有所幫助。
代碼示例如下:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_who_lock]') and OBJECTPROPERTY(id, N'IsProcere') = 1) drop procere [dbo].[sp_who_lock] GO use master go create procere 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 @spidspid = spid,@blbl = 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

以上就是SQL Server 2008查看死鎖的存儲過程的代碼示例的全部內容,本文我們就介紹到這里了,希望本次的介紹能夠對您有所收獲!

『叄』 檢查死鎖的SQL怎麼寫

查詢出來:
select
request_session_id spid,
OBJECT_NAME(resource_associated_entity_id) tableName
from
sys.dm_tran_locks
where
resource_type='OBJECT

殺死死鎖進程:
kill spid

『肆』 如何查看SQL表死鎖

SELECT SPID=p.spid,
DBName = convert(CHAR(20),d.name),
ProgramName = program_name,
LoginName = convert(CHAR(20),l.name),
HostName = convert(CHAR(20),hostname),
Status = p.status,
BlockedBy = p.blocked,
LoginTime = login_time,
QUERY = CAST(t.TEXT AS VARCHAR(MAX))
FROM MASTER.dbo.sysprocesses p
INNER JOIN MASTER.dbo.sysdatabases d
ON p.dbid = d.dbid
INNER JOIN MASTER.dbo.syslogins l
ON p.sid = l.sid
CROSS APPLY sys.dm_exec_sql_text(sql_handle) t
WHERE p.blocked = 0
AND EXISTS (SELECT 1
FROM MASTER.dbo.sysprocesses p1
WHERE p1.blocked = p.spid)
SELECT SPID=p.spid,
DBName = convert(CHAR(20),d.name),
ProgramName = program_name,
LoginName = convert(CHAR(20),l.name),
HostName = convert(CHAR(20),hostname),
Status = p.status,
BlockedBy = p.blocked,
LoginTime = login_time,
QUERY = CAST(t.TEXT AS VARCHAR(MAX))
FROM MASTER.dbo.sysprocesses p
INNER JOIN MASTER.dbo.sysdatabases d
ON p.dbid = d.dbid
INNER JOIN MASTER.dbo.syslogins l
ON p.sid = l.sid
CROSS APPLY sys.dm_exec_sql_text(sql_handle) t
WHERE p.blocked = 0
AND EXISTS (SELECT 1
FROM MASTER.dbo.sysprocesses p1
WHERE p1.blocked = p.spid)
用這個查詢兩次,如果兩次都有某個語句就是了,可以用kill結束它

『伍』 MSSQLSERVER中怎樣查詢引起死鎖的sql語句

當死鎖發生後,通過服務端的Trace就可以將死鎖信息傳到日誌。在SQL Server 2000時代,只能通過Trace flag 1204來開啟,由於Trace flag 1204並不能提供XML死鎖圖,在SQL Server 2005以及之後的版本被Trace flag 1222所取代。
為了在服務端針對所有的Session開啟Trace flag 1222。可以通過如代碼所示。
DBCC TRACEON(1222,-1)

另一種方法是開啟Profiler來捕捉,Profiler捕捉到的圖示死鎖信息內容就更直觀了,

『陸』 怎樣查詢引起死鎖的sql語句

elect 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 )

『柒』 SQL的死鎖怎麼查進程

查詢出來:
select
request_session_id
spid,
OBJECT_NAME(resource_associated_entity_id)
tableName
from
sys.dm_tran_locks
where
resource_type='OBJECT
殺死死鎖進程:
kill
spid

『捌』 如何查看SQL死鎖

其實所有的死鎖最深層的原因就是一個:資源競爭
表現一:
一個用戶A 訪問表A(鎖住了表A),然後又訪問表B
另一個用戶B 訪問表B(鎖住了表B),然後企圖訪問表A

這時用戶A由於用戶B已經鎖住表B,它必須等待用戶B釋放表B,才能繼續,好了他老人家就只好老老實實在這等了
同樣用戶B要等用戶A釋放表A才能繼續這就死鎖了
解決方法:
這種死鎖是由於你的程序的BUG產生的,除了調整你的程序的邏輯別無他法
仔細分析你程序的邏輯,
1:盡量避免同時鎖定兩個資源
2: 必須同時鎖定兩個資源時,要保證在任何時刻都應該按照相同的順序來鎖定資源.

表現二:
用戶A讀一條紀錄,然後修改該條紀錄
這是用戶B修改該條紀錄
這里用戶A的事務里鎖的性質由共享鎖企圖上升到獨占鎖(for update),而用戶B里的獨占鎖由於A有共享鎖存在所以必須等A釋
放掉共享鎖,而A由於B的獨占鎖而無法上升的獨占鎖也就不可能釋放共享鎖,於是出現了死鎖。
這種死鎖比較隱蔽,但其實在稍大點的項目中經常發生。
解決方法:
讓用戶A的事務(即先讀後寫類型的操作),在select 時就是用Update lock
語法如下:
select * from table1 with(updlock) where ....

『玖』 sql server死鎖的進程怎麼處理

怎麼解除SQL Server死鎖的問題?SQL Server死鎖是我們經常會碰到的問題,下面就為您介紹如何查詢SQL Server死鎖,希望對您學習SQL Server死鎖方面能有所幫助。   
SQL Server死鎖的查詢方法:    exec master.dbo.p_lockinfo 0,0 ---顯示死鎖的進程,不顯示正常的進程    exec master.dbo.p_lockinfo 1,0 ---殺死死鎖的進程,不顯示正常的進程.   
SQL Server死鎖的解除方法:    Create proc p_lockinfo    @kill_lock_spid bit=1, --是否殺掉死鎖的進程,1 殺掉, 0 僅顯示    @show_spid_if_nolock bit=1 --如果沒有死鎖的進程,是否顯示正常進程信息,1 顯示,0 不顯示    as    declare @count int,@s nvarchar(1000),@i int    select id=identity(int,1,1),標志,    進程ID=spid,線程ID=kpid,塊進程ID=blocked,資料庫ID=dbid,   
資料庫名=db_name(dbid),用戶ID=uid,用戶名=loginame,累計CPU時間=cpu,    登陸時間=login_time,打開事務數=open_tran, 進程狀態=status,    工作站名=hostname,應用程序名=program_name,工作站進程ID=hostprocess,    域名=nt_domain,網卡地址=net_address    into #t from(    select 標志='死鎖的進程',    spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,    status,hostname,program_name,hostprocess,nt_domain,net_address,   
s1=a.spid,s2=0    from mastersysprocesses a join (    select blocked from mastersysprocesses group by blocked    )b on a.spid=b.blocked where a.blocked=0    union all    select '|_犧牲品_>',    spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,    status,hostname,program_name,hostprocess,nt_domain,net_address,    s1=blocked,s2=1    from mastersysprocesses a where blocked<>0    )a order by s1,s2    select @count=@@rowcount,@i=1    if @count=0 and @show_spid_if_nolock=1    begin    insert #t    select 標志='正常的進程',    spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,    open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address    from mastersysprocesses    set @count=@@rowcount    end    if @count>0    begin    create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))    if @kill_lock_spid=1    begin    declare @spid varchar(10),@標志 varchar(10)    while @i<=@ count    begin    select @spid=進程ID,@標志=標志 from #t whereid=@ i    insert #t1 exec('dbcc inputbuffer(')')    if @標志='死鎖的進程' exec('kill'+@ spid)    set @i=@i+1    end    end    else    while @i<=@ count    begin    select @s='dbcc inputbuffer('+cast(進程ID as varchar)+')' from #t whereid=@ i    insert #t1 exec(@s)    set @i=@i+1    end    select a.*,進程的SQL語句=b.EventInfo    from #t a join #t1 b on a.id=b.id    end

『拾』 用sql語句,怎麼解決mysql資料庫死鎖

MySQL死鎖問題的相關知識是本文我們主要要介紹的內容,接下來我們就來一一介紹這部分內容,希望能夠對您有所幫助。
1、MySQL常用存儲引擎的鎖機制
MyISAM和MEMORY採用表級鎖(table-level locking)
BDB採用頁面鎖(page-level locking)或表級鎖,默認為頁面鎖
InnoDB支持行級鎖(row-level locking)和表級鎖,默認為行級鎖
2、各種鎖特點
表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,並發度最低
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,並發度也最高
頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,並發度一般
3、各種鎖的適用場景
表級鎖更適合於以查詢為主,只有少量按索引條件更新數據的應用,如Web應用
行級鎖則更適合於有大量按索引條件並發更新數據,同時又有並發查詢的應用,如一些在線事務處理系統
4、死鎖
是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。
表級鎖不會產生死鎖。所以解決死鎖主要還是針對於最常用的InnoDB。
5、死鎖舉例分析
在MySQL中,行級鎖並不是直接鎖記錄,而是鎖索引。索引分為主鍵索引和非主鍵索引兩種,如果一條sql語句操作了主鍵索引,MySQL就會鎖定這條主鍵索引;如果一條語句操作了非主鍵索引,MySQL會先鎖定該非主鍵索引,再鎖定相關的主鍵索引。
在UPDATE、DELETE操作時,MySQL不僅鎖定WHERE條件掃描過的所有索引記錄,而且會鎖定相鄰的鍵值,即所謂的next-key locking。
例如,一個表db。tab_test,結構如下:
id:主鍵;
state:狀態;
time:時間;
索引:idx_1(state,time)
出現死鎖日誌如下:
?***(1) TRANSACTION:
?TRANSACTION 0 677833455, ACTIVE 0 sec, process no 11393, OSthread id 278546 starting index read
?mysql tables in use 1, locked 1
?LOCK WAIT 3 lock struct(s), heap size 320
?MySQL thread id 83, query id 162348740 dcnet03 dcnet Searching rows for update
?update tab_test set state=1064,time=now() where state=1061 and time < date_sub(now(), INTERVAL 30 minute) (任務1的sql語句)
?***(1) WAITING FOR THIS LOCK TO BE GRANTED: (任務1等待的索引記錄)
?RECORD LOCKS space id 0 page no 849384 n bits 208 index `PRIMARY` of table `db/tab_test` trx id 0 677833455 _mode X locks rec but not gap waiting
?Record lock, heap no 92 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
?0: len 8; hex 800000000097629c; asc b ;; 1: len 6; hex 00002866eaee; asc (f ;; 2: len 7; hex 00000d40040110; asc @ ;; 3: len 8; hex 80000000000050b2; asc P ;; 4: len 8; hex 800000000000502a; asc P*;; 5: len 8; hex 8000000000005426; asc T&;; 6: len 8; hex 800012412c66d29c; asc A,f ;; 7: len 23; hex 8616e642e706870; asc xxx.com/;; 8: len 8; hex 800000000000042b; asc +;; 9: len 4; hex 474bfa2b; asc GK +;; 10: len 8; hex 8000000000004e24; asc N$;;
?*** (2) TRANSACTION:
?TRANSACTION 0 677833454, ACTIVE 0 sec, process no 11397, OS thread id 344086 updating or deleting, thread declared inside InnoDB 499
?mysql tables in use 1, locked 1
?3 lock struct(s), heap size 320, undo log entries 1
?MySQL thread id 84, query id 162348739 dcnet03 dcnet Updating update tab_test set state=1067,time=now () where id in (9921180) (任務2的sql語句)
?*** (2) HOLDS THE LOCK(S): (任務2已獲得的鎖)
?RECORD LOCKS space id 0 page no 849384 n bits 208 index `PRIMARY` of table `db/tab_test` trx id 0 677833454 lock_mode X locks rec but not gap
?Record lock, heap no 92 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
?0: len 8; hex 800000000097629c; asc b ;; 1: len 6; hex 00002866eaee; asc (f ;; 2: len 7; hex 00000d40040110; asc @ ;; 3: len 8; hex 80000000000050b2; asc P ;; 4: len 8; hex 800000000000502a; asc P*;; 5: len 8; hex 8000000000005426; asc T&;; 6: len 8; hex 800012412c66d29c; asc A,f ;; 7: len 23; hex 8616e642e706870; asc uploadfire.com/hand.php;; 8: len 8; hex 800000000000042b; asc +;; 9: len 4; hex 474bfa2b; asc GK +;; 10: len 8; hex 8000000000004e24; asc N$;;
?*** (2) WAITING FOR THIS LOCK TO BE GRANTED: (任務2等待的鎖)
?RECORD LOCKS space id 0 page no 843102 n bits 600 index `idx_1` of table `db/tab_test` trx id 0 677833454 lock_mode X locks rec but not gap waiting
?Record lock, heap no 395 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
?0: len 8; hex 8000000000000425; asc %;; 1: len 8; hex 800012412c66d29c; asc A,f ;; 2: len 8; hex 800000000097629c; asc b ;;
?*** WE ROLL BACK TRANSACTION (1)
?(回滾了任務1,以解除死鎖)
原因分析:
當「update tab_test set state=1064,time=now() where state=1061 and time < date_sub(now(), INTERVAL 30 minute)」執行時,MySQL會使用idx_1索引,因此首先鎖定相關的索引記錄,因為idx_1是非主鍵索引,為執行該語句,MySQL還會鎖定主鍵索引。
假設「update tab_test set state=1067,time=now () where id in (9921180)」幾乎同時執行時,本語句首先鎖定主鍵索引,由於需要更新state的值,所以還需要鎖定idx_1的某些索引記錄。
這樣第一條語句鎖定了idx_1的記錄,等待主鍵索引,而第二條語句則鎖定了主鍵索引記錄,而等待idx_1的記錄,這樣死鎖就產生了。
6、解決辦法
拆分第一條sql,先查出符合條件的主鍵值,再按照主鍵更新記錄:
?select id from tab_test where state=1061 and time < date_sub(now(), INTERVAL 30 minute);
?update tab_test state=1064,time=now() where id in(......);