一次ORACLE分散式事務鎖異常處理分析

yingyifeng306發表於2022-04-15

Lis 業務執行特定模組時報錯,此模組為醫院 HIS dblink lis 庫執行語句

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';

等待數分鐘未能正常回滾

手工清理事務

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$基表資料後再進行刪除

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( 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 事務時,才使用人工操作的方式來維護分散式事務。

建議:

1 )保持 dblink 資料庫之間的網路穩定

2 )同時減少使用 dblink 進行跨庫事務處理


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

相關文章