第四章:手工不完全恢复

一般是数据库启动不起来的,所以是在mount下进行

 

4.1 不完全恢复的特点:     

      1)让整个database 回到过去某个时间点,不能避免数据丢失。

      2)想跳过坏日志而继续恢复所有其他工作是不可能的,前滚没有这个功能(考点)。

      3)必须以sysdba身份连接进行不完全恢复,普通用户或sysoper都不行(考点)。

      4)语句只有recover databaseuntil 这种形式,表示整个数据库回到某个时间点或SCN,而until是指恢复在指定时间点停止,而非到那个指定时间点(考点)。

 

4.2 不完全恢复(Incompleterecover) 适用环境:

       1)在过去的某个时间点重要的数据被破坏。

       2)在做完全恢复时,丢失了归档日志或当前onlineredo log(考点)

       3)当误删除了表空间时(需要旧的控制文件备份)

       4)丢失了所有的控制文件,使用备份的控制文件恢复时  (条件满足时可以完全恢复)     

        

4.3 不完全恢复的基本类型:

      1)基于时间点 (until time):   使整个数据库恢复到过去的一个时间点前  

      2)基于scn (until change):   使整个数据库恢复到过去的某个SCN前

      2)基于cancel (untilcancel):   使整个数据库恢复到归档日志或当前日志的断点前

      3)基于误删除表空间(使用备份的旧控制文件controlfile): 使整个数据库恢复到误删除表空间前

      

4.4 传统的不完全恢复的操作步骤:(效率低) 现在不大用了,但是这种方法最万能。

      1)先通过logmnr 找到误操作的时间点

      2)对现在的database做新全备(所有的数据文件和当前控制文件,数据库要先正常的关闭,然后cp)

      3)还原该时间点前所有的datafile (将所有旧的dbf备份cp过来,recoverdatabase until change scn)

      4)以当前控制文件进入mount状态,对database做recover,前滚,恢复到误操作时间点

      5)打开数据库(alter databaseopen resetlogs),将恢复出来的table做逻辑备份(exp),将表导出来

      6)再正常关闭数据库,然后再将新刚才的全备还原

      7)将导出的表导入database(imp)

      

其实我们现在用的比较多的是,先看一下闪回数据库是否打开了,如果打开了,那么就闪回。如果是在rman下做的备份,那么我们可以就这个表空间做一个不完全恢复,且不用停机(将表空间做一个TSPITP)。

 

4.5   logminer 工具的使用 日志挖掘

     

     对redo log 进行挖掘,找出在某个时间点所作的DDL 或DML 误操作(包括:时间点、scn 、sql语句)

                                                                                            

4.6 不完全恢复范例:

 

范例1:

 

恢复过去某个时间点误操作的table

 

4.6.1 基于时间点的不完全恢复

在这个状态下先在OS下做一个数据文件和控制文件的冷备。如果前面有备份了,就不要做下面的了。

SQL> shutdown immediate

[oracle@timran ~] $cp /u01/oradata/timran11g/*.dbf  /u01/back1 

[oracle@timran ~] $cp /u01/oradata/timran11g/*.ctl  /u01/back1 

SQL> startup

 

1)环境:scott用户在test表空间下有个t1表

 

SQL>conn scott/scott

SQL>create table t1(id int) tablespace test;

SQL>insert into t1 values(1);

SQL>insert into t1 values(2);

SQL>insert into t1 values(3);

SQL>commit;

SQL>select * from t1;

 

        ID

----------

         1

         2

         3

 

2)误删除了t1表,并purge了。

 

SQL>drop table t1 purge;

SQL>select * from v$log;

 

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARCHIVED STATUS          FIRST_CHANGE# FIRST_TIME

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

         1          1        131  52428800          1 YES      INACTIVE               1875893 2012-6-13 1

         2          1        132  52428800          1 YES      INACTIVE               1896385 2012-6-13 1

         3          1       133   52428800          1 NO       CURRENT                1916973 2012-7-18 1 

 

SQL>alter system switch logfile;

SQL>/

SQL>/

 

SQL>select name from v$archived_log;

 

NAME

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

...

/u01/disk1/timran/arch_1_782662700_129.log

/u01/disk1/timran/arch_1_782662700_130.log

/u01/disk1/timran/arch_1_782662700_131.log

/u01/disk1/timran/arch_1_782662700_132.log

/u01/disk1/timran/arch_1_782662700_133.log //drop table t1 purge这个动作的日志条目记录在此归档日志里了。

/u01/disk1/timran/arch_1_782662700_134.log

/u01/disk1/timran/arch_1_782662700_135.log

 

116 rowsselected

 

3)通过logmr 找出误操作的ddl命令的timestamp 或 san    --DDL日志挖掘

 

SQL>show parameter utl

 

NAME                                 TYPE        VALUE

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

create_stored_outlines               string

utl_file_dir                         string      /home/oracle/logmnr

 

如果utl_file_dir没有值,那么我们可以手动添加值,这样将来日志挖掘的内容就会放在这个目录里。

$ mkdir /home/oracle/logmnr

这个初始化参数不是一个动态参数,只能记到spfile

SQL> alter system setutl_file_dir='/home/oracle/logmnr' scope=spfile;

然后需要重启一下数据库

SQL> startup force

 

--下面这句是固定的

SQL>execute dbms_logmnr_d.build('dict.ora','/home/oracle/logmnr',dbms_logmnr_d.store_in_flat_file); 

 

--往里面添加日志,归档日志,当前日志都可以添加。第一个日志要是.new,后面就是.addfile

SQL> executedbms_logmnr.add_logfile(logfilename=>'/u01/disk1/timran/arch_1_782662700_133.log',options=>dbms_logmnr.new);

 

--SQL>executedbms_logmnr.add_logfile(logfilename=>'/u01/disk1/timran/arch_1_782662700_134.log',options=>dbms_logmnr.addfile); 

  

--下面这个也是固定的

SQL>executedbms_logmnr.start_logmnr(dictfilename=>'/home/oracle/logmnr/dict.ora',options=>dbms_logmnr.ddl_dict_tracking);

 

--查看分析结果

SQL>select username,scn,to_char(timestamp,'yyyy-mm-dd hh24:mi:ss'),sql_redo fromv$logmnr_contents WHERE lower(sql_redo) like 'droptable%';

 

USERNAME                  SCNTO_CHAR(TIMESTAMP,'YYYY-MM-DDH SQL_REDO

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

SCOTT                1917250    2012-07-18 16:44:55      drop table test purge;

SCOTT                1917267    2012-07-18 16:45:01      droptable student purge;

SCOTT                1918000    2012-08-0117:28:29      drop table t1 purge;

 

--释放内存

SQL>execute dbms_logmnr.end_logmnr;

 

4) 关闭数据库,删除所有dbf,准备做不完全恢复

 

SQL>shutdown immediate 或者shutdown abort

 

删之前确保都已经做了备份了。

[oracle@timran~]$ cd /u01/oradata/timran11g

[oracle@timran~]$ rm *.dbf

 

5)还原所有备份的数据文件

 

[oracle@timran~]$ cp /u01/back1/*.dbf ./

 

6)根据log miner提供的信息,做基于时间点的不完全恢复

 

17:31:43SQL> startup

ORACLEinstance started.

 

TotalSystem Global Area  285212672 bytes

FixedSize                  1218968 bytes

VariableSize              75499112 bytes

DatabaseBuffers          201326592 bytes

RedoBuffers                7168000 bytes

Databasemounted.

ORA-01113:file 1 needs media recovery

ORA-01110:data file 1: '/u01/oradata/timran11g/system01.dbf'

这是因为我们用的旧的数据文件头scn,与现在的控制文件scn不一样。

 

17:33:07SQL> recover database until time '2012-08-01 17:28:29';

或者使用scn号,recoverdatabase until change1918000;

 

ORA-00279:change 1917581 generated at 07/18/2012 16:46:34 needed for thread 1

ORA-00289:suggestion : /u01/disk1/timran/arch_1_782662700_133.log

ORA-00280:change 1917581 for thread 1 is in sequence #133

这是因为我们前滚到这一点,需要使用归档日志,所以它建议你使用哪个归档日志。对于归档日志,我们可以使用auto;对于当前在线日志,可能就得指定一个filename了。

 

17:33:17Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

auto

 

Logapplied.

Mediarecovery complete.

 

7)resetlogs方式打开数据库

SQL>alter database open resetlogs;

 

8)验证

 

SQL>select * from scott.t1;

 

        ID

----------

         1

         2

         3

9)看看在resetlogs后,日志sequence重置了。

SQL>select * from v$log;

 

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARCHIVED STATUS          FIRST_CHANGE# FIRST_TIME

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

         1          1          0  52428800          1 YES      UNUSED                       0 

         2          1          0  52428800          1 YES      UNUSED                       0 

         3          1          1  52428800          1 NO       CURRENT                1918000 2012-8-1 17

 

4.6.2 基于SCN的不完全恢复(略)

 

在手工基于scn的不完全恢复的命令子句是change关键字,与基于时间的不完全恢复类似,其命令格式只要将recover命令换成下面即可:

 

SQL>recover database until change 1918000;  

 

这里不多赘述了。                                                                                   

 

4.6.3 基于cancel的不完全恢复

在这个状态下先在OS下做一个数据文件和控制文件的冷备。如果前面有备份了,就不要做下面的了。

SQL> shutdown immediate

[oracle@timran ~] $cp /u01/oradata/timran11g/*.dbf  /u01/back1 

[oracle@timran ~] $cp /u01/oradata/timran11g/*.ctl  /u01/back1 

SQL> startup

 

范例2:在做完全恢复时,丢失了部分归档日志

 

1)模拟环境

 

SQL>select * from t1;

 

        ID

----------

         1

         2

         3

 

SQL>select * from v$log;

 

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARCHIVED STATUS           FIRST_CHANGE#FIRST_TIME

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

    1         1          0   52428800          1 YES      UNUSED                 0

    2         1          0   52428800          1 YES      UNUSED                0

    3         1          1   52428800          1 NO       CURRENT       1918000 2012-8-1 17

 

SQL>insert into t1 values (111);

SQL>commit;

 

SQL>alter system switch logfile;

SQL>/

SQL>/

 

SQL>select * from v$log;

 

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARCHIVED STATUS           FIRST_CHANGE# FIRST_TIME

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

     1         1          2   52428800         1 YES      INACTIVE         1918829 2012-8-1 17

  2          1          3  52428800          1 YES     ACTIVE           1918831 2012-8-1 17

  3          1          4  52428800          1 NO      CURRENT        1918838 2012-8-1 17

 

SQL>insert into t1 values (444);

SQL>commit;

 

SQL>alter system switch logfile;

SQL>/

SQL>/

 

SQL>select * from v$log;

 

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARCHIVED STATUS           FIRST_CHANGE# FIRST_TIME

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

   1         1          5   52428800          1 YES     INACTIVE          1918829 2012-8-1 17

2          1          6  52428800          1 YES     ACTIVE            1918831 2012-8-1 17

   3         1          7   52428800         1 NO       CURRENT        1918838 2012-8-1 17

 

SQL>insert into t1 values (777);

SQL>commit;

SQL>select * from t1;

 

        ID

----------

         1

         2

         3 

       111          //这个动作的日志条目记录在sequence 1里

       444          //这个动作的日志条目记录在sequence 4里

       777          //这个动作的日志条目记录在sequence 7里

 

2)模拟数据文件介质损坏,并需要恢复的归档日志有断点

 

SQL>shutdown abort

 

[oracle@timran~]$ cd /u01/oradata/timran11g

[oracle@timran~]$ rm user01.dbf        假设users 表空间的datafile损坏

 

3)再模拟某归档日志损坏

 

[oracle@timran~]$ cd /u01/disk1/timran

[oracle@timran~]$ ll

 

总计359672

 

-rw-r-----1 oracle oinstall     1024 08-01 16:52arch_1_782662700_139.log

-rw-r-----1 oracle oinstall 46894080 08-01 17:07 arch_1_782662700_140.log

-rw-r-----1 oracle oinstall   608768 08-01 17:48arch_1_790191207_1.log

-rw-r-----1 oracle oinstall     1024 08-01 17:48arch_1_790191207_2.log

-rw-r-----1 oracle oinstall     6144 08-01 17:48arch_1_790191207_3.log

-rw-r-----1 oracle oinstall    49664 08-01 17:49arch_1_790191207_4.log

-rw-r-----1 oracle oinstall     1024 08-01 17:49arch_1_790191207_5.log

-rw-r-----1 oracle oinstall    11264 08-01 17:49arch_1_790191207_6.log

-rw-r-----1 oracle oinstall     1536 08-01 17:49arch_1_790191207_7.log

 

[oracle@timran~]$ mv arch_1_790191207_4.log arch_1_790191207_4.delete

 

[oracle@timran~]$ ll

 

-rw-r-----1 oracle oinstall     1024 08-01 16:52arch_1_782662700_139.log

-rw-r-----1 oracle oinstall 46894080 08-01 17:07 arch_1_782662700_140.log

-rw-r-----1 oracle oinstall   608768 08-01 17:48arch_1_790191207_1.log

-rw-r-----1 oracle oinstall     1024 08-01 17:48arch_1_790191207_2.log

-rw-r-----1 oracle oinstall     6144 08-01 17:48arch_1_790191207_3.log

-rw-r-----1 oracle oinstall    49664 08-01 17:49arch_1_790191207_4.delete //日志不连续了,假设在sequence 4断掉了

-rw-r-----1 oracle oinstall     1024 08-01 17:49arch_1_790191207_5.log

-rw-r-----1 oracle oinstall    11264 08-01 17:49arch_1_790191207_6.log

-rw-r-----1 oracle oinstall     1536 08-01 17:49arch_1_790191207_7.log

 

4)尝试对某数据文件的完全恢复

 

SQL>startup

 

ORACLEinstance started.

TotalSystem Global Area  285212672 bytes

FixedSize                  1218968 bytes

VariableSize              75499112 bytes

DatabaseBuffers          201326592 bytes

RedoBuffers                7168000 bytes

Databasemounted.

ORA-01157:cannot identify/lock data file 4 - see DBWR trace file

ORA-01110:data file 4: '/u01/oradata/timran11g/users01.dbf'

 

SQL>select file#,error from v$recover_file;                                                                                   

 

     FILE# ERROR

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

         4 FILE NOT FOUND

 

[oracle@timran~]$cp /u01/back1/users01.dbf /u01/oradata/timran11g/users01.dbf //还原单个数据文件,企图基于datafile的完全恢复

 

06:09:07SQL> recover datafile 4;

 

有如下报错:

......

......

ORA-00308:cannot open archived log '/u01/disk1/timran/arch_1_790191207_4.log'

ORA-27037:unable to obtain file status

LinuxError: 2: No such file or directory

Additionalinformation: 3

 

//完全恢复失败,因为缺少归档日志:(/u01/disk1/timran/arch_1_790191207_4.log),只能做基于cancel的不完全恢复。

 

5)使用备份还原所有的datafile

 

[oracle@timran~]$ cd /u01/oradata/timran11g

[oracle@timran~]$ rm *.dbf

[oracle@timran~]$ cp /u01/back1/*.dbf ./

 

6)进行基于cancel的不完全恢复

 

SQL>recover database until cancel;

 

ORA-00279:change 1918785 generated at 08/01/2012 17:48:41 needed for thread 1

ORA-00289:suggestion : /u01/disk1/timran/arch_1_790191207_4.log

ORA-00280:change 1918785 for thread 1 is in sequence #4

 

17:56:15Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

auto

ORA-00308:cannot open archived log '/u01/disk1/timran/arch_1_790191207_4.log'

ORA-27037:unable to obtain file status

LinuxError: 2: No such file or directory

Additionalinformation: 3

 

ORA-00308:cannot open archived log '/u01/disk1/timran/arch_1_790191207_4.log'

ORA-27037:unable to obtain file status

LinuxError: 2: No such file or directory

Additionalinformation: 3

 

//选auto不好使,再来一遍选cancel.

 

17:56:21SQL> recover database until cancel;

ORA-00279:change 1918785 generated at 08/01/2012 17:48:41 needed for thread 1

ORA-00289:suggestion : /u01/disk1/timran/arch_1_790191207_4.log

ORA-00280:change 1918785 for thread 1 is in sequence #4

 

17:56:23Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

cancel

Mediarecovery cancelled.

 

//选择cancel ,在丢失的归档日志前终止recover

 

7)resetlogs打开数据库

 

SQL>alter database open resetlogs;

 

8)验证

 

SQL>select * from scott.t1;

 

        ID

----------

         1

         2

         3

       111

4.6.4 基于backupcontrolfile 的恢复(有一定的复杂性)

 

不完全恢复中的复杂性是恢复数据文件的时候使用备份的旧的控制文件。

 

1)为什么会使用备份的控制文件? 实际工作中主要有两种情况:

 

第一种:当前控制文件全部损坏,而数据文件备份,控制文件备份及当前日志处于不同SCN版本,它们之间又增加过表空间(数据文件)。

第二种:当前控制文件没有损坏,但想要恢复被删除的表空间。

 

2)使用备份的控制文件恢复数据库的语法:

//符合条件时,实现完全恢复。走完归档日志,再走当前日志(使用filename来指定当前日志路径和文件名)。(控制文件中没有记录当前日志,只记录归档日志)

recover database using backupcontrolfile; 

//不完全恢复,打开数据库是,需要alter database open resetlogs;

recover database until[time|change] using backup controlfile;

 

注意:[time|change]是可选的,就是说如果条件满足,仍然可以做到完全恢复。

 

然后会有如下选项:

 

Specifylog: {<RET>=suggested | filename | AUTO | CANCEL}

 

此语法的出现是由于控制文件和当前日志中不一致,当前日志的scn总是最新的,而控制文件可能是老的或尚未更新的(shutdwon abort过)。

 

AUTO:  自动使用archivelog前滚恢复,但一般不包括前滚currentlog;

filename:  输入当前日志文件的路径和文件名,是指currentlog的恢复

CANCEL:  退出。

 

考点:

1)在控制文件丢失后进行恢复将会出现停机时间,因此不能联机执行控制文件的恢复。

2)使用backup controlfile子句的不完全恢复数据库之后,一律要使用alter database open resetlogs打开数据库。

当我们没restlogs就会换一个朝代(incarnation),就是RESETLOGS_ID会不一样。

 

范例1:(属于第一种情况)

第一种:当前控制文件全部损坏,而数据文件备份,控制文件备份及当前日志处于不同SCN版本,它们之间又增加过表空间(数据文件)。

 

环境:当前控制文件损坏,数据文件损坏,有全备但之后增加了表空间,并备份了配套的控制文件。

 

模式:所有数据文件备份(老)------(新建表空间abcd)-----备份控制文件(次新)------日志文件(新)

 

分析:新建表空间数据文件损坏, 全备里没有该数据文件的备份及控制文件描述,当前控制文件又丢失,只能用备份的控制文件恢复。

 

在这个状态下先在OS下做一个数据文件和控制文件的冷备。如果前面有备份了,就不要做下面的了。

SQL> shutdown immediate

[oracle@timran ~] $cp /u01/oradata/timran11g/*.dbf  /u01/back1 

[oracle@timran ~] $cp /u01/oradata/timran11g/*.ctl  /u01/back1 

SQL> startup

 

1)环境:

SQL>select * from v$tablespace;

 

       TS# NAME                           INC BIG FLA ENC

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

         0 SYSTEM                         YES NO  YES

         1 SYSAUX                         YES NO  YES

         4 USERS                          YES NO  YES

         6 EXAMPLE                        YES NO  YES

         8 TEST                           YES NO  YES

         2 UNDOTBS1                       YES NO  YES

         3 TEMP                           NO  NO  YES

 

SQL>select * from v$log;

 

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARC STATUS          FIRST_CHANGE# FIRST_TIME

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

         1          1          7  52428800          1 NO  CURRENT                6676574 2013-01-17 13:55:19

         2          1          5  52428800          1 YES INACTIVE               6676549 2013-01-17 13:54:14

         3          1          6  52428800          1 YES INACTIVE               6676562 2013-01-17 13:54:48

 

SQL>create tablespace abcd datafile '/u01/oradata/timran11g/abcd01.dbf' size 5m;

SQL>create table scott.a1 (name char(10)) tablespace abcd;

SQL>insert into scott.a1 values('a');

SQL>commit;

SQL>select * from scott.a1;

 

NAME

----------

a

 

SQL>alter system switch logfile;

这是因为,不切换的话,它是在当前日志里,而控制文件只存归档日志。

 

2)备份控制文件

 

--19:17:55

SQL>alter database backup controlfile to '/u01/oradata/timran11g/con.bak1';

 

SQL>insert into scott.a1 values('b');

SQL>commit;

 

3) 模拟abcd01.dbf损坏

 

[oracle@timran~]$rm /u01/oradata/timran11g/abcd01.dbf  //数据库open状态,删除abcd01.dbf数据文件

 

SQL>alter system flush buffer_cache;     //dbbuffer 清空 

 

SQL>conn / as sysdba       //换个session查看 a1表物理读失败

已连接。

SQL>select * from scott.a1;

select *from scott.a1

                    *

第 1 行出现错误:

ORA-00376:此时无法读取文件 3

ORA-01110:数据文件 3: '/u01/oradata/timran11g/abcd01.dbf'

 

4)关闭数据库

 

SQL>shutdown abort;

 

5)恢复所有数据文件备份,准备做不完全恢复

[oracle@timrantimran11g]$ cd /u01/oradata/timran11g

[oracle@timrantimran11g]$ rm *.ctl

[oracle@timrantimran11g]$ rm *.dbf

[oracle@timrantimran11g]$ cp /u01/back1/*.dbf ./

[oracle@timrantimran11g]$ cp con.bak1 control01.ctl

[oracle@timrantimran11g]$ cp con.bak1 control02.ctl

[oracle@timrantimran11g]$ cp con.bak1 control03.ctl

 

SQL>startup

ORACLE 例程已经启动。

 

TotalSystem Global Area  422670336 bytes

FixedSize                  1300352 bytes

VariableSize             331352192 bytes

DatabaseBuffers           83886080 bytes

RedoBuffers                6131712 bytes

数据库装载完毕。现在没有open,是在mount状态。

ORA-01589:要打开数据库则必须使用 RESETLOGS 或 NORESETLOGS 选项

这是因为目前日志的scn比控制文件和数据文件都新,这里不去管它。

 

SQL>col name for a50;

SQL>select file#,checkpoint_change#,name from v$datafile;

 

     FILE# CHECKPOINT_CHANGE# NAME

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

         1            6676574/u01/oradata/timran11g/system01.dbf

         2            6676574/u01/oradata/timran11g/sysaux01.dbf

         3            6676601/u01/oradata/timran11g/abcd01.dbf

         4            6676574 /u01/oradata/timran11g/user01.dbf

         5            6676574/u01/oradata/timran11g/example01.dbf

         6            6676574/u01/oradata/timran11g/test01.dbf

         7            6676574/u01/oradata/timran11g/undotbs01.dbf

 

SQL>select file#,checkpoint_change#  fromv$datafile_header;

 

     FILE# CHECKPOINT_CHANGE#

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

         1            6676343

         2            6676343

         3                  0

         4            6676343

         5            6676343

         6            6676343

         7            6676343

 

SQL> 

 

可以看出:1)file3 在控制文件里记录是abcd01.dbf,而与之对应的数据文件3是不存在的,2)备份的数据备份的scn比控制文件scn的还老。

 

6)使用备份控制文件恢复

 

SQL>recover database using backup controlfile;

 

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

ORA-01110:数据文件 3: '/u01/oradata/timran11g/abcd01.dbf'

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

ORA-01110:数据文件 3: '/u01/oradata/timran11g/abcd01.dbf'

 

//此错是因为老备份里没有abcd表空间,但只要控制文件里记录了abcd就好办,方法是建一个datafile的空文件,而其中内容可由日志文件recover(前滚)时填补出来。

 

SQL>alter database create datafile '/u01/oradata/timran11g/abcd01.dbf';

 

---再次使用备份控制文件恢复

 

SQL>recover database using backup controlfile;

 

ORA-00279:change 1917582 generated at 07/18/2012 17:46:34 needed for thread 1

ORA-00289:suggestion : /u01/disk1/timran/arch_1_804846835_6.log

ORA-00280:change 1917582 for thread 1 is in sequence #133

 

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

 

//注意:对于这个例子来说,一定要看清提示:如果提示的arch_1_804846837_6.log不是归档的日志。如果是归档日志,则输入auto;如果是当前日志,则输入filename的目录和文件名。否则open时会失败。

 

ORA-00308:无法打开归档日志 '/u01/disk1/timran/arch_1_804846837_9.log'

ORA-27037:无法获得文件状态

LinuxError: 2: No such file or directory

Additionalinformation: 3

 

//archive日志前滚结束了,但当前日志里还有信息需要恢复

 

SQL>recover database using backup controlfile;   //再次做恢复

 

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

/u01/oradata/timran11g/redo03.log

//把蛇头(当前日志)给它,这里有3个redo log,挨个试试。

已应用的日志。

完成介质恢复。

 

7)resetlogs打开数据库

这里其实已经做了一个完全恢复了,但是它是一种不完全恢复的结构,所以打开还得加resetlogs(不完全恢复的结构,恢复了完全数据)

 

SQL>alter database open resetlogs;

 

8)验证

SQL>select * from scott.a1;

 

NAME

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

a

b

 

 

范例2:(属于第一种情况)(略)

第一种:当前控制文件全部损坏,而数据文件备份,控制文件备份及当前日志处于不同SCN版本,它们之间又增加过表空间(数据文件)。

 

在这个状态下先在OS下做一个数据文件和控制文件的冷备。如果前面有备份了,就不要做下面的了。

SQL> shutdown immediate

[oracle@timran ~] $cp /u01/oradata/timran11g/*.dbf  /u01/back1 

[oracle@timran ~] $cp /u01/oradata/timran11g/*.ctl  /u01/back1 

SQL> startup

 

环境:当前控制文件损坏,新建表空间在备份控制文件之后

 

模式:全备(老)-----备份控制文件(次新)-----新建表空间timran------日志文件(新)

 

分析:整个恢复过程中datafile结构有了变化,变化发生在备份控制文件之后,新增了表空间timran,控制文件备份里没有此表空间记录,但日志里有。

 

1)环境

SQL>drop tablespace abcd including contents and datafiles;

SQL>alter database backup controlfile to '/u01/oradata/timran11g/con.bak2';

SQL>create tablespace timran datafile '/u01/oradata/timran11g/timran01.dbf' size5m; 

SQL>create table scott.r1 (id int) tablespace timran ;

SQL>insert into scott.r1 values(1);

SQL>commit;

 

SQL>select * from v$tablespace;

 

       TS# NAME                                               INCBIG FLA ENC

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

         0 SYSTEM                                            YES NO  YES

         1 SYSAUX                                             YES NO  YES

        14 TIMRAN                                            YES NO  YES

         4 USERS                                             YES NO  YES

         6 EXAMPLE                                            YESNO  YES

         8 TEST                                              YES NO  YES

         3 TEMP                                              NO  NO  YES

         2 UNDOTBS1                                           YESNO  YES

 

SQL>select * from scott.r1;

 

        ID

----------

         1

SQL>  select * from v$log;

 

    GROUP#   THREAD#  SEQUENCE#      BYTES   MEMBERS ARC STATUS          FIRST_CHANGE# FIRST_TIME

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

         1          1          1  52428800          1 NO  CURRENT                6677119 2013-01-17 14:08:18

         2          1          0  52428800          1 YES UNUSED                       0

         3          1          0  52428800          1 YES UNUSED                       0

 

2)模拟新建数据文件损坏

 

[oracle@timrantimran11g]rm timran01.dbf

 

SQL>altersystem flush buffer_cache;

SQL>conn/ as sysdba

SQL>select* from scott.r1;

第 1 行出现错误:

ORA-01116:打开数据库文件 3 时出错

ORA-01110:数据文件 3: '/u01/oradata/timran11g/timran01.dbf'

ORA-27041:无法打开文件

LinuxError: 2: No such file or directory

Additionalinformation: 3

 

3) 关闭数据库

 

SQL>shutdownabort

 

4)还原所有数据文件,以老控制文件替换当前控制文件

 

[oracle@timrantimran11g]$ cd /u01/oradata/timran11g

[oracle@timrantimran11g]$ rm *.ctl

[oracle@timrantimran11g]$ rm *.dbf

[oracle@timrantimran11g]$ cp /u01/back1/*.dbf ./

[oracle@timrantimran11g]$ cp con.bak2 control01.ctl

[oracle@timrantimran11g]$ cp con.bak2 control02.ctl

[oracle@timrantimran11g]$ cp con.bak2 control03.ctl

 

5)启动数据库

 

SQL>startup

ORACLE 例程已经启动。

......

数据库装载完毕。

ORA-01589:要打开数据库则必须使用 RESETLOGS 或 NORESETLOGS 选项

 

SQL>select file#,checkpoint_change#,name from v$datafile;

 

     FILE# CHECKPOINT_CHANGE# NAME

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

         1            6677122 /u01/oradata/timran11g/system01.dbf

         2            6677122/u01/oradata/timran11g/sysaux01.dbf

         4            6677122/u01/oradata/timran11g/user01.dbf

         5            6677122/u01/oradata/timran11g/example01.dbf

         6            6677122 /u01/oradata/timran11g/test01.dbf

         7            6677122/u01/oradata/timran11g/undotbs01.dbf

 

SQL>select file#,checkpoint_change# from v$datafile_header;

 

     FILE# CHECKPOINT_CHANGE#

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

         1            6676343

         2            6676343

         4            6676343

         5            6676343

         6            6676343

         7            6676343

 

6)使用备份控制文件恢复数据库

 

SQL>recover database using backup controlfile;

 

ORA-00279:更改 6676343 (在 01/16/2013 14:11:39 生成) 对于线程 1 是必需的

ORA-00289:建议: /u01/disk1/timran/arch_1_804846837_4.log

ORA-00280:更改 6676343 (用于线程 1) 在序列 #4 中

 

 

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

auto

......

//注意:对于这个例子来说,一定要看清提示:如果提示的arch_1_804846837_6.log不是归档的日志。如果是归档日志,则输入auto;如果是当前日志,则输入filename的目录和文件名。否则open时会失败。

 

ORA-00308:无法打开归档日志 '/u01/disk1/timran/arch_1_804847837_9.log'

ORA-27037:无法获得文件状态

LinuxError: 2: No such file or directory

Additionalinformation: 3

 

经查看arch_1_804946837_9.log是当前日志,所以就是输入filename了

 

SQL>recover database using backup controlfile;

 

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

/u01/oradata/timran11g/redo01.log

......

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

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

ORA-01110:数据文件 3: '/u01/oradata/timran11g/timran01.dbf'

 

ORA-01112:未启动介质恢复

 

SQL>select file#,checkpoint_change#,name from v$datafile;

 

     FILE# CHECKPOINT_CHANGE# NAME

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

         1            6678002/u01/oradata/timran11g/system01.dbf

         2            6678002/u01/oradata/timran11g/sysaux01.dbf

         3            6677999/u01/oracle/dbs/UNNAMED00003  //注意这个问题,老控制文件不知道之后的timran01.dbf

         4            6678002 /u01/oradata/timran11g/user01.dbf

         5            6678002/u01/oradata/timran11g/example01.dbf

         6            6678002/u01/oradata/timran11g/test01.dbf

         7            6678002/u01/oradata/timran11g/undotbs01.dbf

 

SQL>select file#,checkpoint_change# from v$datafile_header;

 

     FILE# CHECKPOINT_CHANGE#

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

         1            6678002

         2            6678002

         3                  0

         4            6678002

         5            6678002

         6            6678002

         7            6678002

 

7)重命名数据文件

 

SQL>alter database create datafile '/u01/oracle/dbs/UNNAMED00003' as'/u01/oradata/timran11g/timran01.dbf';

 

//上面的命令一石二鸟,自动完成了两个动作1)加了一个数据文件timran01.dbf,2)重命名控制文件UNNAMED00003为timran01.dbf

 

SQL>select file#,checkpoint_change#,name from v$datafile;

 

     FILE# CHECKPOINT_CHANGE# NAME

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

         1            6678002/u01/oradata/timran11g/system01.dbf

         2            6678002/u01/oradata/timran11g/sysaux01.dbf

         3            6677999/u01/oradata/timran11g/timran01.dbf

         4            6678002/u01/oradata/timran11g/user01.dbf

         5            6678002 /u01/oradata/timran11g/example01.dbf

         6            6678002/u01/oradata/timran11g/test01.dbf

         7            6678002/u01/oradata/timran11g/undotbs01.dbf

 

SQL>recover database using backup controlfile;

ORA-00279:更改 6677999 (在 01/17/2013 14:20:50 生成) 对于线程 1 是必需的

ORA-00289:建议: /u01/disk1/timran/arch_1_804953298_1.log

ORA-00280:更改 6677999 (用于线程 1) 在序列 #1 中

 

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

/u01/oradata/timran11g/redo01.log

已应用的日志。

完成介质恢复。

 

8)resetlogs打开数据库

 

SQL>alter database open resetlogs;

 

9)验证

 

SQL>select * from scott.r1;

 

        ID

----------

         1

         2

         3

 

范例3 恢复被删除的表空间(属于第二种情况)(略)

第二种:当前控制文件没有损坏,但想要恢复被删除的表空间。

 

在这个状态下先在OS下做一个数据文件和控制文件的冷备。如果前面有备份了,就不要做下面的了。

SQL> shutdown immediate

[oracle@timran ~] $cp /u01/oradata/timran11g/*.dbf  /u01/back1 

[oracle@timran ~] $cp /u01/oradata/timran11g/*.ctl  /u01/back1 

SQL> startup

 

环境:用户使用正常操作命令删除了表空间及其数据文件,但之后又希望恢复删除的表空间。全备里有这个表空间的数据文件。

 

模式:全备(老)------控制文件备份(次新)-----删除表空间------所需日志(新)

 

分析:当用户使用droptablesapce xxx including contents and datafiles 这条DDL语句后,数据库的结构发生了变更,涉及了三个地方。

a)控制文件

b)该表空间下的数据文件

c)系统表空间(数据字典)

 

特别提醒的是:当前的控制文件里已经没有该表空间的信息了,所以不能使用当前的控制文件做恢复。恢复这个表空间要满足三个条件:

a)要有该表空间的数据文件备份

b)使用不完全恢复(基于时间点或scn)

c)使用备份的控制文件,而这个控制文件是删除该表空间前的控制文件,不是当前的控制文件。这个非常重要,该控制文件中的内容记录了你需要恢复数据库结构,重要的这个控制文件必须包括有你要恢复的那个表空间的信息。

 

1)背景:

SQL>select * from v$tablespace;

 

       TS# NAME                           INC BIG FLA ENC

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

         0 SYSTEM                         YES NO  YES

         1 SYSAUX                         YES NO  YES

         5 UNDOTBS2                       YES NO  YES

         4 USERS                          YES NO  YES

         6 EXAMPLE                        YES NO YES

         8 TEST                           YES NO  YES

         3 TEMP                           NO  NO  YES

 

SQL>create table scott.t1(id int) tablespace test;

 

SQL>insert into scott.t1 values(1);

 

SQL>commit;

 

SQL>alter system switch logfile;

 

SQL>/

 

SQL>/

 

2)记录下当前scn  (实际情况下,我们通过4.6.1的方法,使用logmnr进行日志挖掘,发现时间点或者scn)

SQL>select current_scn from v$database;

 

CURRENT_SCN

-----------

    7222848

 

3)备份控制文件

SQL>alter database backup controlfile to '/u01/oradata/timran11g/con.bak'

 

4)删除表空间及数据文件

SQL>drop tablespace test including contents and datafiles;

 

SQL>shutdown abort

 

5)删除所有数据文件和当前控制文件,还原所有数据文件及备份的控制文件

[oracle@timrantimran11g]$ rm *.dbf

[oracle@timrantimran11g]$ rm *.ctl

[oracle@timrantimran11g]$ cp /u01/back1/*.dbf ./

[oracle@timrantimran11g]$ cp con.bak control01.ctl

[oracle@timrantimran11g]$ cp con.bak control02.ctl

[oracle@timrantimran11g]$ cp con.bak control03.ctl

 

6)启动数据库后,要做基于时间点(或SCN)的不完全恢复

 

SQL>startup

...

数据库装载完毕。

ORA-01589:要打开数据库则必须使用 RESETLOGS 或 NORESETLOGS 选

 

SQL>recover database until change 7222848 using backup controlfile;

 

ORA-00279:更改 6678999 (在 01/17/2013 17:20:50 生成) 对于线程 1 是必需的

ORA-00289:建议: /u01/disk1/timran/arch_1_804953398_1.log

ORA-00280:更改 6678999 (用于线程 1) 在序列 #1 中

 

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

auto

//注意:对于这个例子来说,一定要看清提示:如果提示的arch_1_804846837_6.log不是归档的日志。如果是归档日志,则输入auto;如果是当前日志,则输入filename的目录和文件名。否则open时会失败。

 

ORA-00308:无法打开归档日志 '/u01/disk1/timran/arch_1_804946837_9.log'

ORA-27037:无法获得文件状态

LinuxError: 2: No such file or directory

Additionalinformation: 3

 

经查看arch_1_804946837_9.log是当前日志,所以就是输入filename了

 

SQL>recover database until change 7222848 using backup controlfile;

 

ORA-00279:更改 6677999 (在 01/17/2013 14:20:50 生成) 对于线程 1 是必需的

ORA-00289:建议: /u01/disk1/timran/arch_1_804953298_1.log

ORA-00280:更改 6677999 (用于线程 1) 在序列 #1 中

 

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

/u01/oradata/timran11g/redo01.log

已应用的日志。

完成介质恢复。

 

 

7)以不完全恢复方式打开数据库

SQL>alter database open resetlogs;

 

8)验证

SQL>select * from scott.t1;

 

        ID

----------

         1 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

victoruu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值