并行回滚是oracle的一个特性,初衷是为了加速失败事务的回滚,缩小回滚时间,Oracle设计这个特性的初衷大多时候都是实现了,但是在一些情况下,这个初衷变成了硬伤,就像七伤拳一样,伤害是不错,但是自己也要受几份内伤。最近碰到2次因为这个特性导致的数据库hang或者部分业务hang的情况。
我根据经验总结一翻并行回滚的情况怕遇见2种情况:
1.并行回滚相关的bug,此类bug有不少
2.大事务的回滚
关于事务恢复的东西可以参考文章:ID 1494886.1。这里介绍前天碰到的并行回滚导致阻塞的问题,情况是对某张表进行exp导出,结果很慢很慢,等了一晚上都没导完成,采用create table as select的方式也hang住了,信息传到到我这里时候我的反应是事务阻塞,初始判断应该是在段头或者回滚上的阻塞,远程过去时候,并不急着看系统的总体情况,和客户先沟通一翻情况发生的时候是下午1点多开始的,exp和ctas操作也是1点之后,稍微梳理相关的语句信息后初步决定做这几步操作:
1.分析alert.log
2.分析block=1的进程是否存在,是否存在死事务
3.分析发生情况时候的awr以及ash
4.分析发生情况时候的io/cpu情况
5.分析exp/ctas操作时候exp进程的等待
原本打算根据如上的情况后再做下一步的操作,结果在第3个步骤时候就已经发现了问题。alert日志没有报错已经相关有作用的信息,系统中也没有存在的阻塞进程,而AWR中top 5 event确实和我预测的方向在一条线上,具体看如下:
Top 5 Timed Foreground Events
Event | Waits | Time(s) | Avg wait (ms) | % DB time | Wait Class |
---|---|---|---|---|---|
wait for a undo record | 484,175 | 51,190 | 106 | 79.33 | Other |
db file sequential read | 980,647 | 7,411 | 8 | 11.49 | User I/O |
db file scattered read | 29,860 | 723 | 24 | 1.12 | User I/O |
DB CPU | 354 | 0.55 | |||
read by other session | 50,013 | 269 | 5 | 0.42 | User I/O |
以上的信息提示的非常明显,在1小时内存在大量wait for a undo record等待,而此期间内已经关闭了业务,只有exp和ctas操作,可以进一步的判断阻塞的问题应该和涉及对象存在回滚事务有关,当然现场通过undo的信息确认了回滚的对象确实和exp的对象为同一个,具体的方法可以参考文章 《通过undo record找到对应回滚对象信息》 http://www.ludatou.com/?p=2258。
为了确定是并行回滚导致的问题期间收集了以下信息进行判断:
1.FAST_START_PARALLEL_ROLLBACK参数值为low
2.系统中存在死事务
通过awr和收集的信息确定了问题的根源应该就是并行回滚。当然多个并行的回滚进程并没有去判断,在windows平台在系统级别我跳过了这步,为了尽快恢复业务,随即确认了验证性的解决方案,对fast_start_parallel_rollback进行在线变更为false,在对此参数设置不同值的时候,smon进程会停止对该事务的恢复并根据新的参数值重新恢复该事务,该参数是动态的,因此改为false后可以遇见的是该事务会串行顺序回滚,并且速度应该不错,结果并没有让我失望,看下图便知:
当然,现场可以通过smon禁止回滚的方式让exp过去,毕竟是生产,有更好的办法,为啥要用oradebug呢?期间的问题还有不少值得思考,比如undo record的争用,并行回滚进程的资源耗用等,这里不做描述了。