许玉晨 数据和云

墨墨导读:从 Oracle 9i 开始,Oracle引入了一种管理前镜像的新方式。之前的版本是通过 RollBack Segment 进行的,或称为 manual undo(手动 undo)。 


Oracle引入回滚段的目的: 1、事务回滚 2、数据库恢复 3、提供读一致性 4、数据库闪回查询(9i引入) 5、利用闪回特性可以恢复。

一、问题表象:


最近客户遇到一个奇怪的问题,oracle数据库大量undo段迟迟不expired, 最终导致undo不够用,引发一系列undo相关报错,关于隐患参数_undo_autotune是false。v$undostat 始终只有一行,数据一直累加,而正常环境应该是5分钟有一条新纪录。多次尝试重建undo没作用,Undo unexpire还是持续上涨, 修改undo_retention为10800(3小时), _highthreshold_undoretention也改为10800,仍然不起作用。


smon在启动后报了报错:
拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav

当出现断电或硬件故障数据库崩溃或者bug等,通常会发生此问题。启动时,数据库先进行正常的前滚(重做),然后再进行回滚(撤消),这是在回滚时生成错误的地方。


根据官方文档:ORA-600 [4193] “seq# mismatch while adding undo record” (Doc ID 39282.1)的描述,在重做记录和回滚记录之间检测到不匹配。拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_02常规情况,可以通过重建undo来解决,可以参考文档:Step by step to resolve ORA-600 4194 4193 4197 on database crash (Doc ID 1428786.1)

拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_03拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_04

二、问题分析


从 Oracle 9i 开始,oracle引入了一种管理前镜像的新方式. 之前的版本这是通过 RollBack Segment 进行的,或称为 manual undo(手动 undo)。


Oracle引入回滚段的目的:
1、事务回滚
2、数据库恢复
3、提供读一致性
4、数据库闪回查询(9i引入)
5、利用闪回特性可以恢复


我们来看下具体的报错,smon具体的报错信息如下:

拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_05

这里的XID,上面的第七行,表示当前undo block所记录的事务xid,对应V$TRANSACTION.XID信息。

拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_06看下trace里的ktuxc的信息,ktuxc的结构在undo segment header中拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_07

任何时候,一个事务只能使用一个undo block。当然,在Tx 事务表头(ktuxc)中,没有必要存放整个完整的uba地址,存放undo block的dba地址就足够了。事务用这个来指向最近被使用的undo block、块头包含了一个指针,指向了该事务所创建的的最新undo record记录。之前的记录都保存在同一个block或者在另外一个undo block中。undo chain的最末端是是没有dba地址,rci就是undo chain。


事务回滚的完整流程:
1、首先通过TX table header(ktuxc)找到的uba地址
2、通过Tx table中的uba地址,定位到最新使用的undo block地址
3、根据最新的undo block定位到最新的undo record


拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_08


继续看smon的trace拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_09拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_10Doing block recovery for file 8 block 2201054,这里数据尝试去恢复这个块,这个块是undo数据文件的块,也就是,uba:0x022195de.eeab.01对应的回滚段的块。拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_11

准备将这个块dump出来,发现提示无效的rowid。将这个块从asm到本地,发现无法拷贝。后来了解到,8号数据文件也就是undo数据文件,已经经过多次重建,已经找不到之前的数据块。

拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_12


三、解决方法


通过上面的分析,发现通过Tx table中的uba地址,定位到最新使用的undo block地址,这个块根本不存在,多次尝试重建undo没作用。重点来了,那么如何处理?


解决方法:
1、隐含参数*._corrupted_rollback_segments、._offline_rollback_segments。
2、10513 event来禁止smon 进行事务恢复(不一定起作用)。
3、通过bbed修改system回滚段的块,清除free block pool,让oracle认为没有可用的undo block了。
拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_13拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_14

system检查没有坏块。


拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_15


smon的trace不再报错,恢复正常。


拨云见日:揭开ORA-00600:[4193]的神秘面纱_Jav_16


备注:核心生产的system数据块的修改具有一定的危险性,如有问题请联系恩墨工程师,为您提供快速专业可靠的服务。


墨天轮原文链接:https://www.modb.pro/db/29145(复制到浏览器中打开或者点击“阅读原文”)