ORACLE懸疑分散式事務問題處理
當需要在多個Oracle資料庫之間進行資料一致性操作時,就會用到分散式事務。
例如:
insert into T_log@remote_db; --遠端資料庫插入 insert into T_local; --本地資料庫插入 commit;
分佈在本地和遠端兩個db的事務同時操作,這就構成了一個分散式事務。
分散式事務採用Two-Phase Commit提交機制,保證分佈在各個節點的子事務能夠全部提交或全部回滾的原子性。在這種機制下,事務處理過程分為三個階段:
- PREPARE:發起分散式事務的節點通知各個關聯節點準備提交或回滾。各關聯節點此時會做三個事情:重新整理redo資訊到redo log中;將持有的鎖轉換為懸疑事務鎖;取各節點中最大的SCN號進行同步
- COMMIT:寫入commited SCN,釋放鎖資源
- FORGET:懸疑事務表和關聯的資料庫檢視資訊清理
由於分散式事務涉及到多個資料庫之間進行操作,偶爾會遇到一些異常情況(例如系統或網路中斷)導致上述三個階段出現異常,這就在一個或多個節點上,產生不完整的“懸疑分散式事務”。
大多數情況下,出現這種問題,Oracle會由Reco程式進行自動修復,Oracle資料庫會在dba_2pc_pending 和dba_2pc_neighbors等多個檢視中記錄分散式事務相關的資訊,事實上reco程式也是基於這些資訊去做自動修復的。
Reco程式會嘗試連線到其他節點獲取分散式事務資訊,然後嘗試修復失敗的事務,並將對應的事務中的記錄刪除。
但有些情況下(例如節點無法正常訪問或事務表中記錄的資料不完整),Reco程式不能正常完成這個工作,就會丟擲異常。對於分散式事務,對應的異常程式碼區間是ORA-02040 - ORA-02099,可透過alert日誌檢視到錯誤資訊。
例如:
ORA-02054: transaction in-doubt The transaction is neither committed or rolled back locally, and we have lost communication with the global coordinator.
此時往往需要手工處理進行干預。
以下是三種常見的分散式事務問題場景:
- dba_2pc檢視中有資料,但分散式事務已經不存在
- 分散式事務存在,但dba_2pc檢視中沒有資料
- 事務和檢視資料都有,但是執行commit force或rollback force時hang住
透過報錯會有提示,例如:
ORA-01591: lock held by in-doubt distributed transaction 10.20.360 這個10.20.360就是我們需要檢查分散式事務ID
場景一:dba_2pc檢視中有資料,但分散式事務已經不存在
檢視有資料,那麼先檢查資料的狀態
select * from dba_2pc_pending where local_tran_id='10.20.360';
主要看state欄位。
如果事務已經是committed, rollback forced或者commit forced狀態,表示事務已經完成了,但是在FORGET階段處理時,資料庫字典的資訊沒能及時清除。此時,我們呼叫oracle的清理丟失事務資訊的語句就可以完成處理:
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY ('10.20.360');
如果事務是PREPARED狀態,但是在事務表中又沒有活動的事務:
SELECT KTUXEUSN, KTUXESLT, KTUXESQN, /* Transaction ID */ KTUXESTA Status, KTUXECFL Flags FROM x$ktuxe WHERE ktuxesta!='INACTIVE' AND ktuxeusn= 10; --注意替換這裡的回滾段號(xid=usn.slot.(sqn+1)) ----沒有活動的事務
那此時需要手工清理丟失事務的資訊
set transaction use rollback segment SYSTEM; delete from sys.pending_trans$ where local_tran_id = ; delete from sys.pending_sessions$ where local_tran_id = ; delete from sys.pending_sub_sessions$ where local_tran_id = ; commit;
場景二:分散式事務存在,但dba_2pc檢視中沒有資料
遇到ORA-2054, ORA-1591等錯誤,檢查dba_2pc檢視沒有記錄,這種場景不常見,只在少數極端的情況下出現。
先確認現象,分別檢查x$ktuxe和 dba_2pc_pending檢視,查詢語句與場景一相同
在這種情況下無論是執行commit force還是rollback force,都會直接丟擲異常:
commit force '10.20.360'; ORA-02058: no prepared transaction found with ID 10.20.360
這時我們需要將檢視對應的基表資料補入,然後再執行rollback force。
alter system disable distributed recovery; insert into pending_trans$ ( LOCAL_TRAN_ID, GLOBAL_TRAN_FMT, GLOBAL_ORACLE_ID,STATE, STATUS, SESSION_VECTOR,RECO_VECTOR,TYPE#, FAIL_TIME, RECO_TIME) values( '10.20.360', /* <== Replace this with your local tran id */ 306206, 'xxxxxxxx.00000.0.0.0', 'prepared','P', hextoraw( '00000001' ),hextoraw( '00000000' ), 0, sysdate, sysdate ); insert into pending_sessions$ values( '10.20.360',1, hextoraw('00000000'), 'C', 0, 1433927502, '', 14); --1433927502為DBID, 14為userid commit; rollback force '10.20.360'; EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('10.20.360'); --手工清理事務資訊
場景三:事務和檢視資料都有,但是執行commit force或rollback force時hang住
如果檢視和事務表中都有資料,而且狀態是PREPARED,先執行commit force或rollback force,通常就能解決問題,但有時候也會遇到執行force處理時hang住
嘗試purge事務資訊時,有提示報錯:
BEGIN DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('10.20.360'); END; * ERROR at line 1: ORA-06510: PL/SQL: unhandled user-defined exception ORA-06512: at "SYS.DBMS_TRANSACTION", line 94 ORA-06512: at line 1
此時需要進行場景一和場景二的結合起來的所有步驟:
1. 先將檢視對應的基表資料刪除 delete from sys.pending_trans$ where local_tran_id = '10.20.360'; delete from sys.pending_sessions$ where local_tran_id = '10.20.360'; delete from sys.pending_sub_sessions$ where local_tran_id ='10.20.360'; commit; 2. 再插入pending_trans$和pending_sessions$資料,見場景二 3. rollback force '10.20.360'; 4. Purge the transaction: exec dbms_transaction.purge_lost_db_entry('10.20.360');
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31556440/viewspace-2682006/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle分散式事務典型案例處理Oracle分散式
- oracle分散式事務異常處理方法Oracle分散式
- 分散式事務處理方案,微服事務處理方案分散式
- Laravel 分散式事務處理Laravel分散式
- springcloud分散式事務處理 LCNSpringGCCloud分散式
- 一次ORACLE分散式事務鎖異常處理分析Oracle分散式
- 13.SpringCloudSeata處理分散式事務SpringGCCloud分散式
- SpringCloud Alibaba Seata處理分散式事務SpringGCCloud分散式
- 阿里是如何處理分散式事務的阿里分散式
- Oracle Gateway for SQL Server時2PC分散式事務異常處理OracleGatewaySQLServer分散式
- ORACLE分散式事務鎖各種場景下的處理詳解Oracle分散式
- 微服務架構分散式事務管理問題微服務架構分散式
- 分散式系列七: 分散式事務理論分散式
- 分散式系統中的事務問題分散式
- 淺談ORACLE的分散式事務Oracle分散式
- 用Java輕鬆完成一個分散式事務TCC,自動處理空補償、懸掛、冪等Java分散式
- 分散式事務(2)---TCC理論分散式
- 老生常談——利用訊息佇列處理分散式事務佇列分散式
- .NET開源的處理分散式事務的解決方案分散式
- TCC和兩階段分散式事務處理的區別分散式
- 分散式事務處理兩階段提交機制和原理分散式
- 使用強大的DBPack處理分散式事務(PHP使用教程)分散式PHP
- Spring Boot 整合 Seata 解決分散式事務問題Spring Boot分散式
- 分散式事務(一)—分散式事務的概念分散式
- 分散式事務理論加實戰分散式
- (1)分散式事務理論基礎分散式
- 分散式事務對於兩階段提交的錯誤處理分散式
- 分散式事務系列 - 解決跨庫轉賬問題分散式
- Springboot資料庫事務處理——Spring宣告式事務Spring Boot資料庫
- SQLServer 2008中事務日誌已滿問題處理SQLServer
- oracle SP2-問題處理Oracle
- 分散式事務及其CAP和base理論分散式
- 分散式事務(3)---RocketMQ實現分散式事務原理分散式MQ
- Oracle vs PostgreSQL,研發注意事項(6)- 事務處理OracleSQL
- 分散式事務和分散式hash分散式
- 分散式事務(4)---RocketMQ實現分散式事務專案分散式MQ
- 理解分散式事務分散式
- 分散式事務概述分散式