oracle的备份与恢复(3)

手工不完全恢复

1.不完全恢复的特点

1) 必须停机,在 mount 下运行重做日志。

2) 必须以 sysdba 身份连接进行不完全恢复。

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

2.不完全恢复(Incomplete recover)适用环境

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

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

3)当误删除了表空间时(有控制文件备份)

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

3. 不完全恢复的基本类型:

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

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

3)基于 cancel (until cancel): 使整个数据库恢复到归档日志或当前日志的

断点前

4)基于误删除表空间(使用备份的 controlfile): 使整个数据库恢复到误删除表空间前

4. 使用不完全恢复的几个步骤

1)利用 logminer 工具,找出在某个时间点所作的 DDL 或 DML 误操作(包括:时间点、scn 、sql 语

句)

2)做当前数据库的最新全备。

3)使用还原点前的备份还原数据文件,

4)运用日志恢复所有数据文件,前滚至需要的时间点前停止。

5)使用 resetlogs 方式打开数据库。

5. 不完全恢复范例:

范例 1: 恢复过去某个时间点误删除的 table

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

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

SQL> conn scott/scott
SQL> select * from t1;
        ID
----------
         1
         2

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/prod/arch_1_782662700_129.log
/u01/disk1/prod/arch_1_782662700_130.log
/u01/disk1/prod/arch_1_782662700_131.log
/u01/disk1/prod/arch_1_782662700_132.log
/u01/disk1/prod/arch_1_782662700_133.log //drop table t1 purge 这个动作的日志条目记录在此归档日志里了。
/u01/disk1/prod/arch_1_782662700_134.log
/u01/disk1/prod/arch_1_782662700_135.log
 
116 rows selected

3)通过 logmr 找出误操作的 ddl 命令的 timestamp 或 san

SQL> show parameter utl
NAME                                  TYPE        VALUE
------------------------------------ ----------- ------------------------------
create_stored_outlines           string
utl_file_dir                          string      /home/oracle/logmnr
SQL> execute 
dbms_logmnr_d.build('dict.ora','/home/oracle/logmnr',dbms_logmnr_d.store_in_flat
_file); 
 
SQL> execute 
dbms_logmnr.add_logfile(logfilename=>'/u01/disk1/prod/arch_1_782662700_133.log',
options=>dbms_logmnr.new);
 
SQL> execute 
dbms_logmnr.add_logfile(logfilename=>'/u01/disk1/prod/arch_1_782662700_134.log',
options=>dbms_logmnr.addfile); 
  
SQL> execute 
dbms_logmnr.start_logmnr(dictfilename=>'/home/oracle/logmnr/dict.ora',options=>d
bms_logmnr.ddl_dict_tracking);
 
SQL> select username,scn,to_char(timestamp,'yyyy-mm-dd hh24:mi:ss'),sql_redo 
from v$logmnr_contents WHERE lower(sql_redo) like 'drop table%';
 
USERNAME                              SCN  TO_CHAR(TIMESTAMP,'YYYY-MM-DDH 
SQL_REDO
------------------------------ ---------- ------------------------------ 
-----------------------------------------------
SCOTT                              1918000  2012-08-01 17:28:29           
drop table t1 purge;
SQL> execute dbms_logmnr.end_logmnr;

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

SQL> alter system checkpoint; //控制文件更新

SQL> shutdown abort

[oracle@prod ~]$ cd /u01/oradata/prod

[oracle@prod ~]$ rm *.dbf

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

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

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

17:31:43 SQL> startup

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

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

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

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

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

auto

Log applied.

Media recovery complete.

7)resetlogs 方式打开数据库

SQL> alter database open resetlogs;

8)验证

SQL> select * from scott.t1;

ID

----------

1

2

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

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

在手工基于 scn 的不完全恢复的命令子句是 change 关键字,与基于时间的不完全恢复类似,其命令格式只

要将 recover 命令换成下面即可:

SQL> recover database until change 1918000;

这里不多赘述了。

5.3 基于 cancel 的不完全恢复(略)

5.4 基于 backup controlfile 的恢复

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

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

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

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

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

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

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

然后会有如下选项:

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

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

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

filename: 输入当前文件的路径和文件名,是指 current log 的恢复

CANCEL: 退出。

考点:

1)在控制文件丢失后进行恢复将会将会出现停机时间,因此不能联机执行控制文件的恢复。
2)使用 backup controlfile 子句的恢复数据库之后,一律要使用 alter database open resetlogs 打开数据库。

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

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

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

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

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/prod/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/prod/con.bak1';

3) 模拟 abcd01.dbf 损坏,查证访问数据文件报错。

[oracle@prod ~]$rm /u01/oradata/prod/abcd01.dbf //数据库 open 状态,

删除 abcd01.dbf 数据文件

SQL> alter system flush buffer_cache; //db

buffer 清空

SQL> conn / as sysdba //换个 session 查看 a1 表

物理读失败

SQL> select * from scott.a1;

4)关闭数据库

SQL> shutdown abort;

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

[oracle@prod prod]$ cd /u01/oradata/prod

[oracle@prod prod]$ rm *.ctl

[oracle@prod prod]$ rm *.dbf

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

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

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

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

SQL> startup
SQL> col name for a50;
SQL> select file#,checkpoint_change#,name from v$datafile;
     FILE# CHECKPOINT_CHANGE# NAME
---------- ------------------ --------------------------------------------------
         1            6676574 /u01/oradata/prod/system01.dbf
         2            6676574 /u01/oradata/prod/sysaux01.dbf
         3            6676601 /u01/oradata/prod/abcd01.dbf
         4            6676574 /u01/oradata/prod/user01.dbf
         5            6676574 /u01/oradata/prod/example01.dbf
         6            6676574 /u01/oradata/prod/test01.dbf
         7            6676574 /u01/oradata/prod/undotbs01.dbf
SQL> select file#,checkpoint_change#  from v$datafile_header;
     FILE# CHECKPOINT_CHANGE#
---------- ------------------
         1            6676343
         2            6676343
         3                  0
         4            6676343
         5            6676343
         6            6676343
         7            6676343

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

的数据备份的 scn 比控制文件 scn 还老。

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

SQL> recover database using backup controlfile;

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

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

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

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

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

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

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

SQL> recover database using backup controlfile;

......

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

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

Linux Error: 2: No such file or directory

Additional information: 3

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

//注意: 对于这个例子来说,一定要看清提示:如果提示的不是归档的日志(是当前日志),则要直接要输入 filename 不能输入 auto,否则 open 时会失败。

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

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

/u01/oradata/prod/redo03.log //把龙头(当前日志)给它。

已应用的日志。

完成介质恢复。

7)resetlogs 打开数据库

SQL> alter database open resetlogs;

8)验证

SQL> select * from scott.a1;

NAME

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

a

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

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

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

分析:整个恢复过程中 datafile 结构有了变化,变化发生在备份控制文件之后,新增了表空间 prod,控制

文件备份里没有此表空间记录,但日志里有。

1)环境

SQL> drop tablespace abcd including contents and datafiles;
SQL> alter database backup controlfile to '/u01/oradata/prod/con.bak2';
SQL> create tablespace abcd datafile '/u01/oradata/prod/abcd01.dbf' size 5m; 
SQL> create table scott.r1 (id int) tablespace abcd ;
SQL> insert into scott.r1 values(1);
SQL> commit;
SQL> select * from v$tablespace;
       TS# NAME                                               INC BIG FLA ENC
---------- -------------------------------------------------- --- --- --- ---
         0 SYSTEM                                             YES NO  YES
         1 SYSAUX                                             YES NO  YES
        14 ABCD                                                YES NO  YES
         4 USERS                                                YES NO  YES
         6 EXAMPLE                                            YES NO  YES
         8 TEST                                                   YES NO  YES
         3 TEMP                                                 NO  NO  YES
         2 UNDOTBS1                                       YES NO  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@prod prod]rm abcd01.dbf

SQL>alter system flush buffer_cache;

SQL>conn / as sysdba

SQL>select * from scott.r1;

3) 关闭数据库

SQL>shutdown abort

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

[oracle@prod prod]$ cd /u01/oradata/prod

[oracle@prod prod]$ rm *.ctl

[oracle@prod prod]$ rm *.dbf

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

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

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

[oracle@prod prod]$ 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/prod/system01.dbf
         2            6677122 /u01/oradata/prod/sysaux01.dbf
         4            6677122 /u01/oradata/prod/user01.dbf
         5            6677122 /u01/oradata/prod/example01.dbf
         6            6677122 /u01/oradata/prod/test01.dbf
         7            6677122 /u01/oradata/prod/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/prod/arch_1_804846837_4.log

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

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

auto

......

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

/u01/oradata/prod/redo01.log

......

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

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

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

ORA-01112: 未启动介质恢复

SQL> select file#,checkpoint_change#,name from v$datafile;
     FILE# CHECKPOINT_CHANGE# NAME
---------- ------------------ --------------------------------------------------
         1            6678002 /u01/oradata/prod/system01.dbf
         2            6678002 /u01/oradata/prod/sysaux01.dbf
         3            6677999 /u01/oracle/dbs/UNNAMED00003 //这是从日志回写
到控制文件中的名字,需要重命名
         4            6678002 /u01/oradata/prod/user01.dbf
         5            6678002 /u01/oradata/prod/example01.dbf
         6            6678002 /u01/oradata/prod/test01.dbf
         7            6678002 /u01/oradata/prod/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/prod/abcd01.dbf';
//上面的命令一石二鸟,自动完成了两个动作 1)加了一个数据文件 abcd01.dbf,2)重命名控制文件
UNNAMED00003 为 abcd01.dbf
SQL> select file#,checkpoint_change#,name from v$datafile;
     FILE# CHECKPOINT_CHANGE# NAME
---------- ------------------ --------------------------------------------------
         1            6678002 /u01/oradata/prod/system01.dbf
         2            6678002 /u01/oradata/prod/sysaux01.dbf
         3            6677999 /u01/oradata/prod/abcd01.dbf
         4            6678002 /u01/oradata/prod/user01.dbf
         5            6678002 /u01/oradata/prod/example01.dbf
         6            6678002 /u01/oradata/prod/test01.dbf
         7            6678002 /u01/oradata/prod/undotbs01.dbf
SQL> recover database using backup controlfile;

8)resetlogs 打开数据库

SQL> alter database open resetlogs;

9)验证

SQL> select * from scott.r1;
        ID
----------
         1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

早起晚睡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值