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

Oracle 死鎖診斷與解鎖實戰:從錯誤現象到 Session Kill

     編輯:Oracle 教學

現象

  • 手動修改記錄彈出「資源忙碌,指定以 NOWAIT 方式獲取資源超時」對話框。
  • PL/SQL 執行更新語句長時間無回應 (顯示「正在執行」)。
  • 結論:發生死鎖 (或長時間鎖等待)。
資源忙碌錯誤 PL/SQL 執行卡住

步驟 1:查詢被鎖物件與持有 Session

SELECT 
    l.session_id        AS sid,
    s.serial#,
    l.locked_mode       AS 鎖模式,
    l.oracle_username   AS 登錄用戶,
    l.os_user_name      AS 作業系統用戶,
    s.machine           AS 機器名,
    s.terminal          AS 終端,
    o.object_name       AS 被鎖物件,
    s.logon_time        AS 登錄時間
FROM v$locked_object l
JOIN all_objects o ON l.object_id = o.object_id
JOIN v$session s ON l.session_id = s.sid
ORDER BY sid, s.serial#;
鎖查詢結果

關鍵欄位說明

  • LOCKED_MODE:0=None, 1=Null, 2=Row-S (SS), 3=Row-X (SX), 4=Share, 5=S/Row-X (SSX), 6=Exclusive (X)。6 為排他鎖 (DML 修改)。
  • SID, SERIAL#:唯一識別 Session,用於 Kill。

步驟 2:終結阻塞 Session

ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;

範例:ALTER SYSTEM KILL SESSION '7,223' IMMEDIATE;

Kill Session 命令

IMMEDIATE 關鍵字作用

  • 立即標記 Session 為「KILLED」,釋放鎖資源,回滾未提交交易。
  • 無 IMMEDIATE 時,Session 仅标记为待殺除,需等待其下一次資料庫呼叫才真正終止。

進階診斷:鎖等待鏈

-- 完整等待鏈:阻塞者 → 被阻塞者
SELECT 
    blocking_session,
    sid,
    serial#,
    wait_class,
    event,
    seconds_in_wait,
    sql_id
FROM v$session
WHERE blocking_session IS NOT NULL
ORDER BY blocking_session;

常見死鎖成因與預防

生產環境操作建議

  1. 先確認阻塞 Session 是否為關鍵業務 (如結帳、結算),評估 Kill 影響。
  2. 嘗試聯繫持有 Session 的用戶/應用負責人正常提交/回滾。
  3. 必須 Kill 時,使用 IMMEDIATE 並通知相關方。
  4. 事後分析 V$SESSION_WAIT_HISTORY、ASH 報告 定位根因並修正應用/索引。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
成因說明預防措施
多 Session 以不同順序更新同組表Session A 更新 Table1→Table2,Session B 更新 Table2→Table1應用層統一表訪問順序 (按名稱/ID 排序)
未提交的長交易持有鎖批次處理未分批提交,或異常未捕獲導致交易懸掛批次提交、設定交易超時、異常處理中 ROLLBACK
索引缺失導致全表掃描鎖定大量行WHERE 條件無索引,行級鎖升級為大量行鎖建立適當索引、使用 SELECT FOR UPDATE NOWAIT 快速失敗
外鍵未建索引父表刪除/更新時需全表掃描子表加鎖為所有外鍵欄位建立索引