Oracle 編譯儲存過程卡死解決方法

hsfang發表於2019-04-22

起因

事情是這麼發生的:當天網路不好,一個簡單的查詢語句都會卡一下,在完成一個儲存過程之後點選編譯,plsql就卡住了。在等待了一段時間後,plsql還是沒有響應,我以為是網路太卡導致,就直接結束了plsql的程式,準備重新登陸(現在看這麼做還是有待商榷的)。等到我再次登陸編譯後,plsql就再次卡死,之後又嘗試了好幾次,每次都是一編譯就卡死。

解決過程

既然這個問題已經可以進行復現,並且同一個資料庫另一個使用者登陸正常,就可以基本排除是網路波動造成。於是首先判斷是有鎖,於是使用了

SELECT l.session_id sid,  
       s.serial#,  
       l.locked_mode,  
       l.oracle_username,  
       l.os_user_name, 
       s.machine,  
       s.terminal,  
       o.object_name,  
       s.logon_time,  
       p.SPID  
  FROM v$locked_object l, all_objects o, v$session s,v$process p  
 WHERE l.object_id = o.object_id  
   AND l.session_id = s.sid  
   AND s.paddr = p.addr  
 ORDER BY sid, s.serial#;  
複製程式碼

進行查詢,但是卻沒有查詢到任何記錄。 接著利用

select * from dba_ddl_locks
複製程式碼

進行查詢,若是隻是想查詢特定物件,可以加where name='XXX'進行篩選,但是這裡我是想看一下到底多少資源在鎖,所以沒有加條件。 這個語句的查詢非常慢,一開始我以為網路又出問題了,後來等了一會才返回結果。

利用這個語句就查詢到了那個儲存過程的確是存在鎖。利用kill將sessionkill掉

select sid,serial# from v$session where sid=XXX;
alter system kill session 'XXX,XXXXXX';
複製程式碼

再次執行編譯,成功。。

總結

V$LOCKED_OBJECT中只能查詢到DML鎖,DDL鎖是查詢不到的, 通過dba_ddl_locks可以查詢到資料庫中 的ddl鎖,其實dml鎖同樣可以通過dba_dml_locks檢視進行查詢,在每次發現有鎖的時候要區分鎖的種類進行查詢。

相關文章