一、數(shù)據(jù)庫(kù)死鎖的現(xiàn)象

我們提供的服務(wù)有:成都做網(wǎng)站、成都網(wǎng)站制作、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、疏勒ssl等。為數(shù)千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的疏勒網(wǎng)站制作公司
程序在執(zhí)行的過(guò)程中,點(diǎn)擊確定或保存按鈕,程序沒(méi)有響應(yīng),也沒(méi)有出現(xiàn)報(bào)錯(cuò)。
二、oracle死鎖的原理
當(dāng)對(duì)于數(shù)據(jù)庫(kù)某個(gè)表的某一列做更新或刪除等操作,執(zhí)行完畢后該條語(yǔ)句不提交,另一條對(duì)于這一列數(shù)據(jù)做更新操作的語(yǔ)句在執(zhí)行的時(shí)候就會(huì)處于等待狀態(tài),此時(shí)的現(xiàn)象是這條語(yǔ)句一直在執(zhí)行,但一直沒(méi)有執(zhí)行成功,也沒(méi)有報(bào)錯(cuò)。
三、oracle死鎖的定位方法
通過(guò)檢查數(shù)據(jù)庫(kù)表,能夠檢查出是哪一條語(yǔ)句被死鎖,產(chǎn)生死鎖的機(jī)器是哪一臺(tái)。
1)用dba用戶執(zhí)行以下語(yǔ)句
select username,lockwait,status,machine,program from v$session where sid in (select session_id from v$locked_object) 如果有輸出的結(jié)果,則說(shuō)明有死鎖,且能看到死鎖的機(jī)器是哪一臺(tái)。字段說(shuō)明:
Username:死鎖語(yǔ)句所用的數(shù)據(jù)庫(kù)用戶;
Lockwait:死鎖的狀態(tài),如果有內(nèi)容表示被死鎖。
Status: 狀態(tài),active表示被死鎖
Machine: 死鎖語(yǔ)句所在的機(jī)器。
Program: 產(chǎn)生死鎖的語(yǔ)句主要來(lái)自哪個(gè)應(yīng)用程序。
2)用dba用戶執(zhí)行以下語(yǔ)句,可以查看到被死鎖的語(yǔ)句。
Oracle數(shù)據(jù)庫(kù)出現(xiàn)死鎖的時(shí)候可以按照以下處理步驟加以解決:
第一步:嘗試在sqlplus中通過(guò)sql命令進(jìn)行刪除,如果能夠刪除成功,則萬(wàn)事大吉!但通常情況下,出現(xiàn)死鎖時(shí),想通過(guò)命令行或者通過(guò)Oracle的管理工具刪除有死鎖的session,oracle只會(huì)將該session標(biāo)記為killed,但無(wú)法清除掉,往往需要通過(guò)第二步在操作系統(tǒng)層級(jí)進(jìn)行刪除!
Connected?to?Oracle9i?Enterprise?Edition?Release?9.2.0.1.0?
Connected?as?quik
SQL?select?xidusn,?object_id,?session_id,?locked_mode?from?v$locked_object;?--查死鎖的對(duì)象,獲取其SESSION_ID
XIDUSN?OBJECT_ID?SESSION_ID?LOCKED_MODE
----------?----------?----------?-----------
10?30724?29?3
10?30649?29?3
SQL?select?username,sid,serial#?from?v$session?where?sid=29;?--根據(jù)上步獲取到的sid查看其serial#號(hào)
USERNAME?SID?SERIAL#
------------------------------?----------?----------
QUIK?29?57107
SQL?alter?system?kill?session?'29,57107';?--刪除進(jìn)程,如已經(jīng)刪除過(guò),則會(huì)報(bào)ora-00031的錯(cuò)誤;否則oracle會(huì)將該session標(biāo)記為killed狀態(tài),等待一段時(shí)間看能否會(huì)自動(dòng)消失,如長(zhǎng)時(shí)間消失不掉,則需要做后續(xù)步驟
alter?system?kill?session?'29,57107'
ORA-00031:?session?marked?for?kill
SQL?select?pro.spid?from?v$session?ses,v$process?pro?where?ses.sid=29?and?ses.paddr=pro.addr;?--查看spid號(hào),以便在操作系統(tǒng)中根據(jù)該進(jìn)程號(hào)刪除進(jìn)程
SPID
------------
2273286
第二步:進(jìn)入操作系統(tǒng)進(jìn)行刪除進(jìn)程,本示例的操作系統(tǒng)是IBM aix。
login:?root?--錄入用戶名
root's?Password:?--錄入密碼
*******************************************************************************
*?*
*?*
*?Welcome?to?AIX?Version?5.3!?*
*?*
*?*
*?Please?see?the?README?file?in?/usr/lpp/bos?for?information?pertinent?to?*
*?this?release?of?the?AIX?Operating?System.?*
*?*
*?*
*******************************************************************************
Last?unsuccessful?login:?Fri?Apr?23?14:42:57?BEIDT?2010?on?/dev/pts/1?from?10.73
.52.254
Last?login:?Fri?Apr?23?15:27:50?BEIDT?2010?on?/dev/pts/2?from?10.73.52.254
#?ps?-ef|grep?2273286?--查看進(jìn)程詳情
root?2289864?2494636?0?17:07:15?pts/1?0:00?grep?2273286
oracle?2273286?1?0?14:38:24?-?0:21?oracleQUIK?(LOCAL=NO)
#?kill?-9?2273286?--刪除進(jìn)程,小心操作,別寫錯(cuò)進(jìn)程號(hào),如果oracle的關(guān)鍵進(jìn)程被刪,數(shù)據(jù)庫(kù)會(huì)崩潰的!
#?ps?-ef|grep?2273286?--再次查看
root?2289864?2494636?0?17:07:15?pts/1?0:00?grep?2273286
For?Windows,?at?the?DOS?Prompt:?orakill?sid?spid
For?UNIX?at?the?command?line?kill?–9?spid
你這里應(yīng)該存在兩個(gè)代碼對(duì)兩個(gè)表都有操作的過(guò)程,其中的一個(gè)表從你提供的日志上看應(yīng)該是t_user。
session 530 對(duì)應(yīng)的程序中肯定是 先執(zhí)行了類似于:SELECT * FROM TABLE1 FOR UPDATE,然后,在這個(gè)語(yǔ)句后面,執(zhí)行delete from t_user where ID=:1
語(yǔ)句
而你的Session 527則很有可能是執(zhí)行了類似于SELECT * FROM t_user FOR UPDATE, 然后,在這個(gè)語(yǔ)句之后,執(zhí)行對(duì)TABLE1的相關(guān)修改工作,從而造成表的死鎖問(wèn)題。
具體的需要根據(jù)應(yīng)用來(lái)查詢,你可以看看相關(guān)的日志內(nèi)容。
首先你要知道表鎖住了是不是正常鎖?因?yàn)槿魏蜠ML語(yǔ)句都會(huì)對(duì)表加鎖。
你要先查一下是那個(gè)會(huì)話那個(gè)sql鎖住了表,有可能這是正常業(yè)務(wù)需求,不建議隨便KILL
session,如果這個(gè)鎖表是正常業(yè)務(wù)你把session
kill掉了會(huì)影響業(yè)務(wù)的。
建議先查原因再做決定。
(1)鎖表查詢的代碼有以下的形式:
select
count(*)
from
v$locked_object;
select
*
from
v$locked_object;
(2)查看哪個(gè)表被鎖
select
b.owner,b.object_name,a.session_id,a.locked_mode
from
v$locked_object
a,dba_objects
b
where
b.object_id
=
a.object_id;
(3)查看是哪個(gè)session引起的
select
b.username,b.sid,b.serial#,logon_time
from
v$locked_object
a,v$session
b
where
a.session_id
=
b.sid
order
by
b.logon_time;
(4)查看是哪個(gè)sql引起的
select
b.username,b.sid,b.serial#,c.*
from
v$locked_object
a,v$session
b,v$sql
c
where
a.session_id
=
b.sid
and
b.SQL_ID
=
c.sql_id
and
c.sql_id
=
''
order
by
b.logon_time;
(5)殺掉對(duì)應(yīng)進(jìn)程
執(zhí)行命令:alter
system
kill
session'1025,41';
其中1025為sid,41為serial#.
樓主您好
所謂的鎖等待:就是一個(gè)事務(wù)a對(duì)一個(gè)數(shù)據(jù)表進(jìn)行ddl或是dml操作時(shí),系統(tǒng)就會(huì)對(duì)該表加上表級(jí)的排它鎖,此時(shí)其他的事務(wù)對(duì)該表進(jìn)行操作的時(shí)候會(huì)等待a提交或是回滾后,才可以繼續(xù)b的操作
所謂的死鎖:當(dāng)兩個(gè)或多個(gè)用戶相互等待鎖定的數(shù)據(jù)時(shí)就會(huì)發(fā)生死鎖,這時(shí)這些用戶被卡在不能繼續(xù)處理業(yè)務(wù),oracle可以自動(dòng)檢測(cè)死鎖并解決他們,通過(guò)回滾一個(gè)死鎖中的語(yǔ)句,釋放鎖定的數(shù)據(jù),回滾的話會(huì)遇到ora-00060
deadlock detected while waiting for resource
模擬鎖等待:
兩個(gè)事務(wù)a和b,分別創(chuàng)建t1,t2,并且初始化一條數(shù)據(jù),
a 更改t1的數(shù)據(jù),此時(shí)并不提交,這時(shí)候b更改相同的一列,此時(shí)b一直處于等待的狀態(tài)
我們可以查詢鎖等待的內(nèi)容:
wait_lock.sql
select
(select username from v$session where sid = a.sid) username,
a.sid,
(select serial# from v$session where sid = a.sid) serial#,
a.type,
a.id1,
a.id2,
a.lmode,
a.request,
a.block,
b.sid blocking_sid
from v$lock a,
( select * from v$lock
where request 0
and type 'MR'
) b
where a.id1 = b.id1(+)
and a.id2 = b.id2(+)
and a.lmode 0
and a.type 'MR'
order by username,a.sid,serial#,a.type
此時(shí)可以查詢到鎖等待的現(xiàn)象,最后一列不為空的就是等待的事件
此時(shí)我們可以跟a用戶提示讓其提交事務(wù)或是回滾,也可以直接殺死
alter system kill session 'sid,serial#';
保持現(xiàn)狀不動(dòng),在a事務(wù)更改t2表此時(shí)在a事務(wù)會(huì)產(chǎn)生
SQL update t1 set id=1000 where id=1;
update t1 set id=1000 where id=1
*
第 1 行出現(xiàn)錯(cuò)誤:
ORA-00060: 等待資源時(shí)檢測(cè)到死鎖
此時(shí)oracle已經(jīng)幫我解決了這個(gè)死鎖問(wèn)題
死鎖的產(chǎn)生需要四個(gè)必須的條件:
1 ,mutual execution(互斥)資源不能被共享,只能由一個(gè)進(jìn)程使用
2,hold and wait(請(qǐng)求并持續(xù))已經(jīng)得到資源的進(jìn)程可以再次申請(qǐng)新的資源
3,no pre-emption(不可剝奪)已經(jīng)分配的資源不能被相應(yīng)的進(jìn)程強(qiáng)制剝奪
4,circular wait(循環(huán)等待條件)系統(tǒng)中若干進(jìn)程組成環(huán)路,該環(huán)路中的每個(gè)進(jìn)程都在等待相鄰進(jìn)程正占用的資源
定位死鎖:
系統(tǒng)級(jí)別的定位
Select username,lockwait,status,machine,program from v$session where sid in (select session_id from v$locked_object)
Username死鎖的用戶,lockwait死鎖的狀態(tài),status中active表示死鎖,machine死鎖所在的機(jī)器,program死鎖來(lái)自于那個(gè)程序
語(yǔ)句級(jí)別的定位
Select sql_text from v$sql where hash_value in (select
sql_hash_value from v$session where sid in (select session_id from
v$locked_object));
進(jìn)程級(jí)別的定位
Select s.username,l.object_id,l.session_id,s.serial#,l.oracle_usrename,l.os_user_name,l.process from v$locked_object l,v$session s where l.session_id=s.sid;
處理死鎖的一般策略
1,鴕鳥算法忽略該問(wèn)題
2,定位死鎖并且恢復(fù)
3,仔細(xì)對(duì)資源進(jìn)行動(dòng)態(tài)分配,避免死鎖
4,破壞死鎖中的一個(gè)條件
如果oracle解決不了的死鎖,我們需要定位到進(jìn)程級(jí)別,找到對(duì)應(yīng)的sid和serial#
alter system kill 'sid,serail#'
失敗的話,找到對(duì)應(yīng)的進(jìn)程強(qiáng)制關(guān)閉
Select p.spid from v$session s, v$process p where s.sid=xx and s.paddr=p.addr
ps -ef | grep spid
kill -9 xx
查詢oracle的死鎖
lock.sql
SELECT bs.username "Blocking User", bs.username "DB User",
ws.username "Waiting User", bs.SID "SID", ws.SID "WSID",
bs.serial# "Serial#", bs.sql_address "address",
bs.sql_hash_value "Sql hash", bs.program "Blocking App",
ws.program "Waiting App", bs.machine "Blocking Machine",
ws.machine "Waiting Machine", bs.osuser "Blocking OS User",
ws.osuser "Waiting OS User", bs.serial# "Serial#",
ws.serial# "WSerial#",
DECODE (wk.TYPE,
'MR', 'Media Recovery',
'RT', 'Redo Thread',
'UN', 'USER Name',
'TX', 'Transaction',
'TM', 'DML',
'UL', 'PL/SQL USER LOCK',
'DX', 'Distributed Xaction',
'CF', 'Control FILE',
'IS', 'Instance State',
'FS', 'FILE SET',
'IR', 'Instance Recovery',
'ST', 'Disk SPACE Transaction',
'TS', 'Temp Segment',
'IV', 'Library Cache Invalidation',
'LS', 'LOG START OR Switch',
'RW', 'ROW Wait',
'SQ', 'Sequence Number',
'TE', 'Extend TABLE',
'TT', 'Temp TABLE',
wk.TYPE
) lock_type,
DECODE (hk.lmode,
0, 'None',
1, 'NULL',
2, 'ROW-S (SS)',
3, 'ROW-X (SX)',
4, 'SHARE',
5, 'S/ROW-X (SSX)',
6, 'EXCLUSIVE',
TO_CHAR (hk.lmode)
) mode_held,
DECODE (wk.request,
0, 'None',
1, 'NULL',
2, 'ROW-S (SS)',
3, 'ROW-X (SX)',
4, 'SHARE',
5, 'S/ROW-X (SSX)',
6, 'EXCLUSIVE',
TO_CHAR (wk.request)
) mode_requested,
TO_CHAR (hk.id1) lock_id1, TO_CHAR (hk.id2) lock_id2,
DECODE
(hk.BLOCK,
0, 'NOT Blocking', /**//* Not blocking any other processes */
1, 'Blocking', /**//* This lock blocks other processes */
2, 'Global', /**//* This lock is global, so we can't tell */
TO_CHAR (hk.BLOCK)
) blocking_others
FROM v$lock hk, v$session bs, v$lock wk, v$session ws
WHERE hk.BLOCK = 1
AND hk.lmode != 0
AND hk.lmode != 1
AND wk.request != 0
AND wk.TYPE(+) = hk.TYPE
AND wk.id1(+) = hk.id1
AND wk.id2(+) = hk.id2
AND hk.SID = bs.SID(+)
AND wk.SID = ws.SID(+)
AND (bs.username IS NOT NULL)
AND (bs.username 'SYSTEM')
AND (bs.username 'SYS')
ORDER BY 1;
這些語(yǔ)句的執(zhí)行最好是在plsql或是sqldeveloper如果是直接在數(shù)據(jù)庫(kù)里面執(zhí)行的需要格式化表,否則會(huì)很讓你眼花的。
文章題目:oracle死鎖怎么用 查看oracle死鎖
文章路徑:http://chinadenli.net/article22/hpiijc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、營(yíng)銷型網(wǎng)站建設(shè)、手機(jī)網(wǎng)站建設(shè)、定制開發(fā)、品牌網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)