一。数据库此时处于关闭的状态。这种时候又可以分成两种情况:A。数据库是正常的关闭的(normal或者immediate)这种情况下最简单的方法就是offline drop掉这个坏了的或者丢失的数据文件,然后以restricted模式打开数据库然后删除并且重建包含损坏文件的回滚段表空间。具体步骤如下:1。确定数据库是正常的关闭的。方法是可以去查看alert文件,到最后看是否有如下信息:"alter database dismountCompleted: alter database dismount" 如果有的话,就证明数据库是正常关闭的,否则就不能用这个方法去恢复。2。修改init参数文件,移去ROLLBACK_SEGMENTS中包含的损坏数据文件的回滚段表空间的回滚段,如果你不能确定哪些回滚段是坏的,简单的方法是你可以注释掉整个ROLLBACK_SEGMENTS。3。以restricted模式去mount数据库。STARTUP RESTRICT MOUNT 4。offline drop掉那个坏的数据文件ALTER DATABASE DATAFILE ' ' OFFLINE DROP; 5。打开数据库ALTER DATABASE OPEN 如果你看到如下信息"Statement processed",则跳到第7步,如果你看到ORA-604, ORA-376, and ORA-1110的错误信息,继续第6步。6。正常的关闭数据库,然后在init文件中注释掉ROLLBACK_SEGMENTS,并加入隐含参数_corrupted_rollback_segments = ( ,...., )然后以restricted模式打开数据库STARTUP RESTRICT7。删除掉那个包含损坏文件的回滚段表空间。DROP TABLESPACE INCLUDING CONTENTS;8。重建回滚段表空间,记得创建后要把回滚段都online。9。重新使数据库对所有用户可用。ALTER SYSTEM DISABLE RESTRICTED SESSION;10。然后正常关闭数据库,修改init文件,如果开始只是注释掉了ROLLBACK_SEGMENTS的,就去掉注释即可,如果加了隐含参数的,注释掉它,并在ROLLBACK_SEGMENTS加入所有的回滚段。11。正常启动数据库。startup
B。数据库不是正常关闭的(abort或者突然掉电)这种情况下数据库最后是shutdown abort或者crash了,一般这种情况下回滚段中都包含有激活的事务,因此损坏的数据文件是不能被offline drop掉的,此时就需要从一个有效的备份中恢复并执行介质恢复。如果数据库是非归档方式下的话,那只能在redolog没 有被覆盖的情况下才能成功恢复。具体步骤如下:1。从一个有效的备份中恢复损坏的数据文件。2。mount数据库。3。执行以下查询SELECT FILE#, NAME, STATUS FROM V$DATAFILE;如果发现要恢复的文件是offline状态的话,要先online它ALTER DATABASE DATAFILE ' ' ONLINE; 4。执行以下查询SELECT V1.GROUP#, MEMBER, SEQUENCE#, FIRST_CHANGE# FROM V$LOG V1, V$LOGFILE V2 WHERE V1.GROUP# = V2.GROUP# ;这个将列出redlog文件所代表的sequence和first change numbers。5。如果数据库是非归档情况下,执行以下查询:SELECT FILE#, CHANGE# FROM V$RECOVER_FILE;如果CHANGE#大于最小的redolog文件的FIRST_CHANGE#,则数据文件可以被恢复,记得在应用日志的时候要把所有redolog文件全部应用一遍。如果CHANGE#小于最小的redolog文件的FIRST_CHANGE#,则数据文件就不可以被恢复了,这时候你要从一个有效的全备份中去恢复数据库了,如果没有全备份的话,那你就只能把数据库强制打开到一个不一致的状态去exp出数据,然后重新建库导入数据,因为这种方式的恢复oracle是不推荐用户自己做的,所以这里我就不详细说明了。6。恢复数据文件RECOVER DATAFILE ' '7。确信你应用了所有的redolog文件,直至出现提示信息"Media recovery complete"。8。打开数据库。
二。数据库此时处于打开状态。如果你发现有回滚段的数据文件丢失或者损坏了,而此时的数据库是处于打开的状态下并且在运行,就千万不要关闭数据库了,因为在大多数的情况下打开的时候比关闭的时候好解决问题一些。一般也是存在有两种情况:A。是offline丢失或损坏的数据文件,然后从一个备份中恢复,执行介质恢复以保持一致性。但是这种情况要求数据库是归档方式下才可以采用的。B。是offline那个存在丢失或损坏的数据文件所在的整个回滚段表空间,然后删除整个回滚段表空间并重建,但是你必须要杀掉那些在回滚段中已经激活的用户进程才可以offline的。通常第一种情况就比较简单实现,但是更多的用户事务将会出错并且回滚。A的具体步骤:1。offline丢失或损坏的数据文件ALTER DATABASE DATAFILE ' ' 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 ' '5。确信你应用了所有的redolog文件,直至出现提示信息"Media recovery complete"。6。online那个数据文件。ALTER DATABASE DATAFILE ' ' ONLINE;
B的具体步骤:1。offline存在丢失或损坏的数据文件的回滚段表空间中的所有回滚段。ALTER ROLLBACK SEGMENT OFFLINE; 2。检测当然回滚段的状态。SELECT SEGMENT_NAME, STATUS FROM DBA_ROLLBACK_SEGS WHERE TABLESPACE_NAME = ' '; 3。删除所有offline的回滚段DROP ROLLBACK SEGMENT ; 4。处理那些online状态的回滚段。重新执行第二步的查询如果你已经执行过offline操作的回滚段状态仍然是online,则说明这个回滚段内有活动的事务。你要接着查询SELECT SEGMENT_NAME, XACTS ACTIVE_TX, V.STATUSFROM V$ROLLSTAT V, DBA_ROLLBACK_SEGS WHERE 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 (' ', ... , ' ') AND S.TADDR = T.ADDR AND T.XIDUSN = R.USN; 最好能直接联系到那些user让他们自己去回滚或者提交事务,如果不能做到的话,那就只能强制性的杀掉进程了。ALTER SYSTEM KILL SESSION ' , '; 杀掉进程后再过一段时间后回滚段会自动清除那些事务,然后就可以回到第二步继续查询了。6。删除回滚段。DROP TABLESPACE INCLUDING CONTENTS;7。重建回滚段并online它们
