資料庫死鎖查詢
Ⅰ 如何查mysql死鎖進程
查詢死鎖進程
採用如下存儲過程來查詢數據中當前造成死鎖的進程。
drop procere sp_who_lock
go
CREATE procere sp_who_lock
as
begin
declare @spid int
declare @blk int
declare @count int
declare @index int
declare @lock tinyint
set @lock=0
create table #temp_who_lock
(
id int identity(1,1),
spid int,
blk int
)
if @@error<>0 return @@error
insert into #temp_who_lock(spid,blk)
select 0 ,blocked
from (select * from master..sysprocesses where blocked>0)a
where not exists(select * from master..sysprocesses where a.blocked =spid and blocked>0)
union select spid,blocked from master..sysprocesses where blocked>0
if @@error<>0 return @@error
select @count=count(*),@index=1 from #temp_who_lock
if @@error<>0 return @@error
if @count=0
begin
select '沒有阻塞和死鎖信息'
return 0
end
while @index<<A href="mailto:=@count">=@count
begin
if exists(select 1 from #temp_who_lock a where id>@index and exists(select 1 from #temp_who_lock where id<<A href="mailto:=@index">=@index and a.blk=spid))
begin
set @lock=1
select @spid=spid,@blk=blk from #temp_who_lock where id=@index
select '引起資料庫死鎖的是: '+ CAST(@spid AS VARCHAR(10)) + '進程號,其執行的SQL語法如下'
select @spid, @blk
dbcc inputbuffer(@spid)
dbcc inputbuffer(@blk)
end
set @index=@index+1
end
if @lock=0
begin
set @index=1
while @index<<A href="mailto:=@count">=@count
begin
select @spid=spid,@blk=blk from #temp_who_lock where id=@index
if @spid=0
select '引起阻塞的是:'+cast(@blk as varchar(10))+ '進程號,其執行的SQL語法如下'
else
select '進程號SPID:'+ CAST(@spid AS VARCHAR(10))+ '被' + '進程號SPID:'+ CAST(@blk AS VARCHAR(10)) +'阻塞,其當前進程執行的SQL語法如下'
dbcc inputbuffer(@spid)
dbcc inputbuffer(@blk)
set @index=@index+1
end
end
drop table #temp_who_lock
return 0
end
GO
--執行該存儲過程
exec sp_who_lock
補充:
一、產生死鎖的原因
在SQL Server中,阻塞更多的是產生於實現並發之間的隔離性。為了使得並發連接所做的操作之間的影響到達某一期望值而對資源人為的進行加鎖(鎖本質其實可以看作是一個標志位)。當一個連接對特定的資源進行操作時,另一個連接同時對同樣的資源進行操作就會被阻塞,阻塞是死鎖產生的必要條件。
二、如何避免死鎖
1.使用事務時,盡量縮短事務的邏輯處理過程,及早提交或回滾事務;
2.設置死鎖超時參數為合理范圍,如:3分鍾-10分種;超過時間,自動放棄本次操作,避免進程懸掛;
3.優化程序,檢查並避免死鎖現象出現;
4.對所有的腳本和SP都要仔細測試,在正是版本之前;
5.所有的SP都要有錯誤處理(通過@error);
6.一般不要修改SQL SERVER事務的默認級別。不推薦強行加鎖。
三、處理死鎖
1、最簡單的處理死鎖的方法就是重啟服務。
2、根據指定的死鎖進程ID進行處理
根據第二步查詢到的死鎖進行,大致分析造成死鎖的原因,並通過如下語句釋放該死鎖進程
kill pid --pid為查詢出來的死鎖進程號
3、通過存儲過程殺掉某個庫下面的所有死鎖進程和鎖
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_killspid]') and OBJECTPROPERTY(id, N'IsProcere') = 1)
drop procere [dbo].[sp_killspid]
GO
create proc sp_killspid
@dbname varchar(200) --要關閉進程的資料庫名
as
declare @sql nvarchar(500)
declare @spid nvarchar(20)
declare #tb cursor for
select spid=cast(spid as varchar(20)) from master..sysprocesses where dbid=db_id(@dbname)
open #tb
fetch next from #tb into @spid
while @@fetch_status=0
begin
exec('kill '+@spid)
fetch next from #tb into @spid
end
close #tb
deallocate #tb
go
--使用方法,「db_name」為處理的資料庫名稱
exec sp_killspid 'db_name'
Ⅱ 查看sqlserver資料庫是否有死鎖信息
死鎖檢測
use master
Select * from sysprocesses where blocked<>0
--找到SPID
exec sp_lock
--根據SPID找到OBJID
select object_name(85575343)
--根據OBJID找到表名
Ⅲ oracle資料庫死鎖怎麼解決
Oracle資料庫出現死鎖的時候可以按照以下處理步驟加以解決:
第一步:嘗試在sqlplus中通過sql命令進行刪除,如果能夠刪除成功,則萬事大吉!但通常情況下,出現死鎖時,想通過命令行或者通過Oracle的管理工具刪除有死鎖的session,oracle只會將該session標記為killed,但無法清除掉,往往需要通過第二步在操作系統層級進行刪除!
.2.0.1.0
Connectedasquik
SQL>selectxisn,object_id,session_id,locked_modefromv$locked_object;--查死鎖的對象,獲取其SESSION_ID
XIDUSNOBJECT_IDSESSION_IDLOCKED_MODE
-----------------------------------------
1030724293
1030649293
SQL>selectusername,sid,serial#fromv$sessionwheresid=29;--根據上步獲取到的sid查看其serial#號
USERNAMESIDSERIAL#
--------------------------------------------------
QUIK2957107
SQL>altersystemkillsession'29,57107';--刪除進程,如已經刪除過,則會報ora-00031的錯誤;否則oracle會將該session標記為killed狀態,等待一段時間看能否會自動消失,如長時間消失不掉,則需要做後續步驟
altersystemkillsession'29,57107'
ORA-00031:sessionmarkedforkill
SQL>selectpro.spidfromv$sessionses,v$processprowhereses.sid=29andses.paddr=pro.addr;--查看spid號,以便在操作系統中根據該進程號刪除進程
SPID
------------
2273286
第二步:進入操作系統進行刪除進程,本示例的操作系統是IBM aix。
login:root--錄入用戶名
root'sPassword:--錄入密碼
*******************************************************************************
**
**
*WelcometoAIXVersion5.3!*
**
**
*PleaseseetheREADMEfilein/usr/lpp/bosforinformationpertinentto*
*.*
**
**
*******************************************************************************
Lastunsuccessfullogin:FriApr2314:42:57BEIDT2010on/dev/pts/1from10.73
.52.254
Lastlogin:FriApr2315:27:50BEIDT2010on/dev/pts/2from10.73.52.254
#ps-ef|grep2273286--查看進程詳情
root22898642494636017:07:15pts/10:00grep2273286
oracle22732861014:38:24-0:21oracleQUIK(LOCAL=NO)
#kill-92273286--刪除進程,小心操作,別寫錯進程號,如果oracle的關鍵進程被刪,資料庫會崩潰的!
#ps-ef|grep2273286--再次查看
root22898642494636017:07:15pts/10:00grep2273286
ForWindows,attheDOSPrompt:orakillsidspid
ForUNIXatthecommandline>kill–9spid
Ⅳ 如何查看MySQL資料庫的死鎖信息
1. 使用終端或命令提示符登錄到MySQL,輸入命令:mysql -h xxxx.xxx.xxx -P 3306 -u username -p
解釋:xxxx.xxx.xxx是資料庫IP地址,username是資料庫用戶名,輸入命令後,會讓你輸入username對應的密碼,就可以登錄了
4. 如何分析日誌,定位死鎖原因
看3裡面的圖,紫色劃線部分
分析:
事務1,等待
RECORD LOCKS space id 553 page no 376 n bits 368 index `index_user_id` of table `tbj`.`score_user`,這個位置的X鎖
事務2,持有
RECORD LOCKS space id 553 page no 376 n bits 368 index `index_user_id` of table `tbj`.`score_user`這個地方的S鎖
事務2,等待這個地方的X鎖
理論上這個事務2是可以提交的不會,死鎖,但是這個事務日誌只列印最後一部分死鎖,信息,這裡面隱含的條件是,事務1也持有
RECORD LOCKS space id 553 page no 376 n bits 368 index `index_user_id` of table `tbj`.`score_user`這個地方的S鎖,這樣,事務2不能加X鎖,同時事務1也不能加X鎖,產生死鎖。
Ⅳ 資料庫查詢發生死鎖
導致
死鎖
的主要原因是
SQL語句
里有for
update
導致。比如當你訪問這個表時候
有人使用了for
update進行
數據修改
,那在你那裡調試也好執行也好
都會導致無法返回結果
一直卡在那裡。
Ⅵ 資料庫死鎖處理方法
mysql資料庫死鎖解決方法如下:
1、對於按鈕等控制項,點擊後使其立刻失效,不讓用戶重復點擊,避免對同時對同一條記錄操作。
2、使用樂觀鎖進行控制。樂觀鎖大多是基於數據版本(Version)記錄機制實現。即為數據增加一個版本標識,在基於資料庫表的版本解決方案中,一般是 通過為資料庫表增加一個「version」欄位來實現。讀取出數據時,將此版本號一同讀出,之後更新時,對此版本號加一。此時,將提交數據的版本數據與數 據庫表對應記錄的當前版本信息進行比對,如果提交的數據版本號大於資料庫表當前版本號,則予以更新,否則認為是過期數據。樂觀鎖機制避免了長事務中的數據 庫加鎖開銷(用戶A和用戶B操作過程中,都沒有對資料庫數據加鎖),大大提升了大並發量下的系統整體性能表現。Hibernate 在其數據訪問引擎中內置了樂觀鎖實現。需要注意的是,由於樂觀鎖機制是在系統中實現,來自外部系統的用戶更新操作不受系統的控制,因此可能會造 成臟數據被更新到資料庫中。
Ⅶ 資料庫查詢時可能造成死鎖嗎
查詢不會產生死鎖。
更新有可能會造成死鎖。死鎖不需要干預的,系統會定時清理死鎖並在alert里記錄。估計你感興趣的應該是其他的鎖比如行鎖、表鎖或者是鎖等待之類的。