首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 預存程序編譯卡死?會話殘留導致 Recompile Hang 完整解決方案

     編輯:Oracle 資料庫基礎

問題現象

修改並重新編譯預存程序 B 後,需手動重新編譯呼叫它的程序 A。若在重新編譯 A 之前 先去呼叫/執行 A,極易導致 A 編譯過程卡死,尤其在高併發環境下更明顯。強制終止編譯會話後,會話狀態顯示 INACTIVE 但實際未釋放,再次 Recompile 仍會 Hang 住。

根因分析

編譯過程需取得 Library Cache Lock/Pin,若先前有會話持有相關鎖且未正常釋放(如中斷的執行、未提交的交易),後續編譯會阻塞於等待鎖釋放,形成看似「卡死」的現象。

解決步驟

1. 查詢殘留的 INACTIVE 會話

SELECT V.OSUSER,
       V.PROCESS,
       V.PROGRAM,
       V.MACHINE,
       V.TERMINAL,
       V.MODULE,
       V.USERNAME,
       V.STATUS,
       V.SID,
       V.SERIAL#,
       'ALTER SYSTEM KILL SESSION ''' || V.SID || ',' || V.SERIAL# || ''';' AS KILL_SESSION,
       V.PADDR
FROM V$SESSION V
WHERE V.USERNAME LIKE '%USERNAME%'
  AND V.PROGRAM LIKE 'PlSqlDev%'
  AND V.OSUSER LIKE '%%'
  AND V.STATUS = 'INACTIVE';

註:USERNAME、PROGRAM、OSUSER 條件請依實際環境調整,關鍵在於 STATUS = 'INACTIVE' 且為開發工具產生的會話。

2. 執行產生的 KILL SESSION 指令

將查詢結果的 KILL_SESSION 欄位複製,在 SQL*Plus 中執行,終止殘留會話。

3. 重新登入開發工具並 Recompile

殺掉會話後,重新連線至 PL/SQL Developer 或其他工具,對目標預存程序執行 Recompile,即可恢復正常。

預防建議

  • 編譯順序原則: 先編譯被參考物件(B),再編譯參考物件(A),編譯期間嚴禁執行相關程序
  • 維護窗口操作: 可在低峰期或維護窗口執行大量物件重編譯,減少衝突
  • 使用 DBMS_UTILITY.COMPILE_SCHEMA: 批次編譯 Schema 物件,由 Oracle 內部處理依賴順序

總結

預存程序編譯 Hang 多因殘留 INACTIVE 會話持有鎖資源。透過 V$SESSION 精準定位並 Kill 掉這些會話,配合正確的編譯順序,即可徹底解決並預防此類問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved