當前位置:首頁 » 數據倉庫 » 資料庫死鎖測試
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

資料庫死鎖測試

發布時間: 2022-09-01 10:12:24

A. 深入探討如何解決資料庫中的死鎖問題

具體的解決方法如下: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.分析已經找到的,解決問題。

B. DB2資料庫發生死鎖了怎麼辦

db2 get snapshot for locks on sample
db2 get db cfg for sample
db2 update db cfg using dlchktime 10000
-查看資料庫管理器級別快照信息
db2 get snapshot for dbm
-查看資料庫級別快照信息
db2 get snapshot for database on dbname
-查看應用級別快照信息
db2 get snapshot for application agentid appl-handler
註:appl-handler可以從list applicaitions的輸出中得到
-查看錶級別快照信息
db2 get snapshot for tables on dbname
註:需要把tables快照開關設為ON才會有作用
-查看鎖快照信息
db2 get snapshot for locks on dbname

db2 get snapshot for locks on for application agentid appl-handler
-查看動態sql語句快照信息
db2 get snapshot for dynamic sql on dbname

db2 get monitor switches
db2 update monitor switches using lock on statement on
create event monitor mymonitor for deadlocks,statements write to file 'c:/temp'
set event monitor mymonitor state 1
db2evmon - path 'c:/temp'

--轉自:http://blog.csdn.NET/rodjohnsondoctor/article/details/4323514

---

第1頁:上線前的准備
第2頁:維護時的注意事項
第3頁:發生死鎖後的對策

【IT168 技術文檔】在新的資料庫應用系統上線初期,由於測試不完善或不熟悉DB2的機制,常會出現鎖等待死鎖等現象存在於我們的應用系統中,如何捕獲鎖等待或死鎖信息並解決鎖問題,是保證平穩上線必須面對的問題。目前應用系統最常使用的DB2資料庫版本有多個,有8.1,8.2,9.1還有新推出的9.5,對於不同版本的DB2資料庫提供的解決辦法不盡相同,下面對於上述問題的解決作了一個簡單說明,希望對大家有用。

首先在上線前有幾件跟鎖相關的事情需要開發設計人員一定要做好

1. 相關參數的更改

注冊表變數參數:

DB2_EVALUNCOMMITTED=on 當啟用此變數時,在可能的情況下,它將進行表或索引訪問掃描以延遲或避免行鎖定,直到知道數據記錄滿足謂詞求值為止。

DB2_SKIPDELETED=on 當啟用此變數時,在可能的情況下,它允許使用無條件地跳過已刪除的鍵或跳過已刪除的行。

DB2_SKIPINSERTED=on 當啟用此變數時,在可能的情況下,它允許跳過未落實的已插入行,就好像從未插入這些行一樣。

資料庫參數:

LOCKLIST 鎖定列表的內存量,當此參數設置為 AUTOMATIC 時,就啟用了自調整功能。這允許內存調整器根據工作負載需求變化動態地調整此參數控制的內存區大小。如果不是自動,需要設置相對大一些;DB2默認是行鎖,每個行鎖大約佔64或128個位元組(64位資料庫),計算鎖定列表內存的大小公式是: ( 每個應用程序的平均鎖定數目的估計值 * 每個鎖定所需的位元組數(128或64) * maxappls(或者max_coordagents) /4096 ) * 120%,這里只是建議公式,實際情況還要視操作系統實際的內存量來定。

MAXLOCKS 升級前鎖定列表的最大百分比,默認是22%(windows)或10%(unix),可以根據要求自行改動,計算公式是 2 * 100 / maxappls

DLCHKTIME 死鎖檢測時間間隔,默認是10000毫秒(10秒),可以根據要求自行改動,也可不動。增大此參數以降低檢查死鎖的頻率,因此增加應用程序必須等待消除死鎖的時間。 減小此參數會增大檢查死鎖的頻率,從而減少應用程序必須等待死鎖解決的時間,但是會增加資料庫管理器檢查死鎖所花的時間。

LOCKTIMEOUT 鎖等待時間,默認是 -1,也就是永遠等待,請改成固定的值,在事務處理(OLTP)環境中,可以使用 30 秒的初始啟動值。在一個只查詢的環境中,您可以從一個較高的值開始。

LOGFILSIZ 日誌文件大小,此參數定義每個主日誌文件和輔助日誌文件的大小。如果資料庫要運行大量更新、刪除或插入事務,而這將導致日誌文件很快變滿,則應增大日誌文件,了解您的並發應用程序的日誌記錄需求,來確定一個不會分配過量而浪費空間的日誌文件大小。

LOGPRIMARY 主日誌文件數,了解您的並發應用程序的日誌記錄需求,適當增大日誌文件數。

注意: 在更新參數時,需要注意有些參數在更改後需要重新啟動資料庫DB2實例才可以生效;有些參數需要斷開當前所有的應用程序,重新鏈接才能生效;有些參數可以立即生效,使用者請參考相關文檔,注意參數生效特性。

2. 應用程序設計

-程序盡量短小精悍

-程序盡量晚地訪問關鍵資源

-程序盡可能快地提交工作

-程序盡可能快地關閉游標

-建立合適索引

3. 性能測試

要根據將來實際的並發用戶數和數據量進行測試

上線之後維護時我們要做的幾件事情

1. 做好定期維護

通過使用如下命令進行維護:
-reorg表和索引定期重組
-runstats表和索引的統計信息定期更新
-rebind 程序包定期重新編譯

C. DB2 死鎖怎麼測試 具體的測試方法是什麼

你要模擬一個 DB2 的死鎖?

那麼首先, 先創建一個測試表

CREATE TABLE test_main (
id INT NOT NULL,
value VARCHAR(10),
PRIMARY KEY(id)
);

和測試數據...

開2個 DB2 的命令行窗口

會話1:
db2 => select * from test_main@

ID VALUE
----------- ----------
1 ONE
2 TWO
5 Five-5
3 THREE-5

4 條記錄已選擇。

db2 => UPDATE test_main SET value='Two-5' WHERE id=2@
DB20000I SQL 命令成功完成。

會話2:
db2 => UPDATE test_main SET value='THREE' WHERE id=3@
DB20000I SQL 命令成功完成。

會話1:
db2 => UPDATE test_main SET value='THREE-55' WHERE id=3@
由於 id=3 的行,已經被會話2修改,並鎖定,因此會話1當前進入等待狀態。

會話2:
db2 => UPDATE test_main SET value='Two-2' WHERE id=2@
由於 id=2 的行,已經被會話1修改,並鎖定,因此會話2當前進入等待狀態。

等待一段時間後

DB21034E 該命令被當作 SQL 語句來處理,因為它是無效的「命令行處理器」命令。在
SQL 處理期間,它返回:
SQL0911N 因為死鎖或超時,所以當前事務已回滾。原因碼為 "2"。 SQLSTATE=40001
db2 =>

會話1
DB20000I SQL 命令成功完成。
db2 =>
db2 => select * from test_main@

ID VALUE
----------- ----------
1 ONE
2 Two-5
5 Five-5
3 THREE-55

4 條記錄已選擇。

會話2:
db2 => select * from test_main@

ID VALUE
----------- ----------
1 ONE
2 TWO
5 Five-5
3 THREE-5

4 條記錄已選擇。

顯示會話二的更新已丟失。

D. 資料庫查詢發生死鎖

導致
死鎖
的主要原因是
SQL語句
里有for
update
導致。比如當你訪問這個表時候
有人使用了for
update進行
數據修改
,那在你那裡調試也好執行也好
都會導致無法返回結果
一直卡在那裡。

E. 如何檢測oracle資料庫死鎖

從v$locked_object中查詢select
username,lockwait,status,machine,program
from
v$session
where
sid
in
(select
session_id
from
v$locked_object)

F. 如何查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'

G. SQL資料庫總是假死或死鎖。

建議:
1、使用事件探查器,跟蹤一下SQL在死鎖之前執行了哪些SQL語句
2、多數死鎖是因為程序沒有經過嚴格的測試造成的
3、少部分原因是因為觸發器嵌套造成的,SQL有內部機制,當嵌套到一定的層級,就自動終止掉相關的進程
願早日解決問題

H. 資料庫:如何使一張表產生死鎖現象從而無法訪問

如果是sqlserver的話,給出下面示例
SELECT
*
FROM
table
WITH
(HOLDLOCK)
其他事務可以讀取表,但不能更新刪除
SELECT
*
FROM
table
WITH
(TABLOCKX)
其他事務不能讀取表,更新和刪除
如果是oracle的話,lz可以使用for
update用法
select
*
from
TTable1
for
update
鎖定表的所有行,只能讀不能寫
有問題再追問。

I. 怎樣通過程序判斷資料庫是否死鎖

一般採用超時法或事務等待圖法: (1)超時法 如果一個事務的等待時間超過規定時間,就認為發生了死鎖。這個實現簡單,但不足也很明顯。 (2)事務等待圖法 事務等待圖是一個有向圖G=(T, U),