5.3 损坏回滚数据文件的恢复方法
回滚段表空间中的一个数据文件丢失或者损坏导致数据库无法识别它,在启动数据库的时候会出现ORA-1157, ORA-1110的错误,或者操作系统级别的错误,例如ORA-7360。在关闭数据库的时候(normal或者immediate)会出现ORA-1116, ORA-1110的错误,或者操作系统级别的错误,例如ORA-7368。
感谢coolyl的辛勤工作,关于回滚段的大部分内容都是摘自他在itpub的文章。
5.3.1 损坏数据文件,但数据库处于Open状态
如果你发现有回滚段的数据文件丢失或者损坏了,而此时的数据库是处于打开的状态下并且在运行,就千万不要关闭数据库了,因为在大多数的情况下打开的时候比关闭的时候好解决问题一些。
一般也是存在有两种情况:
A。是offline丢失或损坏的数据文件,然后从一个备份中恢复,执行介质恢复以保持一致性。但是这种情况要求数据库是归档方式下才可以采用的。
B。是offline那个存在丢失或损坏的数据文件所在的整个回滚段表空间,然后删除整个回滚段表空间并重建,但是你必须要杀掉那些在回滚段中已经激活的用户进程才可以offline的。
通常第一种情况就比较简单实现,但是更多的用户事务将会出错并且回滚。
A的具体步骤:
1。offline丢失或损坏的数据文件
ALTER DATABASE DATAFILE '<full_path_file_name>' OFFLINE;
2。从一个有效的备份中恢复。
3。执行以下查询
SELECT V1.GROUP#, MEMBER, SEQUENCE#
FROM V$LOG V1, V$LOGFILE V2
WHERE V1.GROUP# = V2.GROUP# ;
这个将列出你的所有redolog文件以及它们所代表的sequence numbers。
4。恢复数据文件。
RECOVER DATAFILE '<full_path_file_name>'
5。确信你应用了所有的redolog文件,直至出现提示信息"Media recovery complete"。
6。online那个数据文件。
ALTER DATABASE DATAFILE '<full_path_file_name>' ONLINE;
B的具体步骤:
1。offline存在丢失或损坏的数据文件的回滚段表空间中的所有回滚段。
ALTER ROLLBACK SEGMENT <rollback_segment> OFFLINE;
2。检测当然回滚段的状态。
SELECT SEGMENT_NAME, STATUS FROM DBA_ROLLBACK_SEGS
WHERE TABLESPACE_NAME = '<TABLESPACE_NAME>';
3。删除所有offline的回滚段
DROP ROLLBACK SEGMENT <rollback_segment>;
4。处理那些online状态的回滚段。
重新执行第二步的查询
如果你已经执行过offline操作的回滚段状态仍然是online,则说明这个回滚段内有活动的事务。你要接着查询
SELECT SEGMENT_NAME, XACTS ACTIVE_TX, V.STATUS
FROM V$ROLLSTAT V, DBA_ROLLBACK_SEGS
WHERE TABLESPACE_NAME = '<TABLESPACE_NAME>' AND SEGMENT_ID = USN;
如果没有返回结果,则证明存在丢失或损坏的数据文件的回滚段表空间中的所有回滚段都已经被offline了,然后重新执行第二步,第三步。如果查询有结果返回,则状态应该是"PENDING OFFLINE".接着查看ACTIVE_TX列,如果值为0,则表明此回滚段中已经没有未处理的事务了,很快就会被offline的,然后等它offline后重新执行2,3步后跳至第六步。如果值大于0,则继续到第五步。
5。强制那些包含活动事务的回滚段offline。
活动的事务应该被提交或者回滚,执行下面的查询看看哪些用户占用了回滚段:
SELECT S.SID, S.SERIAL#, S.USERNAME, R.NAME "ROLLBACK"
FROM V$SESSION S, V$TRANSACTION T, V$ROLLNAME R
WHERE R.NAME IN ('<PENDING_ROLLBACK_1>', ... , '<PENDING_ROLLBACK_N>')
AND S.TADDR = T.ADDR AND T.XIDUSN = R.USN;
最好能直接联系到那些user让他们自己去回滚或者提交事务,如果不能做到的话,那就只能强制性的杀掉进程了。
ALTER SYSTEM KILL SESSION '<SID>, <SERIAL#>';
杀掉进程后再过一段时间后回滚段会自动清除那些事务,然后就可以回到第二步继续查询了。
6。删除回滚段。
DROP TABLESPACE <tablespace_name> INCLUDING CONTENTS;
7。重建回滚段并online它们
说明:
1、数据库如果是open状态,就可以直接在open状态下解决问题,没有必要停下数据库,增加down机时间
2、不管上上面那种恢复方法都是正常性的恢复,不会引起数据的不一致或错误。