記錄**未解決的分散式交易** (Two-Phase Commit, 2PC)。當分散式交易的 COMMIT/ROLLBACK 階段發生網路中斷、節點故障,導致無法完成兩階段提交時,交易資訊會寫入此視圖等待恢復。
DBA_2PC_PENDING| 視圖 | 用途 |
|---|---|
DBA_2PC_PENDING | 本地待解決分散式交易:LOCAL_TRAN_ID, GLOBAL_TRAN_ID, STATE, MIXED, ADVICE, HOST, COMMIT# |
DBA_2PC_NEIGHBORS | 交易參與節點:LOCAL_TRAN_ID, IN_OUT, DATABASE, DBUSER_OWNER, INTERFACE, DBID, SESS#, BRANCH |
SELECT local_tran_id, global_tran_id, state, mixed, advice, host, commit#
FROM dba_2pc_pending;
STATE:collecting (準備階段)、prepared (已準備)、committed、forced commit、forced rollbackADVICE:C (建議提交)、R (建議回滾)、 (無建議)MIXED:YES 表示衝突 (部分提交部分回滾)
SELECT * FROM dba_2pc_neighbors WHERE local_tran_id = 'xxx.xxx.xxx';
-- 強制提交
EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');
-- 或
COMMIT FORCE 'local_tran_id';
-- 強制回滾
ROLLBACK FORCE 'local_tran_id';
警告:手動強制**破壞 2PC 一致性保證**,必須確認所有節點狀態一致後再執行。
-- 當 MIXED=YES (部分節點提交、部分回滾)
EXECUTE DBMS_TRANSACTION.PURGE_MIXED('local_tran_id');
-- 當參與節點永久失聯 (重建/無法啟動)
EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');
UNDO_MANAGEMENT = MANUAL 才能使用 PURGE 程序 (文件未明載)。AUTO 模式下需:
ALTER SYSTEM SET UNDO_MANAGEMENT=MANUAL SCOPE=SPFILE;**實務上極少使用**,通常等待自動恢復或重啟實例。
V$LOCK、V$SESSION_WAIT 確認阻塞鏈
-- 停用 (維護期間防止自動介入)
ALTER SYSTEM DISABLE DISTRIBUTED RECOVERY;
-- 啟用 (預設)
ALTER SYSTEM ENABLE DISTRIBUTED RECOVERY;
分散式查詢前確保 SCN 同步:
-- 方法 1:查詢遠端 DUAL
SELECT * FROM dual@remote_db;
-- 方法 2:提交/回滾當前交易
COMMIT; -- 或 ROLLBACK
-- 給交易命名 (便於追蹤)
SET TRANSACTION NAME 'OrderProcess_20231101_001';
-- 交易中宣告建議 (供手動恢復參考)
ALTER SESSION ADVISE COMMIT; -- 或 ROLLBACK
-- 執行分散式操作
-- COMMIT;
| 錯誤 | 含義 | 處理 |
|---|---|---|
| ORA-02049 | 分散式交易等待鎖逾時 | 檢查阻塞鏈、考慮手動解決 |
| ORA-02050 | 交易已回滾 (遠端節點失敗) | 查看 ALERT LOG、重試 |
| ORA-02051 | 交易狀態不一致 | 檢查 DBA_2PC_PENDING、手動恢復 |
| ORA-02054 | 交易處於 prepared 狀態 | 等待 RECO 或手動 COMMIT FORCE |
| ORA-01591 | 鎖定被 in-doubt 分散式交易持有 | 查詢 DBA_2PC_PENDING、強制解決 |
-- 定期排程檢查
SELECT local_tran_id, global_tran_id, state, mixed, advice,
host, commit#, SYSDATE - commit#/86400 AS days_pending
FROM dba_2pc_pending
WHERE state NOT IN ('committed', 'forced commit', 'forced rollback');
-- 結合告警:若 days_pending > 1 天發送通知