ITPub博客

首页 > 数据库 > Oracle > oracle ORA-01591锁被未决分布式事务处理

oracle ORA-01591锁被未决分布式事务处理

原创 Oracle 作者:wanglinghua0907 时间:2024-01-26 10:59:21 0 删除 编辑


概念:

大意就是,通过dblink连接另一个数据库的表是,对另一个数据库的表进行dml操作,同时也可能在同一个事务中对本库中的本地表做事务提交操作,那么对于dblink的表,需要确保远端的数据库也要提交,那么在本地像远端确认提交的时候,先由本地库发一个prepare的确认信息,远端回复prepare了以后,本地在执行commit信息;此种情况就是在本地执行commit以后,此时远端库还没有完全commit,此时网络中断,导致本地库该表是commit状态,但是远端库还是prepare状态,一般来讲,此时如果源端得到的事务信息是全的,那么数据库不需要人为干预,能够自动根据事务信息进行提交操作,但是出现这个问题的时候,基本就表示提交的事务信息不足以让远端库执行提交操作,所以此时这种事务就需要人为干预了。


视图:

dba_2pc_pending

dba_2pc_neighbors


1.查看

select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending;

或者查*,更全

LOCAL TRAN ID 11.4.419599 GLOBAL TRAN ID ORAHIS . 56f3543 . 11. 4 .419599 STATE c 011 ect ing FAIL 2020-07-30 19: 13:18


1.collecting:在收集数据过程中,产生异常

解决方法: 

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('11.4.419599');

commit;


2.prepared: 在接受到异步commit/rollback指令前, 产生异常

解决方法:  

rollback force tran_id

commit force tran_id; -- 可根据异步transaction的状况决定使用方法。


拼接:

select 'rollback force  ''' || LOCAL_TRAN_ID || ''';' || chr(10) ||
'execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(''' || LOCAL_TRAN_ID
 || ''');' || chr(10) || 'commit;' from DBA_2PC_PENDING;

3.forced rollback: 在使用rollback force出现

解决方法: 

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('11.4.419599');

commit;


4.forced commit:在使用commit force出现

解决方法:  

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('11.4.419599');

commit;


2.prepared解决不了的情况

查询该事务表是否有活动事务

SELECT ktuxeusn,
ktuxeslt,
ktuxesqn,
ktuxesta status,
ktuxecfl flags
FROM x$ktuxe
WHERE ktuxesta != 'inactive'
AND ktuxeusn = 11
AND ktuxeslt = 4
AND ktuxesqn = 419599;

2.1如果没有活动事务

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



2.2如果有活动事务

尝试purge失败

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('11.4.419599');

commit;

execute dbms_transac t ion. 20. 25. 280352' begin dbtng_ transaction. 20, 2.5. 280352')


删除数据字典中分布式事务信息

delete from sys.pending_trans$ where local_tran_id = '11.4.419599';
delete from sys.pending_sessions$ where local_tran_id = '11.4.419599';
delete from sys.pending_sub_sessions$ where local_tran_id ='11.4.419599';
commit;

禁用自动分布式恢复

alter system disable distributed recovery;


根据事务id插入分布式信息(信息随意,只是为了后面回滚使用)

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     ( '11.4.419599', /* <== Replace this with your local tran id */
             306206,
             '123.12345.1.2.3',
             'prepared',
             'p',
             Hextoraw('00000001'),
             Hextoraw('00000000'),
             0,
             sysdate,
             sysdate );
 
INSERT INTO pending_sessions$
VALUES     ( '11.4.419599',/* <==replace only this with your local tran id */
             1,
             Hextoraw('05004f003a1500000104'),
             'c',
             0,
             30258592,
             '',
             146 );
             
             
commit ;

回滚事务

rollback force '11.4.419599';


重新启用自动分布式事务恢复

alter system enable distributed recovery;


再次查看state,已经不是prepared

select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending where LOCAL_TRAN_ID='11.4.419599';



清理没用的事务信息

exec dbms_transaction.purge_lost_db_entry('11.4.419599');


解决


3.分布式事务存在,dba_2pc(pending表)视图中没有数据

遇到ORA-2054, ORA-1591等错误,但是dba_2pc_pending没记录。

这种情况,commit force还是rollback force都会报

ORA-02058: no prepared transaction found with ID 10.20.360

一样的方式,将基表数据补齐。


1.dba_2pc_pending是否没记录

select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending;


2.确认该事务表是否有活动事务

SELECT ktuxeusn,
ktuxeslt,
ktuxesqn,
ktuxesta status,
ktuxecfl flags
FROM x$ktuxe
WHERE ktuxesta != 'inactive'
AND ktuxeusn = 11
AND ktuxeslt = 4
AND ktuxesqn = 419599;

3.禁用自动分布式恢复

alter system disable distributed recovery;


4.根据事务id插入分布式信息(信息随意,只是为了后面回滚使用)

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     ( '11.4.419599', /* <== Replace this with your local tran id */
             306206,
             '123.12345.1.2.3',
             'prepared',
             'p',
             Hextoraw('00000001'),
             Hextoraw('00000000'),
             0,
             sysdate,
             sysdate );
 
INSERT INTO pending_sessions$
VALUES     ( '11.4.419599',/* <==replace only this with your local tran id */
             1,
             Hextoraw('05004f003a1500000104'),
             'c',
             0,
             30258592,
             '',
             146 );
             
             
commit ;

5.回滚事务

rollback force '11.4.419599';


6.重新启用自动分布式事务恢复

alter system enable distributed recovery;


7.再次查看state,已经不是prepared

select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending where LOCAL_TRAN_ID='11.4.419599';

8.清理没用的事务信息

exec dbms_transaction.purge_lost_db_entry('11.4.419599');


解决


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69980685/viewspace-3005230/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle ACE、sql server、oceanbase数据库专家,拥有7年以上的大型数据库运维经验,主方向oracle,擅长故障排除、诊断,大体量(TB)迁移,异常故障修复等。拥有丰富主导大型项目经验。服务行业包括:运营商、银行、金融业、政府单位、医疗、制造业、高校等等。

注册时间:2020-07-31

  • 博文量
    116
  • 访问量
    88775