近期在生产库遇到分布式事务异常,导致涉及的对象被锁住,业务无法正常操作该对象,引发故障
具体日志信息:
Sat Dec 28 11:15:27 2019 Error 2050 trapped in 2PC on transaction 191.4.1345608. Cleaning up. Error stack returned to user: ORA-02054: transaction 191.4.1345608 in-doubt ORA-02050: transaction 2732.33.66755 rolled back, some remote DBs may be in-doubt ORA-03135: connection lost contact ORA-02063: preceding line from xxx ORA-02063: preceding 3 lines from ooo
从dba_2pc_pending中能查到异常事务的状态为prepared,需要手动强制回退异常事务,再清理异常事务记录
具体操作:
rollback force ‘191.4.1345608‘; execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘1.10.255‘);
问题解决!
总结下dba_2pc_pending中事务的几个状态说明和处理方法:
1、Collecting:prepare阶段没准备好就失败了,global coordinator正在等待各个站点返回已准备好的通知,各个站点什么都没发生,无需执行任何操作
处理方法:在本地数据库执行exec dbms_transaction.purge_lost_db_entry(’transaction_id’)清除in_doubt状态的分布式事务记录就可以了
2、Prepared:prepare阶段完成时发生失败,global coordinator处于prepared状态,已经加上分布锁,等待提交,远程commit point site已经自动回滚
处理方法:在global coordinator上执行rollback force ‘transaction_id’,然后在本地数据库执行exec dbms_transaction.purge_lost_db_entry(’transaction_id’)清除in_doubt状态的分布式事务记录
3、Committed:表示此session已提 交,只是在提交后,接受不到global session的transaction信息了,所以产生异步lock,此时对一般不造成table的lock
处理方法:在本地数据库执行exec dbms_transaction.purge_lost_db_entry(’transaction_id’)清除in_doubt状态的分布式事务记录就可以了
4、Forced Commit和Forced Rollback:表示处于forget阶段时出现异常
处理方法:只需在各站点执行exec dbms_transaction.purge_lost_db_entry(’transaction_id’)清除in_doubt状态的分布式事务记录就可以了
总结常见涉及分布式事务的报错及原因说明:
1、ORA-02053: transaction committed, some remote DBs may be in-doubt
事务已经本地提交,然而与其他lc节点的连接已经丢失
2、ORA-02054: transaction in-doubt
事务本地既没有提交也没回滚,丢失与Global Coordinator的连接
3、ORA-02050: transaction rolled back, some remote DBs may be in-doubt
暗示在两阶段提交时发生通信错误.
4、ORA-01591: lock held by in-doubt distributed transaction
遇到上面的错误,用户/应用无法继续处理这个事务,在这种情况下,数据库自动回滚用户的事务请求并且DBA需要手工提交或回滚未确定事务.
注意:读取将会被阻塞,因为直到事务被处理,Oracle不会处理相关数据的版本返回给查询用户.