Chinaunix首页 | 论坛 | 博客
  • 博客访问: 561723
  • 博文数量: 302
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 4765
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-15 23:10
文章分类

全部博文(302)

文章存档

2011年(1)

2008年(301)

我的朋友

分类: 服务器与存储

2008-07-21 23:57:26

起个题目:关于数据文件恢复

这是一个假设的例子(给出的条件并不一定都须用上):
 
周二晚,有一个 联机拷贝os文件的脚本,依次执行下面伪代码
backup controlfile;


set feedback,head,echo,term... off

spool filename;

select 'alter tablespace '||tablespace_name || 'begin backup;' from dba_tablespaces;
select 'cp ' ||name || '......' from v$datafile;
select 'alter tablespace '||tablespace_name || 'end backup;' from dba_tablespaces;
spool off
then run the script;


但是不幸,在备份过程中失败,只有部分文件备份成功,但是dba并不知道。
周三,dba新加了一个数据文件
周四,控制文件损坏,dba手工创建了控制文件
周五,磁盘损坏,恰好丢失了所有控制文件和新加的这个数据文件(该数据文件中有非常重要的期望恢复的数据)其他数据文件都。检查备份,结果发现原来的备份只有部分数据文件拷贝成功然后备份意外终止不再继续执行下面任何代码。很不幸,备份出来的文件也在这个磁盘上坏了。
 
在这种情况下,请问,该数据文件是否能恢复,如能,请描述过程,如不能,请阐述理由。


__________________

blog: 人生就是如此
当前流窜地: 人间天堂
明天又是新的一天
柔嘉维则@life.oracle.eng


呵呵,难得biti这么好兴致,偶也有兴趣试了试,可以恢复出来的。

首先排除biti的一些迷惑条件,基本上知道有一个控制文件的备份,没有任何数据文件的备份,增加的数据文件是在备份控制文件之后,其他的信息都没用。

我的测试过程如下,是把这个丢失的数据文件做为一个普通的数据文件来测试的,但是如果是system文件,恐怕就会复杂很多了,不多说了,看测试过程。
之前先备份了所有的控制文件

然后增加一个数据文件:

C:\Documents and Settings\coolyl>sqlplus "/as sysdba"

SQL*Plus: Release 9.2.0.6.0 - Production on 星期三 3月 2 01:15:58 2005

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

连接到:

Oracle9i Enterprise Edition Release 9.2.0.6.0 - Production

With the Partitioning, OLAP and Oracle Data Mining options

JServer Release 9.2.0.6.0 - Production

SQL> alter tablespace quest add datafile 'D:\ORACLE\ORADATA\ORCL\QUEST1.DBF' size 10M;

表空间已更改。
然后关闭数据库,删除所有控制文件,模拟周四的过程,虽然这步对于是否能恢复没什么意义,呵呵,还是按照biti说的做吧。重要的一点是这步做重建控制文件一定是noresetlogs的。

SQL> shutdown immediate

数据库已经关闭。

已经卸载数据库。

ORACLE 例程已经关闭。

SQL> startup

ORACLE 例程已经启动。

Total System Global Area 97591104 bytes

Fixed Size 454464 bytes

Variable Size 71303168 bytes

Database Buffers 25165824 bytes

Redo Buffers 667648 bytes

ORA-00205: ?????????????????????

SQL> shutdown immediate

ORA-01507: ??????

ORACLE 例程已经关闭。

SQL> startup nomount

ORACLE 例程已经启动。

Total System Global Area 97591104 bytes

Fixed Size 454464 bytes

Variable Size 71303168 bytes

Database Buffers 25165824 bytes

Redo Buffers 667648 bytes

SQL> @d:\control.sql

CREATE CONTROLFILE REUSE DATABASE "ORCL" NORESETLOGS ARCHIVELOG

MAXLOGFILES 5

MAXLOGMEMBERS 3

MAXDATAFILES 100

MAXINSTANCES 1

MAXLOGHISTORY 453

LOGFILE

GROUP 1 'D:\ORACLE\ORADATA\ORCL\REDO01.LOG' SIZE 1M,

GROUP 2 'D:\ORACLE\ORADATA\ORCL\REDO02.LOG' SIZE 1M,

GROUP 3 'D:\ORACLE\ORADATA\ORCL\REDO03.LOG' SIZE 1M

DATAFILE

'D:\ORACLE\ORADATA\ORCL\SYSTEM01.DBF',

'D:\ORACLE\ORADATA\ORCL\UNDOTBS01.DBF',

'D:\ORACLE\ORADATA\ORCL\QUEST.DBF',

'D:\ORACLE\ORADATA\ORCL\QUEST1.DBF'

CHARACTER SET ZHS16GBK

;

RECOVER DATABASE

ALTER SYSTEM ARCHIVE LOG ALL;

ALTER DATABASE OPEN;

控制文件已创建

ORA-00283: ??????????

ORA-00264: ?????

系统已更改。

数据库已更改。

SQL> select open_mode from v$database;

OPEN_MODE

----------

READ WRITE

SQL> select name from v$datafile;

NAME

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

D:\ORACLE\ORADATA\ORCL\SYSTEM01.DBF

D:\ORACLE\ORADATA\ORCL\UNDOTBS01.DBF

D:\ORACLE\ORADATA\ORCL\QUEST.DBF

D:\ORACLE\ORADATA\ORCL\QUEST1.DBF
然后关闭数据库,删除所有控制文件和quest01.dbf文件,模拟周五的情况。

SQL> shutdown immediate

数据库已经关闭。

已经卸载数据库。

ORACLE 例程已经关闭。

SQL> startup

ORACLE 例程已经启动。

Total System Global Area 97591104 bytes

Fixed Size 454464 bytes

Variable Size 71303168 bytes

Database Buffers 25165824 bytes

Redo Buffers 667648 bytes

ORA-00205: ?????????????????????

SQL> shutdown immediate

ORA-01507: ??????

ORACLE 例程已经关闭。
拷贝最开始备份的所有控制文件回来,启动数据库到mount状态:

SQL> startup mount

ORACLE 例程已经启动。

Total System Global Area 97591104 bytes

Fixed Size 454464 bytes

Variable Size 71303168 bytes

Database Buffers 25165824 bytes

Redo Buffers 667648 bytes

ORA-01991: ???????'D:\oracle\ora92\DATABASE\PWDorcl.ORA'

SQL> shutdown immediate

ORA-01109: ??????

已经卸载数据库。

ORACLE 例程已经关闭。

SQL> host

Microsoft Windows XP [Version 5.1.2600]

(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\coolyl>del D:\oracle\ora92\DATABASE\PWDorcl.ORA

C:\Documents and Settings\coolyl>orapwd file=D:\oracle\ora92\DATABASE\PWDorcl.ORA password=oracle entries=10

C:\Documents and Settings\coolyl>exit

SQL> startup mount

ORACLE 例程已经启动。

Total System Global Area 97591104 bytes

Fixed Size 454464 bytes

Variable Size 71303168 bytes

Database Buffers 25165824 bytes

Redo Buffers 667648 bytes

数据库装载完毕。

此时如果做alter database create datafile as这个命令肯定是不行的,因为此时的控制文件还没有quest01.dbf这个文件的信息:

SQL> alter database create datafile 'D:\ORACLE\ORADATA\ORCL\QUEST1.DBF' as 'D:\O

RACLE\ORADATA\ORCL\QUEST1.DBF' reuse;

alter database create datafile 'D:\ORACLE\ORADATA\ORCL\QUEST1.DBF' as 'D:\ORACLE

\ORADATA\ORCL\QUEST1.DBF' reuse

*

ERROR 位于第 1 行:

ORA-01516: 不存在的日志文件, 数据文件或临时文件

'D:\ORACLE\ORADATA\ORCL\QUEST1.DBF'


必须先使用旧的控制文件进行不完全恢复到控制文件中包含了quest01.dbf文件先:

SQL> recover database using backup controlfile until cancel;

ORA-00279: 更改 1229498 (在 03/02/2005 01:13:44 生成) 对于线程 1 是必需的

ORA-00289: 建议: D:\ORACLE\ORA92\RDBMS\ARC00516.001

ORA-00280: 更改 1229498 对于线程 1 是按序列 # 516 进行的

指定日志: {=suggested | filename | AUTO | CANCEL}

ORA-00283: 恢复会话因错误而取消

ORA-01244: 未命名的数据文件由介质恢复添加至控制文件

ORA-01110: 数据文件 4: 'D:\ORACLE\ORADATA\ORCL\QUEST1.DBF'

ORA-01112: 未启动介质恢复
SQL> recover database using backup controlfile until cancel;

ORA-00283: 恢复会话因错误而取消

ORA-01111: 数据文件 4 名称未知 - 请重命名以更正文件

ORA-01110: 数据文件 4: 'D:\ORACLE\ORA92\DATABASE\UNNAMED00004'

ORA-01157: 无法标识/锁定数据文件 4 - 请参阅 DBWR 跟踪文件

ORA-01111: 数据文件 4 名称未知 - 请重命名以更正文件

ORA-01110: 数据文件 4: 'D:\ORACLE\ORA92\DATABASE\UNNAMED00004'
我们看到此时控制文件中已经包含了这个数据文件的信息,但是因为被删除后恢复出来的,所以oracle不知道这个文件的具体名字,给了个奇怪的名字,没关系,我们重新命名一下这个文件:

SQL> alter database create datafile 'D:\ORACLE\ORA92\DATABASE\UNNAMED00004' as '

D:\ORACLE\ORADATA\ORCL\QUEST1.DBF' reuse;

数据库已更改。
这样数据库就存在了quest1.dbf这个文件的信息了,然后我们继续做不完全恢复:

SQL> recover database using backup controlfile until cancel;

ORA-00279: 更改 1229668 (在 03/02/2005 01:16:11 生成) 对于线程 1 是必需的

ORA-00289: 建议: D:\ORACLE\ORA92\RDBMS\ARC00516.001

ORA-00280: 更改 1229668 对于线程 1 是按序列 # 516 进行的

指定日志: {=suggested | filename | AUTO | CANCEL}

ORA-00279: 更改 1229717 (在 03/02/2005 01:18:36 生成) 对于线程 1 是必需的

ORA-00289: 建议: D:\ORACLE\ORA92\RDBMS\ARC00517.001

ORA-00280: 更改 1229717 对于线程 1 是按序列 # 517 进行的

ORA-00278: 此恢复不再需要日志文件 'D:\ORACLE\ORA92\RDBMS\ARC00516.001'

指定日志: {=suggested | filename | AUTO | CANCEL}

ORA-00308: 无法打开存档日志 'D:\ORACLE\ORA92\RDBMS\ARC00517.001'

ORA-27041: 无法打开文件

OSD-04002: 无法打开文件

O/S-Error: (OS 2) The system cannot find the file specified.

ORA-01547: 警告: RECOVER 成功但 OPEN RESETLOGS 将出现如下错误

ORA-01152: 文件 1 没有从完备的旧备份中恢复

ORA-01110: 数据文件 1: 'D:\ORACLE\ORADATA\ORCL\SYSTEM01.DBF'
上面恢复失败,看来'D:\ORACLE\ORA92\RDBMS\ARC00517.001'

还没存在,没关系,当前的所有redolog都在,用这个就行了,重新恢复一次:

SQL> recover database using backup controlfile until cancel;

ORA-00279: 更改 1229717 (在 03/02/2005 01:18:36 生成) 对于线程 1 是必需的

ORA-00289: 建议: D:\ORACLE\ORA92\RDBMS\ARC00517.001

ORA-00280: 更改 1229717 对于线程 1 是按序列 # 517 进行的

指定日志: {=suggested | filename | AUTO | CANCEL}

D:\oracle\oradata\orcl\redo01.log

已应用的日志。

完成介质恢复。

SQL> alter database open resetlogs;

数据库已更改。

SQL> select name from v$datafile;

NAME

--------------------------------------------------------------------------------
D:\ORACLE\ORADATA\ORCL\SYSTEM01.DBF

D:\ORACLE\ORADATA\ORCL\UNDOTBS01.DBF

D:\ORACLE\ORADATA\ORCL\QUEST.DBF

D:\ORACLE\ORADATA\ORCL\QUEST1.DBF
至此,丢失的那个重要的数据文件恢复完毕。

总结一下整个的恢复过程:

biti给了很多迷惑的信息,让人觉得看似没法恢复似的。但是了解了备份恢复的机制,就很少排除这些迷惑信息了,因为没有备份,要恢复这个数据文件,首先保证在控制文件中有这个新增加的数据文件的信息,加上所有的归档日志在就可以了,biti给出的条件满足恢复的前提,因此理论上就应该是可以恢复的。

因为开始备份的控制文件无这个新增加的数据文件的信息,因此恢复就得分为两步了,先恢复到控制文件中存在了这个新增的数据文件的时候,因为是利用归档恢复出来的,控制文件中关于这个数据文件的信息不一定准确,需要我们去手工来重命名为正确的数据文件,然后剩下的恢复就跟普通的恢复一样了。
欢迎biti指正和补充,^_^。
BTW:困了,睡觉去了,biti你害我这么晚还没睡,去杭州就看我怎么宰你吧,嘿嘿
代码:--------------------------------------------------------------------------------

--先备份控制文件,模拟周二晚上的备份,因为反正后面所有备份都丢失了,所以作不作热备没有关系

SQL> alter database backup controlfile to 'd:\temp\control01.ctl';
Database altered.
--创建新的数据文件,模拟周三,并插入一些数据,看看后面是不是没有数据丢失

SQL> create tablespace ts_fun datafile 'c:\oracle\oradata\orcl\ts_fun01.dbf' siz

e 2m;
Tablespace created.
SQL> create table t (n number) tablespace ts_fun;
Table created.
SQL> insert into t values(1);
1 row created.
SQL> commit;
Commit complete.
SQL> shutdown immediate;

Database closed.

Database dismounted.

ORACLE instance shut down.

SQL> startup

ORACLE instance started.
Total System Global Area  177282760 bytes

Fixed Size                   454344 bytes

Variable Size             150994944 bytes

Database Buffers           25165824 bytes

Redo Buffers                 667648 bytes

Database mounted.

Database opened.
--模拟周四控制文件损坏,shutdown abort以后操作系统端删除控制文件,然后把备份的控制文件copy回来

SQL> shutdown abort;

ORACLE instance shut down.
--此时已经用备份的控制文件mount数据库了

SQL>starup mount;
--这一步是关键,恢复到的时间是紧跟在添加了新的数据文件之后的一个时间点,

--如何得到这个时间点?呵呵,很简单,无论是create tablespace还是add datafile都会记录在alertlog中,自然都有时间点的

--(善用alertlog,免除logminer的麻烦)。

--恢复时,系统要求ARC00311.001,查看归档路径发现最大只到310,所以要求的redo信息是存在在online redolog中的,给出online redolog名称就行

SQL> recover database using backup controlfile until time '2005-3-2 03:45:31';

ORA-00279: change 5289982431 generated at 03/02/2005 03:42:55 needed for thread

1

ORA-00289: suggestion : C:ORACLEORADATAORCLARCHIVEARC00311.001

ORA-00280: change 5289982431 for thread 1 is in sequence #311


Specify log: {=suggested | filename | AUTO | CANCEL}

c:oracleoradataorclREDO02.LOG

ORA-00283: recovery session canceled due to errors

ORA-01244: unnamed datafile(s) added to controlfile by media recovery

ORA-01110: data file 8: 'C:\ORACLE\ORADATA\ORCL\TS_FUN01.DBF'


ORA-01112: media recovery not started
--同样是关键,此处直接用datafile number,就不用去管怪怪的由于恢复而生成的文件名了.

--ilenumber从哪儿知道?呵呵,上面一步的操作信息中就有了。

SQL> alter database create datafile 8 as 'C:\ORACLE\ORADATA\ORCL\TS_FUN01.DBF';
Database altered.
--数据文件回来了,作完全恢复,同样指定online redolog名称

SQL> recover database using backup controlfile;

ORA-00279: change 5289982661 generated at 03/02/2005 03:45:06 needed for thread

1

ORA-00289: suggestion : C:ORACLEORADATAORCLARCHIVEARC00311.001

ORA-00280: change 5289982661 for thread 1 is in sequence #311


Specify log: {=suggested | filename | AUTO | CANCEL}

c:oracleoradataorclREDO02.LOG

Log applied.

Media recovery complete.
SQL> alter database open resetlogs;
Database altered.
--检索数据,发现没有任何数据丢失。

SQL> select * from t;
         N

----------

         1
SQL>
SQL*Plus: Release 9.2.0.5.0 - Production on Wed Mar 2 04:28:33 2005
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
Connected to an idle instance.
SQL> startup nomount

ORACLE instance started.
Total System Global Area  177282760 bytes

Fixed Size                   454344 bytes

Variable Size             150994944 bytes

Database Buffers           25165824 bytes

Redo Buffers                 667648 bytes

SQL> CREATE CONTROLFILE REUSE DATABASE "ORCL" NORESETLOGS  ARCHIVELOG

  2  --  SET STANDBY TO MAXIMIZE PERFORMANCE

  3      MAXLOGFILES 5

  4      MAXLOGMEMBERS 3

  5      MAXDATAFILES 100

  6      MAXINSTANCES 1

  7      MAXLOGHISTORY 226

  8  LOGFILE

  9    GROUP 1 'C:\ORACLE\ORADATA\ORCL\REDO01.LOG'  SIZE 10M,

 10    GROUP 2 'C:\ORACLE\ORADATA\ORCL\REDO02.LOG'  SIZE 10M,

 11    GROUP 3 'C:\ORACLE\ORADATA\ORCL\REDO03.LOG'  SIZE 10M

 12  -- STANDBY LOGFILE

 13  DATAFILE

 14    'C:\ORACLE\ORADATA\ORCL\SYSTEM01.DBF',

 15    'C:\ORACLE\ORADATA\ORCL\UNDOTBS01.DBF',

 16    'C:\ORACLE\ORADATA\ORCL\INDX01.DBF',

 17    'C:\ORACLE\ORADATA\ORCL\TOOLS01.DBF',

 18    'C:\ORACLE\ORADATA\ORCL\USERS01.DBF',

 19    'C:\ORACLE\ORADATA\ORCL\O1_MF_TS_TEST_0ZZF1Z2Y_.DBF',

 20    'C:\ORACLE\ORADATA\ORCL\O1_MF_TS_TEST_0ZZFKG5T_.DBF',

 21    'C:\ORACLE\ORADATA\ORCL\O1_MF_LOGMNRTS_11MH1CJ9_.DBF'

 22  CHARACTER SET ZHS16GBK

 23  ;
Control file created.
SQL> recover database until time '2005-3-2 04:28:05';

ORA-00283: recovery session canceled due to errors

ORA-01244: unnamed datafile(s) added to controlfile by media recovery

ORA-01110: data file 8: 'C:\ORACLE\ORADATA\ORCL\TS_FUN01.DBF'


SQL> alter database create datafile 8 as 'C:\ORACLE\ORADATA\ORCL\TS_FUN01.DBF';
Database altered.
SQL>

SQL> recover database;

Media recovery complete.

SQL> alter database open;
Database altered.
SQL>
阅读(992) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~