2013/11/06

Published 11月 06, 2013 by

ORA-00060: Deadlock Detected

ORA-00060: Deadlock Detected

關於資料庫鎖死的檢查方法
一、 資料庫鎖死的現象
程式在執行的過程中,點擊確定或保存按鈕,程式沒有回應,也沒有出現報錯。

二、鎖死的原理
當對於資料庫某個表的某一列做更新或刪除等操作,執行完畢後該條語句不提
交,另一條對於這一列資料做更新操作的語句在執行的時候就會處於等待狀態,
此時的現象是這條語句一直在執行,但一直沒有執行成功,也沒有報錯。

三、鎖死的定位方法
通過檢查資料庫表,能夠檢查出是哪一條語句被鎖死,產生鎖死的機器是哪一台。



當從alter log發現ORA-00060,代表Deadlock已經解除Detected.
Alter log:發生Deadlock,查看此檔案
Wed Nov  6 10:10:04 2013
ORA-00060: Deadlock detected. More info in file /orasys/product/admin/c5prpt/udump/c5prpt_ora_32569.trc.
Wed Nov  6 10:12:10 2013


$ more /orasys/product/admin/c5prpt/udump/c5prpt_ora_32569.trc
DEADLOCK DETECTED ( ORA-00060 )
[Transaction Deadlock]
The following deadlock is not an ORACLE error. It is a
deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:
Deadlock graph:àsession707 wait 868, session 868 wait 707形成deadlock
                       ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name          process session holds waits  process session holds waits
TX-000a0018-001d63aa        23     707     X             19     868           X
TX-000b0029-0023f388        19     868     X             23     707           X
session 707: DID 0001-0017-0AA762A9     session 868: DID 0001-0013-167D753A
session 868: DID 0001-0013-167D753A     session 707: DID 0001-0017-0AA762A9
Rows waited on:
Session 868: obj - rowid = 0000CF8E - AAAM+OABDAAAALVAAB
  (dictionary objn - 53134, file - 67, block - 725, slot - 1)
Session 707: obj - rowid = 0000CFCC - AAAM/MABDAAAASnAAF
  (dictionary objn - 53196, file - 67, block - 1191, slot - 5)
Information on the OTHER waiting sessions:
Session 868: àc5dw1這一台主機,apw3wp.exe(IIS)
  pid=19 serial=50969 audsid=160057031 user: 60/STDMAN
  O/S info: user: NETWORK?SERVICE, term: C5DW1, ospid: 3768:5276, machine: C5FAB\C5DW1
            program: w3wp.exe
  application name: w3wp.exe, hash value=2799981571
  Current SQL Statement:
  DELETE FROM QRTZ_FIRED_TRIGGERSàsession 868執行的SQL
End of information on OTHER waiting sessions.
Current SQL statement for this session:
UPDATE QRTZ_TRIGGERS SET TRIGGER_STATE = :state WHERE JOB_NAME = :jobName AND JOB_GROUP = :jobGroup AND TRIGGER_STATE = :oldStateàsession 707執行的SQL

確認是否有Deadlock:
1)用dba用戶執行以下語句
select username,lockwait,status,machine,program from v$session where sid in (select session_id from v$locked_object);

如果有輸出的結果,則說明有鎖死,且能看到鎖死的機器是哪一台。欄位說明:
Username
:鎖死語句所用的資料庫用戶;
Lockwait
:鎖死的狀態,如果有內容表示被鎖死。
Status
狀態,active表示被鎖死
Machine
鎖死語句所在的機器。
Program
產生鎖死的語句主要來自哪個應用程式。

2
)用dba用戶執行以下語句,可以查看到被鎖死的語句。
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));

鎖死的解決方法
 
一般情況下,只要將產生鎖死的語句提交就可以了,但是在實際的執行過程中。用戶可能不知道產生鎖死的語句是哪一句。可以將程式關閉並重新啟動就可以了。
 
1)查找鎖死的進程:
sqlplus "/as sysdba"
SELECT s.username,l.OBJECT_ID,l.SESSION_ID,s.SERIAL#,l.ORACLE_USERNAME,l.OS_USER_NAME,l.PROCESS 
FROM V$LOCKED_OBJECT l,V$SESSION S WHERE l.SESSION_ID=S.SID;
  2kill掉這個鎖死的進程:
  alter system kill session ‘sid,serial#’; (其中sid=l.session_id
  3)如果還不能解決:
        找尋pid,從os的下手kill掉此process(#kill -9 pid)
  其中pid是這個進程的進程號,kill掉這個Oracle進程。

##########查詢PID/SID
Oracle sid and Linux pid
Sometimes we found Oracle process that has been running too long using top command on Linux. We know it has PID. But how to know the SID of the process?
Here is the script:
Select substr(a.spid,1,9) pid, substr(b.sid,1,5) sid, substr(b.serial#,1,5) ser#, substr(b.machine,1,6) box, substr(b.username,1,10) username, substr(b.osuser,1,8) os_user, substr(b.program,1,30) program from
v$session b, v$process a where
b.paddr = a.addr and type='USER' order by spid;

參考資料: