一次悬挂事务的处理思路

前几天看技术通信的时候,看到一篇《一次悬挂事务处理的全过程》,觉得分析的很好,和大家来分享下。其中具体的过程就不细说了,主要介绍下思路。

问题是这样的,某数据库新建了一个undotbs2,准备将系统默认的undotbs1(已经使用了2年了)切到undotbs2中。但是很长时间undotbs1中仍然有online的segment,并且数据库alerlog中出现告警:Undo Tablespace 4 moved to Pending Switch-Out states。

1.检查dba_rollback_segs中哪个segment_name,segment_id是非offline状态。

2.根据segment_id关联v$rollstat表的usn,观察其详细状态,发现status为pending offline。

3.alter system dump undo header “undo的segment_name”;

其中state表示undo的状态,state=9表示已经commit或者rollback,state=10表示没有commit或者rollback,states=2表示存在prepared的悬挂事务。

4.检查发现dba_2pc_pending中无记录

5.检查发现在x$ktuxe中存在kutxesta=’PREPARED’ and ktuxecfl like ‘%REV%’的记录。

6.因此,问题就找到原因了,是属于dba_2pc_pending和基表信息不一致。由于undotbs1上有悬挂未决的事务,使得其中一个segment无法正常offline。因此无法完成切换。

7.修正一致性。dba 0x5fc16d7f经过转化,16进制转成2进制,前面补起0到32位,前10位为file id,后面的为block id,得0x5fc16d7f->1011111110000010110110101111111->1011111110000010110110101111111->0101111111 0000010110110101111111->383 93567
于是alter system dump file 383 block 93567;
看trace文件中objn,检查此object no的对象在数据库中是否存在,如果不存在,则我们不需要重建该对象,只需直接修改dba 2pc pending信息即可。

8.将pend_trans$视图补录完整,可见http://www.oracleblog.org/working-case/how-to-deal-with-distributed-transaction/,分布式事务故障处理的最后一段。其中,local transaction id为之前查询x$ktuxe表的ktuxeusn.ktuxeslt.ktuxesqn。

相关文章

一条评论

  1. “只需直接修改dba 2pc pending信息即可” 怎么修改呢?
    “检查此object no的对象在数据库中是否存在” 如果存在呢,该怎么处理呢?

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据