第六章:手工不完全恢复
1、不完全恢复的特点:让整个database 回到过去某个时间点,不能避免数据丢失
2、不完全恢复(Incomplete recover) 使用环境:
1)过去的某个时间点重要的table被破坏
2)在做完全恢复时,丢失了归档日志或当前 online redo log
3)当误删除了表空间(有备份)
4)丢失了所有的控制文件,用备份的控制文件恢复
3、不完全恢复的类型:
1)基于时间点或 基于change (scn)的不完全恢复:用于恢复过去时间点误操作的table
2)基于cancel :用于归档日志或当前redo log 丢失,不能做完全恢复
3)基于备份的controlfile:用于表空间的恢复
4、不完全恢复的操作步骤:
1)先对现在的database做全备
2)通过logmnr 找到误操作的时间点
3)转储所有的datafile
4)在mount状态下,对database做recover,恢复到过去的时间点
5)将恢复出来的table做逻辑备份
6)再对database做完全恢复
5、logminer 工具的使用
-------对redo log 进行挖掘,找出在某个时间点所作的DDL 或DML 操作(包括:时间点、datablock scn 、sql语句)
1)对DML 分析
04:56:30 SQL> select * from test;
ID
----------
1
2
3
4
5
6
7
8
8 rows selected.
04:56:40 SQL> delete from test;
8 rows deleted.
04:56:48 SQL> commit;
Commit complete.
04:56:50 SQL> insert into test values (111);
1 row created.
04:57:44 SQL> insert into test values (222);
1 row created.
04:57:47 SQL> insert into test values (333);
1 row created.
04:57:49 SQL> commit;
Commit complete.
04:57:51 SQL> select * from test;
ID
----------
111
222
333
04:57:57 SQL>
04:57:01 SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ---------
1 1 4 52428800 1 NO CURRENT 1255988 16-AUG-11
2 1 2 52428800 1 YES INACTIVE 1252334 16-AUG-11
3 1 3 52428800 1 YES INACTIVE 1255986 16-AUG-11
04:57:06 SQL> alter system archive log current;
System altered.
04:57:21 SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ---------
1 1 4 52428800 1 YES ACTIVE 1255988 16-AUG-11
2 1 5 52428800 1 NO CURRENT 1259738 17-AUG-11
3 1 3 52428800 1 YES INACTIVE 1255986 16-AUG-11
04:57:22 SQL>
2)启用logmnr
-------添加database补充日志
04:59:50 SQL> alter database add supplemental log data;
Database altered.
----------查询日志(归档和当前日志)
04:57:21 SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ---------
1 1 4 52428800 1 YES ACTIVE 1255988 16-AUG-11
2 1 5 52428800 1 NO CURRENT 1259738 17-AUG-11
3 1 3 52428800 1 YES INACTIVE 1255986 16-AUG-11
05:00:46 SQL> select member from v$logfile;
MEMBER
------------------------------------------------------------------------------------------------------------------------
/u01/app/oracle/oradata/prod/redo03.log
/u01/app/oracle/oradata/prod/redo02.log
/u01/app/oracle/oradata/prod/redo01.log
05:00:47 SQL> select name from v$archived_log;
NAME
------------------------------------------------------------------------------------------------------------------------
/disk1/arch/prod/arch_38_1_758481658.log
/disk1/arch/prod/arch_39_1_758481658.log
/disk1/arch/prod/arch_40_1_758481658.log
/disk1/arch/prod/arch_41_1_758481658.log
/disk1/arch/prod/arch_42_1_758481658.log
/disk1/arch/prod/arch_43_1_758481658.log
/disk1/arch/prod/arch_44_1_758481658.log
/disk1/arch/prod/arch_45_1_758481658.log
/disk1/arch/prod/arch_46_1_758481658.log
/disk1/arch/prod/arch_2_1_759309442.log
/disk1/arch/prod/arch_3_1_759309442.log
/disk1/arch/prod/arch_4_1_759309442.log
46 rows selected.
----------添加日志,分析
05:00:56 SQL> execute dbms_logmnr.add_logfile(logfilename=>'/disk1/arch/prod/arch_4_1_759309442.log',options=>dbms_logmnr.new);
PL/SQL procedure successfully completed.
05:02:58 SQL> execute dbms_logmnr.add_logfile(logfilename=>'/u01/app/oracle/oradata/prod/redo02.log',options=>dbms_logmnr.addfile);
PL/SQL procedure successfully completed.
----------执行logmnr 分析
05:02:58 SQL>execute dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
PL/SQL procedure successfully completed.
--------查询分析结果
05:23:33 SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
05:06:13 SQL> COL SQL_REDO FOR A50
05:06:21 SQL> R
1* select username,scn,timestamp,sql_redo from v$logmnr_contents where seg_name='TEST'
USERNAME SCN TIMESTAMP SQL_REDO
------------------------------ ---------- ------------------- --------------------------------------------------
1259691 2011-08-17 04:56:50 delete from "SCOTT"."TEST" where "ID" = '4' and RO
WID = 'AAAM3bAACAAAAA/AAA';
1259691 2011-08-17 04:56:50 delete from "SCOTT"."TEST" where "ID" = '5' and RO
WID = 'AAAM3bAACAAAAA/AAB';
1259691 2011-08-17 04:56:50 delete from "SCOTT"."TEST" where "ID" = '6' and RO
WID = 'AAAM3bAACAAAAA/AAC';
1259691 2011-08-17 04:56:50 delete from "SCOTT"."TEST" where "ID" = '7' and RO
WID = 'AAAM3bAACAAAAA/AAD';
1259691 2011-08-17 04:56:50 delete from "SCOTT"."TEST" where "ID" = '8' and RO
WID = 'AAAM3bAACAAAAA/AAE';
05:06:25 SQL>
---------结束日志分析
05:06:25 SQL> execute dbms_logmnr.end_logmnr;
PL/SQL procedure successfully completed.
2)对DDL 操作分析
04:57:57 SQL> drop table test purge;
Table dropped.
05:09:39 SQL> create table test (id int ) tablespace test;
Table created.
05:09:55 SQL> insert into test values (1) ;
1 row created.
05:10:01 SQL> commit;
Commit complete.
---------设置logmnr 参数,存放数据字典文件
[oracle@work prod]$ mkdir /home/oracle/logmnr
05:11:28 SQL> show parameter utl
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
create_stored_outlines string
utl_file_dir string
05:11:31 SQL> alter system set utl_file_dir='/home/oracle/logmnr' scope=spfile;
System altered.
05:11:48 SQL> startup force
ORACLE instance started.
Total System Global Area 314572800 bytes
Fixed Size 1219184 bytes
Variable Size 79693200 bytes
Database Buffers 230686720 bytes
Redo Buffers 2973696 bytes
Database mounted.
Database opened.
05:12:08 SQL> show parameter utl
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
create_stored_outlines string
utl_file_dir string /home/oracle/logmnr
05:12:13 SQL>
---------建立数据字典文件dict.ora
05:12:13 SQL> execute dbms_logmnr_d.build('dict.ora','/home/oracle/logmnr',dbms_logmnr_d.store_in_flat_file);
PL/SQL procedure successfully completed.
---------查看日志信息
05:13:46 SQL> col name for a50
05:13:52 SQL> r
1* select name,sequence# from v$archived_log
NAME SEQUENCE#
-------------------------------------------------- ----------
/disk1/arch/prod/arch_38_1_758481658.log 38
/disk1/arch/prod/arch_39_1_758481658.log 39
/disk1/arch/prod/arch_40_1_758481658.log 40
/disk1/arch/prod/arch_41_1_758481658.log 41
/disk1/arch/prod/arch_42_1_758481658.log 42
/disk1/arch/prod/arch_43_1_758481658.log 43
/disk1/arch/prod/arch_44_1_758481658.log 44
/disk1/arch/prod/arch_45_1_758481658.log 45
/disk1/arch/prod/arch_46_1_758481658.log 46
/disk1/arch/prod/arch_2_1_759309442.log 2
/disk1/arch/prod/arch_3_1_759309442.log 3
/disk1/arch/prod/arch_4_1_759309442.log 4
/disk1/arch/prod/arch_5_1_759309442.log 5
47 rows selected.
05:14:24 SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIM
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ---------
1 1 4 52428800 1 YES INACTIVE 1255988 16-AUG-11
2 1 5 52428800 1 YES INACTIVE 1259738 17-AUG-11
3 1 6 52428800 1 NO CURRENT 1280754 17-AUG-11
05:14:38 SQL> col member for a60
05:14:43 SQL>
1* select group#,member from v$logfile
GROUP# MEMBER
---------- ------------------------------------------------------------
3 /u01/app/oracle/oradata/prod/redo03.log
2 /u01/app/oracle/oradata/prod/redo02.log
1 /u01/app/oracle/oradata/prod/redo01.log
05:14:43 SQL>
-------------添加日志分析
05:14:43 SQL> execute dbms_logmnr.add_logfile(logfilename=>'/u01/app/oracle/oradata/prod/redo03.log',options=>dbms_logmnr.new);
PL/SQL procedure successfully completed.
05:20:59 SQL> execute dbms_logmnr.add_logfile(logfilename=>'/disk1/arch/prod/arch_5_1_759309442.log',options=>dbms_logmnr.addfile);
PL/SQL procedure successfully completed.
------------执行分析
05:16:08 SQL> execute dbms_logmnr.start_logmnr(dictfilename=>'/home/oracle/logmnr/dict.ora',options=>dbms_logmnr.ddl_dict_tracking);
PL/SQL procedure successfully completed.
----------查看分析结果
05:23:33 SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
05:22:55 SQL> select username,scn,timestamp,sql_redo from v$logmnr_contents
05:22:57 2 WHERE USERNAME ='SCOTT' and lower(sql_redo) like '%table%';
USERNAME SCN TIMESTAMP SQL_REDO
------------------------------ ---------- ------------------- --------------------------------------------------
SCOTT 1260664 2011-08-17 05:09:38 drop table test purge;
SCOTT 1260698 2011-08-17 05:09:55 create table test (id int ) tablespace test;
05:23:33 SQL>
05:06:25 SQL> execute dbms_logmnr.end_logmnr;
PL/SQL procedure successfully completed.
不完全恢复案例:
案例1:
------------恢复过去某个时间点误操作的table
1)基于时间点
05:06:13 SQL> COL SQL_REDO FOR A50
05:06:21 SQL> R
1* select username,scn,timestamp,sql_redo from v$logmnr_contents where seg_name='TEST'
USERNAME SCN TIMESTAMP SQL_REDO
------------------------------ ---------- ------------------- --------------------------------------------------
1259691 2011-08-17 04:56:50 delete from "SCOTT"."TEST" where "ID" = '4' and RO
WID = 'AAAM3bAACAAAAA/AAA';
1259691 2011-08-17 04:56:50 delete from "SCOTT"."TEST" where "ID" = '5' and RO
WID = 'AAAM3bAACAAAAA/AAB';
1259691 2011-08-17 04:56:50 delete from "SCOTT"."TEST" where "ID" = '6' and RO
WID = 'AAAM3bAACAAAAA/AAC';
1259691 2011-08-17 04:56:50 delete from "SCOTT"."TEST" where "ID" = '7' and RO
WID = 'AAAM3bAACAAAAA/AAD';
1259691 2011-08-17 04:56:50 delete from "SCOTT"."TEST" where "ID" = '8' and RO
WID = 'AAAM3bAACAAAAA/AAE';
------通过以上logmnr 分析,将test表恢复到delete 之前(time:2011-08-17 04:56:50)
05:33:23 SQL> select * from test;
ID
----------
1
----------test 表现有的数据
----------将database启动到mount ,进行restore 和recover
05:35:38 SQL> conn /as sysdba
Connected.
05:35:46 SQL>
05:35:46 SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
05:36:14 SQL>
05:36:14 SQL> startup mount
ORACLE instance started.
Total System Global Area 314572800 bytes
Fixed Size 1219184 bytes
Variable Size 71304592 bytes
Database Buffers 239075328 bytes
Redo Buffers 2973696 bytes
Database mounted.
05:37:18 SQL>
----------restore 所有的datafile
[oracle@work ~]$ cp /disk1/backup/prod/close_bak/*.dbf /u01/app/oracle/oradata/prod/
---------基于时间的恢复(时间点为logmnr查询的时间)
05:40:13 SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
05:41:05 SQL> recover database until time '2011-08-17 04:56:50';
Media recovery complete.
查看告警日志:
ALTER DATABASE RECOVER database until time '2011-08-17 04:56:50'
Wed Aug 17 05:41:10 2011
Media Recovery Start
Wed Aug 17 05:41:10 2011
Recovery of Online Redo Log: Thread 1 Group 1 Seq 4 Reading mem 0
Mem# 0 errs 0: /u01/app/oracle/oradata/prod/redo01.log
Wed Aug 17 05:41:12 2011
Incomplete Recovery applied until change 1259690
Wed Aug 17 05:41:12 2011
Media Recovery Complete (prod)
Completed: ALTER DATABASE RECOVER database until time '2011-08-17 04:56:50'
Wed Aug 17 05:41:59 2011
-----------验证
05:41:13 SQL> alter database open resetlogs;
Database altered.
05:42:23 SQL> select * from scott.test;
ID
----------
1
2
3
4
5
6
7
8
8 rows selected.
案例2:
-----------恢复过去某个时间点误操作的表
1)基于change (scn)
05:45:41 SQL> truncate table scott.test;
Table truncated.
05:45:52 SQL> insert into scott.test values (11);
1 row created.
05:46:05 SQL> insert into scott.test values (22);
1 row created.
05:46:07 SQL> insert into scott.test values (33);
1 row created.
05:46:09 SQL> commit;
Commit complete.
05:46:11 SQL> select * from scott.test;
ID
----------
11
22
33
05:46:16 SQL>
--------通过logmr 分析出误操作的scn
05:52:30 SQL> select current_scn from v$database; //datablock 记录的scn
CURRENT_SCN
-----------
1260285
------------test 表里的记录
05:52:12 SQL> select * from scott.test;
ID
----------
1
2
3
4
5
6
7
8
8 rows selected
05:52:47 SQL> truncate table scott.test;
Table truncated
05:54:18 SQL> insert into scott.test values (11);
1 row created.
05:54:22 SQL> insert into scott.test values (22);
1 row created.
05:54:24 SQL> insert into scott.test values (33);
1 row created.
05:54:25 SQL> commit;
Commit complete.
05:54:26 SQL>
进行基于change的恢复:
---------在mount状态,进行restore 和recover
-------restore 所有的datafile
05:46:16 SQL> startup force mount
ORACLE instance started.
Total System Global Area 314572800 bytes
Fixed Size 1219184 bytes
Variable Size 71304592 bytes
Database Buffers 239075328 bytes
Redo Buffers 2973696 bytes
Database mounted.
05:48:07 SQL>
[oracle@work ~]$ cp /disk1/backup/prod/close_bak/*.dbf /u01/app/oracle/oradata/prod/
05:55:07 SQL> select file#,checkpoint_change# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 1260061
2 1260061
3 1260061
4 1260061
5 1260061
6 1260061
7 1260061
8 1260061
9 1260061
9 rows selected.
05:57:00 SQL> select file#,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 1258960
2 1258960
3 1258960
4 1258960
5 1258960
6 1258960
7 1258960
8 1258960
9 1258960
9 rows selected.
----------基于change 的recover
05:57:03 SQL> recover database until change 1260285;
ORA-00279: change 1258960 generated at 08/17/2011 04:37:14 needed for thread 1
ORA-00289: suggestion : /disk1/arch/prod/arch_4_1_759309442.log
ORA-00280: change 1258960 for thread 1 is in sequence #4
05:57:33 Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
auto
ORA-00279: change 1259691 generated at 08/17/2011 05:41:59 needed for thread 1
ORA-00289: suggestion : /disk1/arch/prod/arch_1_1_759390119.log
ORA-00280: change 1259691 for thread 1 is in sequence #1
ORA-00279: change 1260023 generated at 08/17/2011 05:44:31 needed for thread 1
ORA-00289: suggestion : /disk1/arch/prod/arch_2_1_759390119.log
ORA-00280: change 1260023 for thread 1 is in sequence #2
ORA-00278: log file '/disk1/arch/prod/arch_1_1_759390119.log' no longer needed for this recovery
ORA-00279: change 1260025 generated at 08/17/2011 05:44:32 needed for thread 1
ORA-00289: suggestion : /disk1/arch/prod/arch_3_1_759390119.log
ORA-00280: change 1260025 for thread 1 is in sequence #3
ORA-00278: log file '/disk1/arch/prod/arch_2_1_759390119.log' no longer needed for this recovery
Log applied.
Media recovery complete.
05:57:44 SQL>
查看告警日志:
ALTER DATABASE RECOVER database until change 1260285
Wed Aug 17 05:57:32 2011
Media Recovery Start
Media Recovery start incarnation depth : 2, target inc# : 5, irscn : 1259690
ORA-279 signalled during: ALTER DATABASE RECOVER database until change 1260285 ...
Wed Aug 17 05:57:38 2011
ALTER DATABASE RECOVER CONTINUE DEFAULT
Wed Aug 17 05:57:38 2011
Media Recovery Log /disk1/arch/prod/arch_4_1_759309442.log
ORA-279 signalled during: ALTER DATABASE RECOVER CONTINUE DEFAULT ...
Wed Aug 17 05:57:40 2011
ALTER DATABASE RECOVER CONTINUE DEFAULT
Wed Aug 17 05:57:40 2011
Media Recovery Log /disk1/arch/prod/arch_1_1_759390119.log
ORA-279 signalled during: ALTER DATABASE RECOVER CONTINUE DEFAULT ...
Wed Aug 17 05:57:40 2011
ALTER DATABASE RECOVER CONTINUE DEFAULT
Wed Aug 17 05:57:40 2011
Media Recovery Log /disk1/arch/prod/arch_2_1_759390119.log
ORA-279 signalled during: ALTER DATABASE RECOVER CONTINUE DEFAULT ...
Wed Aug 17 05:57:41 2011
ALTER DATABASE RECOVER CONTINUE DEFAULT
Wed Aug 17 05:57:41 2011
Media Recovery Log /disk1/arch/prod/arch_3_1_759390119.log
Wed Aug 17 05:57:41 2011
Recovery of Online Redo Log: Thread 1 Group 2 Seq 1 Reading mem 0
Mem# 0 errs 0: /u01/app/oracle/oradata/prod/redo02.log
Wed Aug 17 05:57:41 2011
Recovery of Online Redo Log: Thread 1 Group 1 Seq 2 Reading mem 0
Mem# 0 errs 0: /u01/app/oracle/oradata/prod/redo01.log
Wed Aug 17 05:57:41 2011
Recovery of Online Redo Log: Thread 1 Group 3 Seq 3 Reading mem 0
Mem# 0 errs 0: /u01/app/oracle/oradata/prod/redo03.log
Wed Aug 17 05:57:41 2011
Incomplete Recovery applied until change 1260286
Wed Aug 17 05:57:41 2011
Media Recovery Complete (prod)
Completed: ALTER DATABASE RECOVER CONTINUE DEFAULT
--------验证
05:57:44 SQL> alter database open resetlogs;
Database altered.
05:59:46 SQL> select * from scott.test;
ID
----------
1
2
3
4
5
6
7
8
8 rows selected.