前几天看技术通信的时候,看到一篇《一次悬挂事务处理的全过程》,觉得分析的很好,和大家来分享下。其中具体的过程就不细说了,主要介绍下思路。
问题是这样的,某数据库新建了一个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”;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
TRN TBL:: index state cflags wrap# uel scn dba parent-xid nub stmt_num ------------------------------------------------------------------------------------------------ 0x19 2 0x97 0x7571de 0x0021 0x0106.20f81ec5 0x5fc16d7f 0x0000.000.00000000 0x00000001 0x5fc16d7f 0x01 9 0x00 0x758b70 0x000c 0x0106.20f81f33 0x02001e14 0x0000.000.00000000 0x00000001 0x00000000 0x02 9 0x00 0x759c18 0x001c 0x0106.20f81ecd 0x02001e13 0x0000.000.00000000 0x00000001 0x00000000 0x03 9 0x00 0x7591f5 0x0028 0x0106.20f81f2b 0x02001e14 0x0000.000.00000000 0x00000001 0x00000000 0x04 9 0x00 0x758223 0x0013 0x0106.20f81f13 0x02001e14 0x0000.000.00000000 0x00000001 0x00000000 0x05 9 0x00 0x75839c 0x0029 0x0106.20f81f1f 0x02001e14 0x0000.000.00000000 0x00000001 0x00000000 0x06 9 0x00 0x758005 0x001e 0x0106.20f8218a 0x02001e14 0x0000.000.00000000 0x00000001 0x00000000 0x07 9 0x00 0x759125 0x0024 0x0106.20f81f03 0x02001e14 0x0000.000.00000000 0x00000001 0x00000000 0x08 9 0x00 0x7574c5 0x0005 0x0106.20f81f1b 0x02001e14 0x0000.000.00000000 0x00000001 0x00000000 0x09 9 0x00 0x756b6a 0x001b 0x0106.20f82178 0x02001e14 0x0000.000.00000000 0x00000001 0x00000000 0x0a 9 0x00 0x75886e 0x0006 0x0106.20f82186 0x02001e14 0x0000.000.00000000 0x00000001 0x00000000 0x0b 9 0x00 0x7595e2 0x0000 0x0106.20f81ec0 0x02001e13 0x0000.000.00000000 0x00000001 0x00000000 0x0c 9 0x00 0x7580c7 0x002f 0x0106.20f81f37 0x02001e14 0x0000.000.00000000 0x00000001 0x00000000 …… |
其中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。
一条评论
“只需直接修改dba 2pc pending信息即可” 怎么修改呢?
“检查此object no的对象在数据库中是否存在” 如果存在呢,该怎么处理呢?