回滚段损坏的恢复

回滚段损坏的恢复:

在abort关闭数据库之后,重新启动数据库即出现以下错误:

SMON: about to recover undo segment 57
SMON: mark undo segment 57 as available
SMON: about to recover undo segment 57
SMON: mark undo segment 57 as available
SMON: about to recover undo segment 57
SMON: mark undo segment 57 as available

这次abort关闭最终导致了回滚段损坏。在此提醒大家,使用abort方式关闭数据库,是具有相当风险的,执行时应该相当谨慎。

进一步查询数据库的当前状态,查询v$session_wait视图,发现数据库当前存在大量等待:

SQL> select sid,event from v$session_wait where event not like 'SQL%';

其中存在大量队列竞争,进行检查v$lock视图:

SQL> select * from v$lock where type <> 'MR';

从输出中注意到,大量Session的请求都被阻塞,而阻塞这些Session的进程正是SMON进行。那么问题已经基本清晰,由于abort关闭数据库,导致回滚段损坏,回滚段不断尝试修复回滚段,回滚事务,这一事务又导致其他事务的锁等待,从而整个数据库异常缓慢,无法响应。

在这样情况下,最好的方式是通过备份进行恢复,使整个数据库恢复正常。但是通过备份进行恢复可能存在的问题有:

·恢复时间可能很长,业务影响过大;
·如果执行不完全恢复,则可能导致部分数据丢失。

由于生产环境一般都不允许进行停机长时间的恢复,所以只能作为特殊情况进行处理。在初始化参数文件中设置隐含参数:

_offline_rollback_segments='_SYSSMU57$'
_corrupted_rollback_segments='_SYSSMU57$'

将57号回滚段标记为损坏并脱机,然后重新启动数据库,此时观察alert文件中的错误信息:

SMON: about to recover undo segment 57
SMON: mark undo segment 57 as available
SMON: about to recover undo segment 57
SMON: mark undo segment 57 as available
SMON: about to recover undo segment 57
SMON: mark undo segment 57 as available

此时数据库仍然尝试去恢复57号回滚段,由于已经强制将该回滚段Offline,此时可以将损坏的回滚段删除:

SQL> drop rollback segment '_SYSSMU57$';
Rollback segment dropped.

此时继续观察alert文件,之前的错误不再出现。

至此数据库基本恢复了正常运行,但是需要注意的是,由于强制删除了一个回滚段,那么一定会损失部分事务,导致数据库不一致。如果损失的事务是用户事务,那么通过检查和修正错误就可以解决;如果损失的事务是系统事务,那么可能会出现ORA-600错误,就需要DBA介入进行进一步的故障处理和问题解决。

- The End -