oracle分散式事務異常處理方法

sjw1933發表於2024-04-09

故障描述

業務執行特定模組時報錯,比如:

lis 中語句如下:

select mzhm, max(shsj) as shsj, jg
  from (select a.outpatient_id as mzhm,
               a.check_time as shsj,
               (select quantitative_result
                  from lis_inspection_result rst
                 where rst.inspection_id = a.inspection_id) as jg
          from lis_inspection_sample a, lis_requisition_item b
         where a.requisition_id = b.requisition_id
           and check_time > sysdate - 4
           and b.charge_item_id in
               ('LIS062943', 'LIS080455', 'LIS069172', 'LIS080454',
                'LIS080073', 'LIS080072', 'LIS080450', 'LIS080459',
                'LIS080451', 'LIS080491', 'LIS080492')) aa
 group by mzhm, jg;


報錯如下圖:

解決方法

查詢 dba_2pc_pending 檢視,可看到確實有此事務

一、嘗試將此分散式事務 rollback

rollback force '13.3.394006';


等待數分鐘未能正常回滾

二、如果rollback ,可以採用 手工清理事務的方式

set transaction use rollback segment SYSTEM;
delete from sys.pending_trans$ where local_tran_id = '13.3.394006'; 
delete from sys.pending_sessions$ where local_tran_id = '13.3.394006'; 
delete from sys.pending_sub_sessions$ where local_tran_id ='13.3.394006'; 
commit;

再次查詢 dba_2pc_pending 檢視

已無事務資訊

但在當前資料庫執行語句時依舊報錯

ORA-01591: lock held by in-doubt distributed transaction 13.3.394006

即使是重啟資料庫例項也無法釋放

三、如果前兩者都不行,都不能恢復業務,那麼 進一步處理

參考文件:( DBMS_LOGSTDBY.BUILD Seems to Hang And Does Not Return To SQL prompt. (Doc ID 747495.1)

查詢 rollback segment 基表 x$ktuxe


SELECT KTUXEUSN, KTUXESLT, KTUXESQN, /* Transaction ID */ KTUXESTA Status,KTUXECFL Flags FROM x$ktuxe WHERE ktuxesta!='INACTIVE' AND ktuxeusn= 1;

KTUXEUSN KTUXESLT KTUXESQN STATUS FLAGS

---------- ---------- ---------- ---------------- ------------------------

9 26 1443117 ACTIVE NONE

11 14 9246366 ACTIVE NONE

13 3 394006 PREPARED SCO|COL|REV|DEAD

嘗試手工回滾這個事務
commit force
'13.3.394006' ;
報錯:ORA-02058: no prepared transaction found with ID 13.3.394006

處理方法:手工插入pending_trans$基表資料後再進行刪除

a

lter 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( ‘13.3.394006’, /* <== 這裡替換成報錯的事務號,即13.3.394006 */
306206, /* */
'XXXXXXX.12345.1.2.3', /* 這些不用修改 */
'prepared','P', 
hextoraw( '00000001' ), 
hextoraw( '00000000' ), 
0, sysdate, sysdate );
 
insert into pending_sessions$
values( ‘13.3.394006’, /* <== 這裡替換成報錯的事務號,即13.3.394006 */
1, hextoraw('05004F003A1500000104'), /* 這些不用修改 */
'C', 0, 30258592, '', 146); /* 這些不用修改 */
 
commit;
commit force ‘13.3.394006’;
 
If commit force raises an error then note the error message and execute the following:
 
delete from pending_trans$ where local_tran_id=‘13.3.394006’;
delete from pending_sessions$ where local_tran_id=‘13.3.394006’;
commit;

alter system enable distributed recovery;

總結與建議

ORA-01591 錯誤一般是由於分散式事務造成的,造成分散式事務失敗的原因主要是庫之間的網路突然異常,造成兩個庫中的事務資訊不一致,所以會有殘餘的分散式事務資訊。對於絕大多數情況,當恢復連線或 CRASH 的資料庫重新啟動後,會自動解決分散式事務,不需要人工干預。當特殊情況,網路異常,觸發特殊資料庫 BUG 時,未成自動 recovery 事務時,才使用人工操作的方式來維護分散式事務。




來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/23825935/viewspace-3011857/,如需轉載,請註明出處,否則將追究法律責任。

相關文章