1. 程式人生 > >模擬阻塞和死鎖及檢測

模擬阻塞和死鎖及檢測

鄒建04-5-12http://topic.csdn.net/t/20040512/01/3056773.html
--正常阻塞的例子:  
   
  --建立一個測試表  
  create   table   test(a   int)  
  go  
   
  --開啟事務,插入資料  
  begin   tran  
  insert   test(a)   values(1)  
   
  --注意沒有提交或回滾事務  
  --此時,你用你上述語句是查詢不到的,因為還沒有發生阻塞  
   
   
  --而阻塞的產生是在這個時候  
  --開啟一個新視窗,執行下面的語句  
  select   *   from   test  
   
  --因為前面那個事務沒有提交,此時,這個查詢要等待第一個處理視窗的操作完成,此時,前面視窗中的處理就阻塞了本視窗的處理,只要前面視窗提交或回滾事務,本視窗的操作就可以正常進行.   這就是正常阻塞

--而死鎖就是這種情況  
   
  設table1(A,B,C)  
  A         B         C  
  a1       b1       c1  
  a2       b2       c2  
  a3       b3       c3  
   
  table2(D,E)  
  D         E  
  d1       e1  
  d2       e2  
   
  在第一個連線中執行以下語句  
  begin   tran  
        update   table1  
        set   A='aa'  
        where   B='b2'    
        waitfor     delay   '00:00:30'  
        update   table2  
        set   D='d5'  
        where   E='e1'    
  commit   tran  
         
  在第二個連線中執行以下語句  
  begin   tran  
        update   table2  
        set   D='d5'  
        where   E='e1'    
        waitfor     delay   '00:00:10'  
        update   table1  
        set   A='aa'  
        where   B='b2'      
  commit   tran  
   
  同時執行,系統會檢測出死鎖,並中止程序 


檢測:
1.查找出SQLServer的死鎖和阻塞的源頭
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)

ifexists (select*from dbo.sysobjects where id =object_id(N'[dbo].[sp_who_lock]'andOBJECTPROPERTY(id, N'IsProcedure'=1)
dropprocedure[dbo].[sp_who_lock]
GO
/***************************************************************************
//  建立 : fengyu  郵件 : [email protected]  日期 :2004-04-30

//  修改 : 從http://www.csdn.net/develop/Read_Article.asp?id=26566學習到並改寫  
//  說明 : 檢視資料庫裡阻塞和死鎖情況
***************************************************************************/
use master
go
createprocedure sp_who_lock
as
begin
declare @spid int,@bl int,
    @intTransactionCountOnEntry     
int,
        @intRowcount             
int,
        @intCountProperties         
int,
        @intCounter             
int

    
createtable #tmp_lock_who (
    id 
intidentity(1,1),
    spid 
smallint,
    bl 
smallint)
    
    
IF @@ERROR<>0RETURN @@ERROR
    
    
insertinto #tmp_lock_who(spid,bl) select0 ,blocked
      
from (select*from sysprocesses where  blocked>0 ) a 
      
wherenotexists(select*from (select*from sysprocesses where  blocked>0 ) b 
      
where a.blocked=spid)
      
unionselect spid,blocked from sysprocesses where  blocked>0

    
IF @@ERROR<>0RETURN @@ERROR    
     
-- 找到臨時表的記錄數
select     @intCountProperties =Count(*),@intCounter =1
    
from #tmp_lock_who
    
    
IF @@ERROR<>0RETURN @@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 ASVARCHAR(10)) +'程序號,其執行的SQL語法如下'
 
else
            
select'程序號SPID:'+CAST(@spid ASVARCHAR(10))+''+'程序號SPID:'+CAST(@bl ASVARCHAR(10)) +'阻塞,其當前程序執行的SQL語法如下'
 
DBCC INPUTBUFFER (@bl )
    
end    

-- 迴圈指標下移
set @intCounter = @intCounter +1
end


droptable #tmp_lock_who

return0
end

2.檢視當前程序,或死鎖程序,並能自動殺掉死程序

/*--處理死鎖

檢視當前程序,或死鎖程序,並能自動殺掉死程序

因為是針對死的,所以如果有死鎖程序,只能檢視死鎖程序
當然,你可以通過引數控制,不管有沒有死鎖,都只檢視死鎖程序

--鄒建 2004.4--*/

/*--呼叫示例

exec p_lockinfo
--*/
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 master..sysprocesses a join (
select blocked from master..sysprocesses 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 master..sysprocesses a where blocked<>0
)a order by s1,s2

select @[email protected]@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 master..sysprocesses
set @[email protected]@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<[email protected]
begin
select @spid=程序ID,@標誌=標誌 from #t where [email protected]
insert #t1 exec('dbcc inputbuffer('[email protected]+')')
if @標誌='死鎖的程序' exec('kill '[email protected])
set @[email protected]+1
end
end
else
while @i<[email protected]
begin
select @s='dbcc inputbuffer('+cast(程序ID as varchar)+')' from #t where [email protected]
insert #t1 exec(@s)
set @[email protected]+1
end
select a.*,程序的SQL語句=b.EventInfo
from #t a join #t1 b on a.id=b.id
end
go

相關推薦

模擬阻塞檢測

鄒建04-5-12http://topic.csdn.net/t/20040512/01/3056773.html--正常阻塞的例子:         --建立一個測試表     create   table   test(a   int)     go    

譯碼阻塞的等待資源

block waitresource 等待資源 譯碼阻塞和死鎖的等待資源常用等待資源介紹以下表格列出了常用等待資源的格式和意義。ResourceFormatExampleTableDatabaseID:ObjectID:IndexIDTAB: 5:261575970:1 In

第十六章——處理阻塞(2)——偵測阻塞阻塞查詢

前言: 如果一個事務正在等待一些給其他事務鎖定的資源。這個事務就被成為“被阻塞的事務”。反過來,引起阻塞的事務,也就是鎖定資源並造成其他事務等待的事務叫做“正在阻塞的事務”。 長時間執行事務會阻塞其他事務和查詢,使他們等待長時間。在繁重的系統中,很多時候我們會遇到阻塞問題,

SQL SERVER 檢視資料庫裡阻塞情況

  if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'[dbo].[sp_who_lock]')   and   OBJECTPROPERTY(id,   N'I

處理阻塞(2)——偵測阻塞阻塞查詢

前言: 如果一個事務正在等待一些給其他事務鎖定的資源。這個事務就被成為“被阻塞的事務”。反過來,引起阻塞的事務,也就是鎖定資源並造成其他事務等待的事務叫做“正在阻塞的事務”。 長時間執行事務會阻塞其他事務和查詢,使他們等待長時間。在繁重的系統中,很多時候我們會遇到阻塞問題,如果一個事務因為阻塞未完成。會造成

模擬案例分析

草稿箱二十篇隨筆沒有釋出,零零散散記錄著曾經以為還不錯的知識點。稍作整理髮布,方便以後檢視。2015-11-26 18:04 整理,未釋出 1、模擬死鎖 首先建立測試資料,然後開啟必要的跟蹤,最後執行兩個語句模擬死鎖。 1.1、建立測試資料 建立測試資料表、建立索引 create table

什麼是的必要條件解決方法

 一、要點提示  二、內容簡介   在計算機系統中有很多一次只能由一個程序使用的資源,如印表機,磁帶機,一個檔案的I節點等。在多道程式設計環境中,若干程序往往要共享這類資源,而且一個程序所需要的資源不止一個。這樣,就會出現若干程序競爭有限資源,又推進順序不當,從而構成無限期迴圈等待的局面。

作業系統第三章之檢測

死鎖的檢測與解除 *當系統為程序分配資源時,若未採取任何限制性措施,則系統必須提供檢測和解除死鎖的手段,為此係統必須: 1.儲存有關資源的請求和分配資訊; 2.提供一種演算法,以利用這些資訊來檢測系統是否已進入死鎖狀態。 資源分配圖 系統死鎖可利用資源分配圖來描

什麼是的必要條件解決方法【轉】

一、要點提示 (1) 掌握死鎖的概念和產生死鎖的根本原因。 (2) 理解產生死鎖的必要條件–以下四個條件同時具備:互斥條件、不可搶佔條件、佔有且申請條件、迴圈等待條件。 (3) 記住解決死鎖的一般方法,掌握死鎖的預防和死鎖的避免二者的基本思想。 (4) 掌握死鎖

mysql行檢測

行鎖顧名思義,就是針對單行資料加鎖,在mysql中,鎖的實現是由引擎層實現的,MyISAM引擎就不支援行鎖 不支援行鎖就意味著併發控制只能使用表鎖,也就是說同一時間,在這個表上只能有一個更新在執行,這就會 影響到業務的併發度。InnoDB是支援行鎖的,這也是MyISAM被InnoDB替代的重要原因之一。

檢測

在線 才有 inf 發現 情況 接受 等待時間 正常 lock 如圖所示,事務A在等待事務B釋放id=2的鎖,事務B在等待事務A釋放id=1的鎖 這種情況就是死鎖 發生死鎖有兩種方法解決 1.直接進入等待,直到超時。這個超時時間可以通過參數innodb_lock_

【SQL Server學習筆記】事務、鎖定、阻塞

body sqlserve distrib reset reads cli ast function pre http://blog.csdn.net/sqlserverdiscovery/article/details/7712068 Column nameData

進程解決辦法

優先級 pad lec net 互斥 全序 將在 結構 log 操作系統 2009-09-24 16:48:58 閱讀767 評論1 字號:大中小 訂閱 一、要點提示 (1) 掌握死鎖的概念和產生死鎖的根本原因。 (2) 理解產生死鎖的必要條件--以下四個條件同時具

樂觀悲觀CAS實現

通信 我認 行鎖 一起 flush expected ges 同步鎖 優化 樂觀鎖與悲觀鎖   悲觀鎖:總是假設最壞的情況,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖。傳統的關系型數據庫裏邊就用到了很多這種

postgresql查看解決方法

sel can from 數據 post sta 進程 wait nbsp 檢索出死鎖進程的ID   SELECT * FROM pg_stat_activity WHERE datname=‘數據庫名‘ and waiting=‘t‘;  找到對用的pid列的值 

MySQL技術內幕 InnoDB儲存引擎:阻塞升級

1、堵塞 因為不同鎖之間的相容性關係,在有些時刻一個事務中的鎖需要等待另外一個事務中的鎖釋放它所佔用的資源,這就是堵塞。 引數innodb_lock_wait_timeout用來控制等待的時間,預設50秒,是可以動態設定的。 引數innodb_rollback_on

jstack簡單使用,定位迴圈、執行緒阻塞等問題

當我們執行java程式時,發現程式不動,但又不知道是哪裡出問題時,可以使用JDK自帶的jstack工具去定位; 廢話不說,直接上例子吧,在window平臺上的; 一、死迴圈 package software.architect.OtherAnalyzer.main; public

《現代作業系統》閱讀筆記——排程

排程 何時需要排程 建立新的程序時 執行父程序還是子程序 程序退出時 程序阻塞時 I/O中斷結束後 排程演算法目標 給所有程序公平的CPU份

#Java中活有什麼區別?如何避免

Java中活鎖和死鎖是指什麼,你知道他們之間的區別嗎,下面我們可以來討論一下: 如果有想要學習java的小夥伴,可來我們的java學習扣裙哦:72340,3928裡面贈送java系列教學視訊和資料!小編也是從事了6年java開發的全棧工程師,歡迎初學者和想要進階

Python執行緒,以及多執行緒帶來的資料錯亂的解決方法

摘至本人有道雲筆記《Python執行緒》 1.python多執行緒的建立 在Python中,同樣可以實現多執行緒,有兩個標準模組thread和threading,不過我們主要使用更高階的threading模組 threading模組提供的類:      Thread,