ORA-01591错误解决方法(二)

2014-11-24 17:28:13 · 作者: · 浏览: 1

16hextoraw( '00000001' ),


17hextoraw( '00000000' ),

180, sysdate, sysdate );



已创建 1 行。



SQL> insert into pending_sessions$

2values( '72.0.1608712',

31, hextoraw('05004F003A1500000104'),

4'C', 0, 30258592, '',

5146

6);



已创建 1 行。



SQL> commit;



提交完成。

SQL> alter system enable distributed recovery;



系统已更改。



此时,查询dba_2pc_pending发现已有该事务,并且状态是我们模拟出的prepared状态

SQL> select * from dba_2pc_pending;

LOCAL_TRAN_IDGLOBAL_TRAN_ID STATEMIX A TRAN_COMMENTFAIL_TIMEFORCE_TIME RETRY_TIME OS_USER

OS_TERMINAL HOSTDB_USER

COMMIT#

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

72.0.1608712XXXXXXX.12345.1.2.3 prepared no12-11月-0812-11月-08



此时我们结束这个事务

SQL> COMMIT FORCE '72.0.1608712';



提交完成。



再次查询dba_2pc_pending,发现事务是forced commit状态,该事务已经结束。

SQL> select * from dba_2pc_pending;



LOCAL_TRAN_IDGLOBAL_TRAN_ID STATEMIX A TRAN_COMMENTFAIL_TIMEFORCE_TIME RETRY_TIME OS_USER

OS_TERMINALHOSTDB_USER COMMIT#

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

72.0.1608712XXXXXXX.12345.1.2.3 forced commitno12-11月-08 12-11月-08 12-11月-08



通过x$kutxe 查询事务信息,发现事务释放了回滚段,事务已经结束。

SQL> SELECT KTUXEUSN, KTUXESLT, KTUXESQN, /* Transaction ID */

2KTUXESTA Status,

3KTUXECFL Flags

4FROM x$ktuxe

5WHERE ktuxesta!='INACTIVE'

6AND ktuxeusn= 72;



未选定行



此时,我们需要清除dba_2pc_pending中分布式事务的残余信息

SQL> alter session set "_smu_debug_mode"=4;―― 在session级别设置回滚段处于手工管理模式,如果不设置这个参数,在回滚段自动管理模式下,清除事务信息会报错

会话已更改。



SQL> execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('72.0.1608712');――用dbms包清除事务信息



PL/SQL 过程已成功完成。



SQL> select * from dba_2pc_pending;



未选定行



测试访问业务表

SQL> select count(*) from UNITELE.BI_MQSYNC_SOURCE_CONTROL_T1;



COUNT(*)

----------

367

问题解决。


其实,我在另外一个客户处也碰到过类似问题,当时也是报ORA-01591,但是在dba_2pc_pending中可以查到prepared状态的事务,此时只需要commit force结束这个事务,并清除事务信息就可以了。对于上面的案例,我怀疑开发商直接清除了分布式事务信息,但是事务并没有结束,导致锁资源得不到释放报ORA-01591。



总结:ORA-01591错误一般是由于分布式事务造成的,造成分布式事务失败的原因主要是库之间的网络突然中断,造成两个库中的事务信息不一致,所以会有残余的分布式事务信息。此时,要针对不同的事务状态做不同的 理。同时在遇到棘手的问题时,可以查询metalink,该案例参考metalink文档:NOTE:401302.1
[@more@]