起因
事情是這麼發生的:當天網路不好,一個簡單的查詢語句都會卡一下,在完成一個儲存過程之後點選編譯,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檢視進行查詢,在每次發現有鎖的時候要區分鎖的種類進行查詢。