利用BBED工具重现生产系统UNDO故障

不久前,公司一套Oracle 9i数据库出现了Dead事务,具体表现为数据库事务SMON回滚事务出现死循环,导致数据库redo log激增,(不断重写UNDO,抹掉重写抹掉重写….),CPU使用率高居不下。Dead事务无法清除,造成了生产系统巨大安全隐患,数据库CPU Idle基本为0,巨大的Redo使得数据库恢复成为可能中的不可能…..

数据库出现Dead事务,死循环回滚是因为UNDO BLOCK出现逻辑损坏,处理思路将该事务所用的回滚段DROP掉,代价为事务的提交结果回滚状态不可控,经与应用确认可忽略此事务的最终状态,所以决定使用本案例中的处理方案。

因ORACLE 9i数据库测试资源有限,我使用了11g 11.2.0.4版本测试环境重现UNDO BLOCK逻辑问题及处理方式。

一.故障现象模拟

(1)数据库建立新事务,不提交或回滚并查看事务信息:

undo_corruption_block -11

 

undo_corruption_block -21

(2)利用BBED工具将事务使用的UNDO段,将BLOCK DBA更改:

undo_corruption_block -3

(3)执行alter system flush buffer_cache

进行一致读与事务回滚操作,均失败:

undo_corruption_block-4

(4)数据库出现Dead事务,重启并不能解决问题:

undo_corruption_block-5

P.S x$ktuxe为 [K]ernel [T]ransaction [U]ndo Transa[x]tion [E]ntry,他可以帮助我们定位到数据库中的Dead事务,上图中的信息可以定位到3号回滚段中,事务槽6存在Dead事务。

二.故障现象恢复:

(1)如生产系统遇到UNDO故障,不要纠结于损坏的UNDO本身,尽快回复业务可用性为首要任务,我们当时生产数据库出现了相对于此案例更加严重UNDO损坏,导致事务无法正常进行

undo_corruption_block -10

(2)回归本案例,该Dead事务不会影响当前事务正常运行,但是会消耗巨大的数据库服务器、数据库资源:

我们将UNDO TABLESPACE已经切换至UNDOTBS2,但是UNDTBS1 TABLESPACE 3号回滚段认为ONLINE状态

undo_corruption_block-7

(3)尝试Drop Undo Segment不成功,同样因为存在Dead事务:(P.S 如果手工DROP UNDO SEGMENT 需要修改隐含参数: alter system set “_smu_debug_mode”=4;本测试环境之前已经修改完成)

undo_corruption_block-8

(4)利用*._corrupted_rollback_segments隐含参数将此Undo Segment标记为corrupted(需要重启实例),完成后,Dead事务已经消失,但是此事务不能Rollback成功,事务最终状态无法把控

undo_corruption_block -9