实验步骤:
1. SQL> truncate table t1;
Table truncated.
2. SQL> select group#,sequence#,bytes,archived,status,first_change# from v$log;
GROUP# SEQUENCE# BYTES ARC STATUS FIRST_CHANGE#
---------- ---------- ---------- --- ---------------- -------------
1 0 10485760 YES UNUSED 0
2 0 10485760 YES UNUSED 0
3 1 10485760 NO CURRENT 3300998
3. insert into t1
select dbms_flashback.get_system_change_number
from (select rownum from dba_objects where rownum <= 1000) a,
(select rownum from dba_objects where rownum <= 1000) b;
commit;
4. SQL> select group#,sequence#,bytes,archived,status,first_change# from v$log;
GROUP# SEQUENCE# BYTES ARC STATUS FIRST_CHANGE#
---------- ---------- ---------- --- ---------------- -------------
1 2 10485760 NO CURRENT 3303611
2 0 10485760 YES UNUSED 0
3 1 10485760 YES ACTIVE 3300998
5. SQL> select min(scn) ,max(scn) from t1;
MIN(SCN) MAX(SCN)
---------- ----------
3303561 3303632
6. T1的redo,落在1,2日志上。
7. SQL> alter system switch logfile;
System altered.
8. SQL> select group#,sequence#,bytes,archived,status,first_change# from v$log;
GROUP# SEQUENCE# BYTES ARC STATUS FIRST_CHANGE#
---------- ---------- ---------- --- ---------------- -------------
1 2 10485760 YES ACTIVE 3303611
2 3 10485760 NO CURRENT 3303663
3 1 10485760 YES ACTIVE 3300998
9. SQL> alter database backup controlfile to trace as '/tmp/ctl.sql' reuse;
Database altered.
10. SQL> shutdown abort
ORACLE instance shut down.
11. 我们模拟active的和current的日志文件都损坏,所以这里我把日志都移走了
12. SQL> ! mv $ORACLE_BASE/oradata/$ORACLE_SID/redo0* /tmp
13. SQL> ! ls -l /tmp/redo*
-rw-r----- 1 oracle10g oinstall 10486272 Mar 26 08:21 /tmp/redo01.log
-rw-r----- 1 oracle10g oinstall 10486272 Mar 26 08:21 /tmp/redo02.log
-rw-r----- 1 oracle10g oinstall 10486272 Mar 26 08:25 /tmp/redo03.log
14. 这个时候startup肯定报错
15. SQL> startup
ORACLE instance started.
Total System Global Area 285212672 bytes
Fixed Size 1218992 bytes
Variable Size 104859216 bytes
Database Buffers 176160768 bytes
Redo Buffers 2973696 bytes
Database mounted.
ORA-00313: open failed for members of log group 3 of thread 1
ORA-00312: online log 3 thread 1: '/u02/oradata/orac10g/redo03.log'
ORA-27037: unable to obtain file status
Linux Error: 2: No such file or directory
Additional information: 3
16. 备份一下控制文件看一下数据文件信息
17. SQL> select file#,name,checkpoint_change#,recover,fuzzy,checkpoint_count from v$datafile_header;
FILE# NAME CHECKPOINT_CHANGE# REC FUZ CHECKPOINT_COUN
-------- ---------------------------------------- ------------------ --- --- ----------------
1 /u02/oradata/orac10g/system01.dbf 3300999 NO YES 497
2 /u02/oradata/orac10g/undotbs01.dbf 3300999 NO YES 261
3 /u02/oradata/orac10g/sysaux01.dbf 3300999 NO YES 501
4 /u02/oradata/orac10g/users01.dbf 3300999 NO YES 515
5 /u02/oradata/orac10g/example01.dbf 3300999 NO YES 464
18. (数据库需要崩溃恢复)
19. SQL> ! cp $ORACLE_BASE/oradata/$ORACLE_SID/*.dbf /tmp
SQL> ! cp $ORACLE_BASE/oradata/$ORACLE_SID/*.ctl /tmp
20. SQL> ! ls -l /tmp/*.ctl
-rw-r----- 1 oracle10g oinstall 7454720 Mar 26 06:42 /tmp/control01.ctl
-rw-r----- 1 oracle10g oinstall 7454720 Mar 26 06:42 /tmp/control02.ctl
-rw-r----- 1 oracle10g oinstall 7454720 Mar 26 06:42 /tmp/control03.ctl
SQL> ! ls -l /tmp/*.dbf
-rw-r----- 1 oracle10g oinstall 222830592 Mar 26 06:41 /tmp/example01.dbf
-rw-r----- 1 oracle10g oinstall 293609472 Mar 26 06:41 /tmp/sysaux01.dbf
-rw-r----- 1 oracle10g oinstall 534781952 Mar 26 06:41 /tmp/system01.dbf
-rw-r----- 1 oracle10g oinstall 209723392 Mar 26 06:41 /tmp/temp01.dbf
-rw-r----- 1 oracle10g oinstall 104865792 Mar 26 06:42 /tmp/undotbs01.dbf
-rw-r----- 1 oracle10g oinstall 18358272 Mar 26 06:42 /tmp/users01.dbf
这里我们并没有还原数据文件,刚才的备份只是保留故障现场做的备份
21. 另开一个session2:
col name for a40
set linesize 130
select file#,name,checkpoint_change#,recover,fuzzy,checkpoint_count from v$datafile_header;
FILE# NAME CHECKPOINT_CHANGE# REC FUZ CHECKPOINT_COUNT
---------- ---------------------------------------- ------------------ --- --- ----------------
1 /u02/oradata/orac10g/system01.dbf 3300999 NO YES 497
2 /u02/oradata/orac10g/undotbs01.dbf 3300999 NO YES 261
3 /u02/oradata/orac10g/sysaux01.dbf 3300999 NO YES 501
4 /u02/oradata/orac10g/users01.dbf 3300999 NO YES 515
5 /u02/oradata/orac10g/example01.dbf 3300999 NO YES 464
22. session1:
SQL> recover database until cancel;
ORA-00279: change 3300999 generated at 03/26/2011 09:45:15 needed for thread 1
ORA-00289: suggestion : /u02/oradata/1_1_746790312.dbf
ORA-00280: change 3300999 for thread 1 is in sequence #1
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
按回车
23. session2:
SQL> /
FILE# NAME CHECKPOINT_CHANGE# REC FUZ CHECKPOINT_COUNT
---------- ---------------------------------------- ------------------ --- --- ----------------
1 /u02/oradata/orac10g/system01.dbf 3303611 NO YES 497
2 /u02/oradata/orac10g/undotbs01.dbf 3303611 NO YES 261
3 /u02/oradata/orac10g/sysaux01.dbf 3303611 NO YES 501
4 /u02/oradata/orac10g/users01.dbf 3303611 NO YES 515
5 /u02/oradata/orac10g/example01.dbf 3303611 NO YES 464
我们发现这里虽然前滚了日志1,但是fuzzy并没有变成no,数据文件还是不一致的。
数据文件并没有还原 实际上oracle认为是崩溃恢复
要把active和current的在线日志全部应用才能恢复到数据文件一致
24. SQL> select group#,sequence#,bytes,archived,status,first_change# from v$log;
GROUP# SEQUENCE# BYTES ARC STATUS FIRST_CHANGE#
---------- ---------- ---------- --- ---------------- -------------
1 2 10485760 YES ACTIVE 3303611
2 3 10485760 NO CURRENT 3303663
3 1 10485760 YES ACTIVE 3300998
25. SQL> select min(scn) ,max(scn) from t1;
MIN(SCN) MAX(SCN)
---------- ----------
3303561 3303632
26. session1:
ORA-00279: change 3303611 generated at 03/26/2011 10:40:04 needed for thread 1
ORA-00289: suggestion : /u02/oradata/1_2_746790312.dbf
ORA-00280: change 3303611 for thread 1 is in sequence #2
ORA-00278: log file '/u02/oradata/1_1_746790312.dbf' no longer needed for this recovery
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
按回车,前滚日志2
27. session2:
SQL> /
FILE# NAME CHECKPOINT_CHANGE# REC FUZ CHECKPOINT_COUNT
---------- ---------------------------------------- ------------------ --- --- ----------------
1 /u02/oradata/orac10g/system01.dbf 3303663 NO YES 497
2 /u02/oradata/orac10g/undotbs01.dbf 3303663 NO YES 261
3 /u02/oradata/orac10g/sysaux01.dbf 3303663 NO YES 501
4 /u02/oradata/orac10g/users01.dbf 3303663 NO YES 515
5 /u02/oradata/orac10g/example01.dbf 3303663 NO YES 464
我们发现还是不行
28. session1:
ORA-00279: change 3303663 generated at 03/26/2011 10:41:14 needed for thread 1
ORA-00289: suggestion : /u02/oradata/1_3_746790312.dbf
ORA-00280: change 3303663 for thread 1 is in sequence #3
ORA-00278: log file '/u02/oradata/1_2_746790312.dbf' no longer needed for this recovery
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
29. 提示要3,但是3号日志是当前的,不可能有归档日志文件,而且我们的当前在线日志又移走了。
所以这里就无法恢复了
30. 按回车后报错
ORA-00308: cannot open archived log '/u02/oradata/1_3_746790312.dbf'
ORA-27037: unable to obtain file status
Linux Error: 2: No such file or directory
Additional information: 3
ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: '/u02/oradata/orac10g/system01.dbf'
31. 我们为了实验连贯性,就把移走的当前日志应用到前滚中
32. SQL> recover database until cancel;
ORA-00279: change 3303663 generated at 03/26/2011 10:41:14 needed for thread 1
ORA-00289: suggestion : /u02/oradata/1_3_746790312.dbf
ORA-00280: change 3303663 for thread 1 is in sequence #3
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
/tmp/redo02.log
Log applied.
Media recovery complete.
输入当前在线日志redo02.log的路径,完成恢复了,数据没丢
33. session2:
SQL> /
FILE# NAME CHECKPOINT_CHANGE# REC FUZ CHECKPOINT_COUNT
---------- ---------------------------------------- ------------------ --- --- ----------------
1 /u02/oradata/orac10g/system01.dbf 3303678 NO NO 498
2 /u02/oradata/orac10g/undotbs01.dbf 3303678 NO NO 262
3 /u02/oradata/orac10g/sysaux01.dbf 3303678 NO NO 502
4 /u02/oradata/orac10g/users01.dbf 3303678 NO NO 516
5 /u02/oradata/orac10g/example01.dbf 3303678 NO NO 465
这里fuzzy也变成no了,说明数据文件一致了。
34. SQL> alter database open resetlogs;
Database altered.
35. SQL> select MIN(SCN),MAX(SCN) from t1;
MIN(SCN) MAX(SCN)
---------- ----------
3303561 3303632(前滚所有日志,数据没有丢失)