現場環境是Oracle的數據庫集羣,部署了xxx.xxx.xxx.102,xxx.xxx.xxx.104,xxx.xxx.xxx.106,xxx.xxx.xxx.108,xxx.xxx.xxx.109共五個節點,每次出現死鎖的時候,就要登錄每個節點去查詢死鎖,然後逐條的去解鎖。
1、查詢集羣下,所有節點的死鎖:
--Oracle數據庫查詢死鎖,
select sess.sid,
sess.serial#,
lo.oracle_username,
lo.os_user_name,
ao.object_name,
'alter system kill session '''||sess.sid||','||sess.serial#||'''; ' as a,
lo.locked_mode
-- gv$locked_object gv$session 這兩個表加上g,查詢的是所有節點下的死鎖
from gv$locked_object lo, dba_objects ao, gv$session sess
where ao.object_id = lo.object_id
and lo.session_id = sess.sid
--指定表名
and ao.object_name = 'TA_SP_APPROVE_INFO'
--指定用戶名
and lo.oracle_username = 'HNCS_APPROVE'
注意:
1、'alter system kill session '''||sess.sid||','||sess.serial#||'''; ' as a, 這一句是把查詢到的死鎖用解除死鎖的語句拼接起來,查詢出來之後,我們就只要複製這一列,執行即可解除死鎖;
2、from gv$locked_object lo, dba_objects ao, gv$session sess from後面的gv$locked_object和gv$session中的g,表示的查詢全局(也就是集羣下所有的節點);這樣的話,當我們把第一點說的列複製出來,解除死鎖的時候,很多解除死鎖的語句都會報:丟失或無效的會話ID。因爲很多的死鎖不是在本節點,所以在本節點無法解除死鎖。
3、可以指定用戶名和表名作爲查詢條件,只查詢對應的死鎖。
查詢得到的結果示例如下:
alter system kill session '7580,64754';
alter system kill session '7580,59542';
2、查詢集羣下,當前節點的死鎖:
--Oracle數據庫查詢死鎖,
select sess.sid,
sess.serial#,
lo.oracle_username,
lo.os_user_name,
ao.object_name,
'alter system kill session '''||sess.sid||','||sess.serial#||'''; ' as a,
lo.locked_mode
-- v$locked_object v$session 這兩個表沒有加上g,查詢的是當前節點下的死鎖
from v$locked_object lo, dba_objects ao, v$session sess
where ao.object_id = lo.object_id
and lo.session_id = sess.sid
--指定表名
and ao.object_name = 'TA_SP_APPROVE_INFO'
--指定用戶名
and lo.oracle_username = 'HNCS_APPROVE'
注意:
from v$locked_object lo, dba_objects ao, v$session sess 這一句中的 v$locked_object 和 v$session ,他們的$前面只有v,並沒有g,說明只是查詢當前節點。這樣查詢出來的死鎖基本上都是在本節點上的,直接複製就能解除死鎖。所以,如果有多個節點,就要在每個節點上都執行同樣的操作,才能解除所有的死鎖。