SQL> insert into tt values(1,dbms_flashback.get_system_change_number);
已创建 1 行。
SQL> insert into tt values(2,dbms_flashback.get_system_change_number);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from tt;
ID SCN
---------- ----------
1 7235265
2 7235294
通过查找tt,可以大致估算我们插入数据时的时间。
查看v$log:
SQL> select group#,status,archived,sequence#,first_change#,next_change# from v$log;
GROUP# STATUS ARC SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
---------- ---------------- --- ---------- ------------- ------------
1 INACTIVE YES 424 7179754 7189656
2 INACTIVE YES 425 7189656 7227701
3 CURRENT NO 426 7227701 2.8147E+14
有上述插入数据的SCN和目前日志的FIRST_CHANGE#知,上述数据的日志存放在当前日志文件中,也就是序列号为426。上述的FIRST_CHANGE#表示开始使用该组日志时的scn,
next_change#表示切换该组日志时的scn,也就是使用下一组日志的FIRST_CHANGE#。
分析一下status:
current:表示目前使用的日志,毫无疑问。
active:已经完成归档,日志文件已经写入磁盘,可能和该部分日志相对应的数据块的修改还没有写入磁盘,在内存里,所以该日志文件在数据库crash后恢复可能会用到。
inactive:此时已经完成归档,日志文件和对应修改的数据库已经写入磁盘。
由于这三组日志循环切换,产生的日志我们怎么标识呢,
这就是序列号重要的作用了:
SQL> alter system switch logfile;
系统已更改。
SQL> select name,thread#,sequence#,first_change#,next_change# from v$archived_log WHERE sequence# = 426;
NAME THREAD# SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------- ---------- ------------- ------------
/u01/app/oracle/flash_recovery_area/ORCL3939/archivelog/2015_04_27/o1_mf_1_426_bmvr5f9j_.arc 1 426 7227701 7236412
看上面的 name,sequence#,知道序列用来标识归档文件的作用了吧。
THREAD#:因为此时数据库是在单实例下,一个数据库对应一个实例:
所以此时thread#可以理解为实例编号。
在RAC下,此时的THREAD#对应的是节点号。
我们现在模拟:
SQL> insert into tt values(3,dbms_flashback.get_system_change_number
2 );
已创建 1 行。
SQL> commit;
提交完成。
SQL> alter system switch logfile;
系统已更改。
SQL> insert into tt values(4,dbms_flashback.get_system_change_number
2 );
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> alter system switch logfile;
系统已更改。
SQL> insert into tt values(5,dbms_flashback.get_system_change_number);
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> alter system switch logfile;
系统已更改。
SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME NEXT_CHANGE# NEXT_TIME
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- -------------- ------------ --------------
1 1 433 52428800 512 1 NO CURRENT 7239074 27-4月 -15 2.8147E+14
2 1 431 52428800 512 1 YES ACTIVE 7239029 27-4月 -15 7239057 27-4月 -15
3 1 432 52428800 512 1 YES ACTIVE 7239057 27-4月 -15 7239074 27-4月 -15
我们此时删除数据文件:
[oracle@localhost ~]$ cd /u01/app/oracle/oradata/orcl3939
[oracle@localhost orcl3939]$ rm -rf *.dbf
然后把之前备份的数据文件移到/u01/app/oracle/oradata/orcl3939,如果全部移动的话,则数据库可以打开了,之前对于表tt的操作数据完全丢失
[oracle@localhost beifeng]$ cp *.dbf /u01/app/oracle/oradata/orcl3939
SQL> startup mount;
ORACLE 例程已经启动。
Total System Global Area 351522816 bytes
Fixed Size 1336484 bytes
Variable Size 297798492 bytes
Database Buffers 46137344 bytes
Redo Buffers 6250496 bytes
数据库装载完毕。
此时打开到mount状态是完全可以的。
SQL> alter database open;
alter database open
*
第 1 行出现错误:
ORA-01113: 文件 1 需要介质恢复
ORA-01110: 数据文件 1: '/u01/app/oracle/oradata/orcl3939/system01.dbf'
此时我们恢复数据库:
SQL> recover database;
ORA-00279: 更改 7233493 (在 04/27/2015 13:51:53 生成) 对于线程 1 是必需的 ORA-00289:
建议:
/u01/app/oracle/flash_recovery_area/ORCL3939/archivelog/2015_04_27/o1_mf_1_426_b
mvr5f9j_.arc
ORA-00280: 更改 7233493 (用于线程 1) 在序列 #426 中
指定日志: {
=suggested | filename | AUTO | CANCEL}
此时会用到归档日志:/u01/app/oracle/flash_recovery_area/ORCL3939/archivelog/2015_04_27/o1_mf_1_426_b
mvr5f9j_.arc
序列号为:426,
更改时的scn:7233493
指定日志分析:
suggest:表示用的归档日志文件位置就是建议的位置
filename:表示归档后的日志若你修改位置,此时你需要指定位置
auto:表示数据库自动恢复
cancle:只恢复到该步骤即停止
/u01/app/oracle/flash_recovery_area/ORCL3939/archivelog/2015_04_27/o1_mf_1_427_b