在这里收录曾经遇到的另一个案例,本案例发生在某大型电信运营商的生产系统。
收到技术援助请求后,登陆该数据库主机。客户报告的情况是,CPU忙,IO缓慢,业务请求无法响应,客户投诉大量增加。
首先查看告警日志文件,得到如下信息:
bash-2.03$ cd admin/wap/bdump/ bash-2.03$ tail -f alert_WAPTL.log SMON: mark undo segment 29 as available SMON: about to recover undo segment 29 SMON: mark undo segment 29 as available SMON: about to recover undo segment 29 SMON: mark undo segment 29 as available SMON: about to recover undo segment 29 SMON: mark undo segment 29 as available SMON: about to recover undo segment 29 SMON: mark undo segment 29 as available SMON: about to recover undo segment 29 SMON: mark undo segment 29 as available SMON: about to recover undo segment 29 SMON: mark undo segment 29 as available
这个信息高速我们,目前29号回滚段出现问题,SMON不断尝试恢复该回滚段,但是始终无法恢复正常。这个恢复尝试占用了大量的CPU资源。继续搜索这个损坏出现的原因,在alert文件的前面部分,找到如下线索:
Thu Aug 31 19:13:23 2006 Shutting down instance (abort)
在abort关闭数据库之后,重新启动数据库即出现以上错误。
询问用户当时的情况是,数据库运行极其缓慢,用户请求得不到响应,就强行关闭了数据库,这次Abort关闭最终导致了回滚段损坏。在此提醒大家,使用abort方式关闭数据库,是具有相当风险的,具体执行时应该相当谨慎。
进一步的,我们检查数据库的当前状态,查询v$session_wait视图,发现数据库当前存在大量等待:
SQL> select sid,event from v$session_wait where event not like 'SQL%'; SID EVENT ---------- ---------------------------------------------------------------- 。。。。。。。。。。。。。。 35 enqueue 92 enqueue 95 enqueue 97 enqueue 207 enqueue 212 enqueue 223 enqueue 224 enqueue 220 enqueue 210 enqueue 203 enqueue 99 enqueue 89 enqueue 3 log file parallel write 5 log buffer space 237 log buffer space 22 log buffer space 238 log file sync 14 wait for a undo record 34 wait for a undo record 246 wait for a undo record 28 row cache lock 110 row cache lock 243 row cache lock 33 rows selected.
其中存在大量队列竞争,我们进而检查v$lock视图:
SQL> select * from v$lock where type<>'MR'; ADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK ---------------- ----- -- ---------- ----- ------ ------- ------- ---------- .................... 00000400C72A1CE0 5 TX 116 338 6 0 0 0 00000400C70CF990 5 TM 15 0 3 0 0 0 00000400C5672A50 5 TX 1900602 120 6 0 188 1 00000400C5672720 5 PS 1 4 4 0 188 0 00000400C5672698 5 PS 1 3 4 0 188 0 00000400C5672610 5 PS 1 2 4 0 188 0 00000400C5670328 5 TS 2 1 3 0 1444 0 00000400C56702A0 5 PS 1 1 4 0 188 0 00000400C5670190 5 PS 1 0 4 0 188 0 00000400C5670108 5 TS 18 1 3 0 365 0 ...................... 00000400C74B31A0 35 TX 3342351 26 6 0 189 0 00000400C70CEF10 35 TM 111452 0 3 0 188 0 00000400C70CEE50 35 TM 111449 0 3 0 188 0 00000400C5672AF0 35 TX 1900602 120 0 4 188 0 00000400C70CF5D0 89 TM 112649 0 3 0 41 0 00000400C5673040 89 TX 1900602 120 0 6 41 0 00000400C70CF210 92 TM 112649 0 3 0 74 0 00000400C5672D98 92 TX 1900602 120 0 6 74 0 00000400C70CF750 95 TM 112649 0 3 0 29 0 00000400C5673150 95 TX 1900602 120 0 6 29 0 00000400C70CF8D0 97 TM 112649 0 3 0 20 0 00000400C5673260 97 TX 1900602 120 0 6 20 0 00000400C70CF390 99 TM 112649 0 3 0 52 0 00000400C5672EA8 99 TX 1900602 120 0 6 52 0 00000400C70CF690 203 TM 112649 0 3 0 30 0 00000400C56730C8 203 TX 1900602 120 0 6 30 0 00000400C70CF2D0 207 TM 112649 0 3 0 59 0 00000400C5672E20 207 TX 1900602 120 0 6 59 0 00000400C70CF450 210 TM 112649 0 3 0 50 0 00000400C5672F30 210 TX 1900602 120 0 6 50 0 00000400C70CF510 212 TM 112649 0 3 0 42 0 00000400C5672FB8 212 TX 1900602 120 0 6 42 0 00000400C70CF090 220 TM 112649 0 3 0 128 0 00000400C5672C00 220 TX 1900602 120 0 6 128 0 00000400C70CF810 223 TM 112649 0 3 0 20 0 00000400C56731D8 223 TX 1900602 120 0 6 20 0 00000400C70CEFD0 224 TM 112649 0 3 0 120 0 00000400C5672C88 224 TX 1900602 120 0 6 120 0 48 rows selected.
从以上输出中注意到,大量Session的请求都被阻塞,而阻塞这些Session的进程正是SMON进程(sid=5)。
那么问题已经基本清晰,由于abort关闭数据库,导致回滚段损坏,回滚段不断尝试修复回滚段,回滚事务,这一事务有导致其他事务的锁等待,从而整个数据库异常缓慢,无法响应。
这种情况下,最好的方式是通过备份进行恢复,使整个数据库恢复正常。但是通过备份进行恢复可能存在的问题有:
恢复时间可能很长,业务影响过大。
如果执行不完全恢复,则可能导致部分数据库丢失。
….
由于用户环境不允许进行停机长时间的恢复,所以只能作为特殊情况进行处理。在初始化参数文件中设置隐含参数:
_offline_rollback_segments= _SYSSMU29$ _corrupted_rollback_segments= _SYSSMU29$
将29号回滚段标记为损坏并脱机,然后重新启动数据库,此时观察alert文件中的错误信息:
Fri Sep 1 07:56:18 2006 SMON: about to recover undo segment 29 SMON: mark undo segment 29 as needs recovery Fri Sep 1 08:01:26 2006 SMON: about to recover undo segment 29 SMON: mark undo segment 29 as needs recovery Fri Sep 1 08:06:33 2006 SMON: about to recover undo segment 29 SMON: mark undo segment 29 as needs recovery
此时数据库仍然尝试去恢复29号回滚段,由于已经强制将该回滚段Offline,此时可以将损坏的回滚段删除:
SQL> drop rollback segment "_SYSSMU29$"; Rollback segment dropped.
此时继续观察alert文件,之前的错误不再出现
Fri Sep 1 10:27:11 2006 drop rollback segment "_SYSSMU29$" Fri Sep 1 10:27:11 2006 Completed: drop rollback segment "_SYSSMU29$"
至此数据库基本恢复了正常运行,但是需要注意的是,由于我们强制删除了一个回滚段,那么一定会损失部分事务,导致数据库不一致。
如果损失的事务是用户事务,那么通过检查和修正数据错误就可以解决;如果损失的事务是系统事务,那么可能会出现ORA-600错误,就需要DBA介入进行进一步的故障处理和问题解决。