Oracle 恢复案例

第五章 其它恢复案例

5.1 损坏联机日志的恢复方法


5.1.1 损坏非当前联机日志

大家都清楚,联机日志分为当前联机日志和非当前联机日志,非当前联机日志的损坏是比较简单的,一般通过clear命令就可以解决问题。


1
、启动数据库,遇到ORA-00312 or ORA-00313错误,如

ORA-00313: open failed for members of log group 1 of thread 1

ORA-00312: online log 1 thread 1: 'D:/Oracle/ORADATA/TEST/REDO01.LOG'

从这里我们知道日志组1的数据文件损坏了

从报警文件可以看到更详细的信息

2 查看V$log视图

SQL> select group#,sequence#,archived,status from v$log;

 

    GROUP#      SEQUENCE# ARCHIVED STATUS

---------- ---------- -------- ----------------

         1          1     YES      INACTIVE

         2          2     YES      INACTIVE

         3          3     NO       CURRENT

可以知道,该组是非当前状态,而且已经归档。

3 CLEAR命令重建该日志文件

SQL>alter database clear logfile group 1;

如果是该日志组还没有归档,则需要用

SQL>alter database clear unarchived logfile group 1;

4 打开数据库,重新备份数据库

SQL>alter database open;

 

说明:

1、如果损坏的是非当前的联机日志文件,一般只需要clear就可以重建该日志文件,但是如果该数据库处于归档状态但该日志还没有归档,就需要强行clear

2、建议clear,特别是强行clear后作一次数据库的全备份;

3、此方法适用于归档与非归档数据库。

 

5.1.2 损坏当前联机日志

 

归档模式下当前日志的损坏有两种情况,

一、是数据库是正常关闭,日志文件中没有未决的事务需要实例恢复,当前日志组的损 坏就可以直接用alter database clear unarchived logfile group n来重建。

二、是日志组中有活动的事务,数据库需要媒体恢复,日志组需要用来同步,有两种补救办法:

A.  最好的办法就是通过不完全恢复,可以保证数据库的一致性,但是这种办法要求在归档方式下,并且有可用的备份

B.  通过强制性恢复,但是可能导致数据库不一致。


下面分别用来说明这两种恢复方法:

 

5.1.2.1 通过备份来恢复

1 打开数据库,会遇到一个类似的错误

ORA-00313: open failed for members of log group 1 of thread 1

ORA-00312: online log 1 thread 1: 'D:/Oracle/ORADATA/TEST/REDO01.LOG'

ORA-27041: unable to open file

OSD-04002: unable to open file

O/S-Error: (OS 2) 系统找不到指定的文件

 

2 查看V$log,发现是当前日志

SQL> select group#,sequence#,archived,status from v$log;

 

    GROUP#      SEQUENCE# ARCHIVED STATUS

--------- ---------- -------- ----------------

         1          1     NO       CURRENT

         2          2     YES      INACTIVE

         3          3     YES      INACTIVE

 

3 发现clear不成功

SQL> alter database clear unarchived logfile group 1;

alter database clear unarchived logfile group 1

*

ERROR at line 1:

ORA-01624: log 1 needed for crash recovery of thread 1

ORA-00312: online log 1 thread 1: 'D:/Oracle/ORADATA/TEST/REDO01.LOG'

 

4 拷贝有效的数据库的全备份,并不完全恢复数据库:

可以采用获取最近的SCN的办法用until scn恢复或用until cnacel恢复

recover database until cancel

先选择auto,尽量恢复可以利用的归档日志,然后重新

recover database until cancel

这次输入cancel,完成不完全恢复,也就是说恢复两次。

如:

SQL> recover database until cancel;

Auto

……

SQL> recover database until cancel;

Cancel;

5 利用alter database open resetlogs打开数据库.

 

说明:

  1、这种办法恢复的数据库是一致的不完全恢复,会丢失当前联机日志中的事务数据;

  2、这种方法适合于归档数据库并且有可用的数据库全备份;

  3、恢复成功之后,记得再做一次数据库的全备份;

  4、建议联机日志文件一定要实现镜相在不同的磁盘上,避免这种情况的发生,因为任何数据的丢失对于生产来说都是不容许的。

 

5.1.2.2 如果没有备份,进行强制性恢复

1 打开数据库,会遇到一个类似的错误

ORA-00313: open failed for members of log group 1 of thread 1

ORA-00312: online log 1 thread 1: 'D:/Oracle/ORADATA/TEST/REDO01.LOG'

ORA-27041: unable to open file

OSD-04002: unable to open file

O/S-Error: (OS 2) 系统找不到指定的文件

 

2 查看V$log,发现是当前日志

SQL> select group#,sequence#,archived,status from v$log;

 

    GROUP#  SEQUENCE# ARCHIVED STATUS

---------- ---------- -------- ----------------

         1          1 NO       CURRENT

         2          2 YES      INACTIVE

         3          3 YES      INACTIVE

 

3 发现clear不成功

SQL> alter database clear unarchived logfile group 1;

alter database clear unarchived logfile group 1

*

ERROR at line 1:

ORA-01624: log 1 needed for crash recovery of thread 1

ORA-00312: online log 1 thread 1: 'D:/Oracle/ORADATA/TEST/REDO01.LOG'

 

4 把数据库down

    SQL>shutdown immediate

 

5 init<sid>.ora中加入如下参数

     _allow_resetlogs_corruption=TRUE

 

6 重新启动数据库,利用until cancel恢复

    SQL>recover database until cancel;

    Cancel

如果出错,不再理会,发出

SQL>alter database open resetlogs;

 

7 数据库被打开后,马上执行一个full export

 

8 shutdown数据库,去掉_all_resetlogs_corrupt参数

 

9 重建库

 

10import并完成恢复

 

11、建议执行一下ANALYZE TABLE ...VALIDATE STRUCTURE CASCADE;


说明:

1、该恢复方法是没有办法之后的恢复方法,一般情况下建议不要采用,因为该方法可能导致数据库的不一致;

2、该方法也丢失数据,但是丢失的数据没有上一种方法的数据多,主要是未写入数据文件的已提交或未提交数据;

3、建议成功后严格执行以上的711步,完成数据库的检查与分析;

4、全部完成后做一次数据库的全备份;

5、建议联机日志文件一定要实现镜相在不同的磁盘上,避免这种情况的发生,因为任何数据的丢失对于生产来说都是不容许的。


5.2 损坏控制文件的恢复方法

 

5.2.1 损坏单个控制文件

损坏单个控制文件是比较容易恢复的,因为一般的数据库系统,控制文件都不是一个,而且所有的控制文件都互为镜相,只要拷贝一个好的控制文件替换坏的控制文件就可以了。

 

1 控制文件损坏,最典型的就是启动数据库出错,不能mount数据库

SQL>startup

ORA-00205: error in identifying controlfile, check alert log for more info

查看报警日志文件,有如下信息

alter database  mount

Mon May 26 11:59:52 2003

ORA-00202: controlfile: 'D:/Oracle/oradata/chen/control01.ctl'

ORA-27041: unable to open file

OSD-04002: unable to open file

O/S-Error: (OS 2) 系统找不到指定的文件。

 

2 停止数据库:

SQL>shutdown immediate

 

3 拷贝一个好的控制文件替换坏的控制文件或修改init.ora中的控制文件参数,取消这个坏的控制文件。

 

4 重新启动数据:

SQL>startup

 

说明:

1、损失单个控制文件是比较简单的,因为数据库中所有的控制文件都是镜相的,只需要简单的

拷贝一个好的就可以了;

2、建议镜相控制文件在不同的磁盘上;

3、建议多做控制文件的备份,长期保留一份由alter database backup control file to trace产生的控制文件的文本备份。


5.2.2
损坏全部控制文件

 

损坏多个控制文件,或者人为的删除了所有的控制文件,通过控制文件的复制已经不能解决问题,这个时候需要重新建立控制文件。

 

同时注意,alter database backup control file to trace可以产生一个控制文件的文本备份。


以下是详细重新创建控制文件的步骤:

1 关闭数据库

SQL>shutdown immediate;

2 删除所有控制文件,模拟控制文件的丢失

 

3 启动数据库,出现错误,并不能启动到mount

SQL>startup

ORA-00205: error in identifying controlfile, check alert log for more info

查看报警日志文件,有如下信息

alter database  mount

Mon May 26 11:53:15 2003

ORA-00202: controlfile: 'D:/Oracle/oradata/chen/control01.ctl'

ORA-27041: unable to open file

OSD-04002: unable to open file

O/S-Error: (OS 2) 系统找不到指定的文件。

 

4 关闭数据库

SQL>shutdown immediate;

 

5 internalsys下运行如下创建控制文件的脚本,注意完整列出联机日志或数据文件的路径,或修改由alter database backup control file to trace备份控制文件时产生的脚本,去掉多余的注释即可。


STARTUP NOMOUNT

CREATE CONTROLFILE REUSE DATABASE "TEST" NORESETLOGS NOARCHIVELOG

         MAXLOGFILES 32

         MAXLOGMEMBERS 2

         MAXDATAFILES 254

         MAXINSTANCES 1

         MAXLOGHISTORY 226

LOGFILE

    GROUP 1 'D:/Oracle/ORADATA/TEST/REDO01.LOG'  SIZE 1M,

    GROUP 2 'D:/Oracle/ORADATA/TEST/REDO02.LOG'  SIZE 1M,

    GROUP 3 'D:/Oracle/ORADATA/TEST/REDO03.LOG'  SIZE 1M

DATAFILE

    'D:/Oracle/ORADATA/TEST/SYSTEM01.DBF',

    'D:/Oracle/ORADATA/TEST/RBS01.DBF',

    'D:/Oracle/ORADATA/TEST/USERS01.DBF',

    'D:/Oracle/ORADATA/TEST/TEMP01.DBF',

    'D:/Oracle/ORADATA/TEST/TOOLS01.DBF',

    'D:/Oracle/ORADATA/TEST/INDX01.DBF'

CHARACTER SET ZHS16GBK;

 

-- Recovery is required if any of the datafiles are restored backups,

-- or if the last shutdown was not normal or immediate.

RECOVER DATABASE

--if the last shutdown was not normal or immediate

--noarchive

-- RECOVER DATABASE UNTIL CANCELUSING BACKUP CONTROLFILE

--archive

-- RECOVER DATABASE USING BACKUP CONTROLFILE UNTIL CANCEL

-- Database can now be opened normally.

ALTER DATABASE OPEN;

--if recover database until cancel

--ALTER DATABASE OPEN RESETLOGS;

6 如果没有错误,数据库将启动到open状态下。

 

说明:

1、重建控制文件用于恢复全部数据文件的损坏,需要注意其书写的正确性,保证包含了所有的数据文件与联机日志;

2、经常有这样一种情况,因为一个磁盘损坏,我们不能再恢复(store)数据文件到这个磁盘,因此在store到另外一个盘的时候,我们就必须重新创建控制文件,用于识别这个新的数据文件,这里也可以用这种方法用于恢复。

 

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后重新执行23步后跳至第六步。如果值大于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、不管上上面那种恢复方法都是正常性的恢复,不会引起数据的不一致或错误。

 

5.3.2数据库关闭,但是数据文件中没有活动事务

 

这种情况下最简单的方法就是offline drop掉这个坏了的或者丢失的数据文件,然后以restricted模式打开数据库然后删除并且重建包含损坏文件的回滚段表空间。

 

具体步骤如下:

1 确定数据库是正常的关闭的。方法是可以去查看alert文件,到最后看是否有如下信息:

"alter database dismount

Completed: alter database dismount"

如果有的话,就证明数据库是正常关闭的,否则就不能用这个方法去恢复。

2 修改init参数文件,移去ROLLBACK_SEGMENTS中包含的损坏数据文件的回滚段表空间的回滚段,如果你不能确定哪些回滚段是坏的,简单的方法是你可以注释掉整个ROLLBACK_SEGMENTS

3 restricted模式去mount数据库。

STARTUP RESTRICT MOUNT

4 offline drop掉那个坏的数据文件

ALTER DATABASE DATAFILE '<full_path_file_name>' OFFLINE DROP;

5 打开数据库

ALTER DATABASE OPEN

如果你看到如下信息"Statement processed",则跳到第7步,如果你看到ORA-604, ORA-376, and ORA-1110的错误信息,继续第6步。

6、   正常的关闭数据库,然后在init文件中注释掉ROLLBACK_SEGMENTS,并加入隐含参数

_corrupted_rollback_segments = ( <rollback1>,...., <rollbackN> )

然后以restricted模式打开数据库

STARTUP RESTRICT

7 删除掉那个包含损坏文件的回滚段表空间。

DROP TABLESPACE <tablespace_name> INCLUDING CONTENTS;

8 重建回滚段表空间,记得创建后要把回滚段都online

9 重新使数据库对所有用户可用。

ALTER SYSTEM DISABLE RESTRICTED SESSION;

10、然后正常关闭数据库,修改init文件,如果开始只是注释掉了ROLLBACK_SEGMENTS的,就去掉注释即可,如果加了隐含参数的,注释掉它,并在ROLLBACK_SEGMENTS加入所有的回滚段。

11、正常启动数据库:

Startup

说明

1、这种方法的前提条件是数据库是正常关闭(不是abort)可用;

2、这种方法是正常方法,不会引起数据错误。

 

5.3.3 数据库关闭,数据文件中有活动事务,没有可用备份。

一般造成这种原因的情况是采用了shutdown abort或其它原因异常关机(如断电)导致的。

 

1、开启一个事务

SQL> set transaction use rollback segment rbs0;

Transaction set.

SQL> insert into test (a) values (1);

1 row created.

 

2、异常关闭

SQL> shutdown abort;

Oracle instance shut down.

 

3、删除rbs的一个数据文件

C:>del D:/Oracle/oradata/chen/rbs01.

 

4、修改INIT<sid>.ora :

rollback_segments=(system)

添加_corrupted_rollback_segments=(rbs0,rbs1,rbs2……)

 

5SQL>Startup mount

 

6SQL>alter database datafile 'd:/Oracle/oradata/t8i/rbs01.dbf' offline drop;

数据库已更改。

 

7SQL>recover database

完成介质恢复。

 

8SQL>alter database open ;

数据库已更改。

 

9SQL>select * from v$rollname;

 

         USN    NAME

----   -------

         0      SYSTEM

 

10SQL>select segment_name,tablespace_name,status
FROM dba_rollback_segs;


SEGMENT_NAME   TABLESPACE_NAME       STATUS

----------- ------ ------------------------------------

SYSTEM         SYSTEM                ONLINE

RBS0           RBS                   NEEDS RECOVERY

RBS1           RBS                   NEEDS RECOVERY

RBS2           RBS                   NEEDS RECOVERY

 

11SQL>drop rollback segment rbs0;

重算段已丢弃。

    SQL>drop rollback segment rbs1;

重算段已丢弃。

    SQL>drop rollback segment rbs2;

重算段已丢弃。

 

12SQL>select segment_name,tablespace_name,status
FROM dba_rollback_segs;


SEGMENT_NAME TABLESPACE_NAME   STATUS

-------------------------------------

SYSTEM        SYSTEM            ONLINE

 

13SQL>drop tablespace rbs including contents;

表空间已丢弃。

 

14、重建新的回滚表空间及回滚段,并联机。

 

15SQL>shutdown abort

 

16、再修改INIT<sid>.ora

rollback_segments=(rbs0,rbs1,rbs2)

_corrupted_rollback_segments=(rbs0,rbs1,rbs2)去掉。

 

17SQL>startup

 

说明:

1、这种办法是万不得以的时候使用的方法,如果有备份,都建议从备份上进行恢复;

2、这种方法恢复的数据库,可能会引起数据库的数据错误;

3、恢复成功以后,建议exp/imp数据,并重新分析检查数据库。


5.3.4
数据库关闭,数据文件中有活动事务,从备份恢复

1、从一个有效的备份中恢复损坏的数据文件。

2mount数据库。

3、执行以下查询:

SELECT FILE#, NAME, STATUS FROM V$DATAFILE;

如果发现要恢复的文件是offline状态的话,要先online它:

ALTER DATABASE DATAFILE '<full_path_file_name>' ONLINE;

4、执行以下查询

SELECT V1.GROUP#, MEMBER, SEQUENCE#, FIRST_CHANGE#

FROM V$LOG V1, V$LOGFILE V2

WHERE V1.GROUP# = V2.GROUP# ;

这个将列出redlog文件所代表的sequencefirst change numbers

 

5、如果数据库是非归档情况下,执行以下查询:

SELECT FILE#, CHANGE# FROM V$RECOVER_FILE;

如果CHANGE#大于最小的redolog文件的FIRST_CHANGE#,则数据文件可以被恢复,记得在应用日志的时候要把所有redolog文件全部应用一遍。


如果CHANGE#小于最小的redolog文件的FIRST_CHANGE#,则数据文件就不可以被恢复了,这时候你要从一个有效的全备份中去恢复数据库了,如果没有全备份的话,那你就只能把数据库强制打开到一个不一致的状态去exp出数据,然后重新建库导入数据,因为这种方式的恢复Oracle是不推荐用户自己做的,所以这里我就不详细说明了。

 

6、恢复数据文件:

RECOVER DATAFILE '<full_path_file_name>'

7、确信你应用了所有的redolog文件,直至出现提示信息"Media recovery complete"

8、打开数据库。


说明:

1、这种方法要求在归档有备份的方式下进行,而且是建议方式;

2、这种方法不会导致数据库的错误。


5.4 损坏临时数据文件的恢复方法

 

临时数据文件的恢复是比较简单的,因为临时文件中不涉及到其它的有用的数据,所以可以删除后重建。


1、关闭数据库:

SQL>shutdown immediate

2、删除临时数据文件,模拟媒体失败;

 

3、启动数据库,检测到文件错误;

 

4、脱机该数据文件:

SQL>alter database datafile '文件名全名' offline drop;

 

5、打开数据库

SQL>alter database open

 

6、删除该临时表空间

SQL>drop tablespace temp(或其它临时表空间名称);

 

7、重新创建该表空间,并重新分配给用户。


说明:

1、临时数据文件是非重要文件,不保存永久数据,可以随时删除重建,不影响数据库的数据安全;

2、如果重新建立以后,别忘了重新分配给用户。


常见恢复误区

1可以不需要备份,只有归档就能进行数据库的向前的恢复


:这个在Oracle 9i以前起码是不可能的,在别的数据库我也没有听说过,不完全恢复的主要思路是利用不完全点之前的备份,加上归档日志,恢复到不完全恢复点,9i中出现了一个flashback的特性,这个特性的使用,也是有很多局限的。


2进行不完全恢复只需要拷贝一个需要恢复的备份数据文件

:不完全恢复需要拷贝所有的数据文件,最好包括临时数据文件在内,否则需要另外的处理,如果有一个数据文件的SCN大于不完全恢复点,那么这个恢复都将是失败的。


3
使用RMAN目录与目标数据库在同一数据库能很好进行数据库的恢复

:使用恢复目录与目标数据库在同一个数据库中,将存在很大的恢复局限,如该数据库的系统数据文件的损害,数据库根本不能open,那么RMAN也就无法连接恢复目录,也就不存在恢复了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值