写这篇文章,源于客户的数据库因为断电后无法启动,经过从网上查看,最后联系oracle得以解决,我后续会把此次客户问题及处理过程贴上。
现在我打算根据warehouse老师的试验,走一遍,研究下具体的原理:http://www.itpub.net/thread-1065138-1-1.html。
试验环境11.2.0.3
其实一句话就可以说明白:那就是数据文件的头上不仅包含了checkpoint_change#,更重要的是它包含了这个checkpoint_change#所在的logfile的sequence#,准确的说是rba。有了rba,在恢复时就能准确的知道到底需要哪个logfile(archivelog or redo)。
1、首先,查看控制文件(control file)中记录的checkpoint_change#,这个就是做checkpoint时的scn号:
SQL> set pages 80
SQL> set lines 1500
SQL> set numwidth 20
SQL> select resetlogs_change#, to_char(resetlogs_time, 'DD-MON-YYYY HH24:MI:SS') RSLTime,
to_char(resetlogs_change#) RSLscn, to_char(prior_resetlogs_time, 'DD-MON-YYYY HH24:MI:SS') PRSLTime, to_char(prior_resetlogs_change#) PRSLscn,
checkpoint_change# CKPscn, controlfile_change# CTLscn,
to_char(controlfile_time, 'DD-MON-YYYY HH24:MI:SS') CTLTime,
current_scn, controlfile_type from v$database;
这里我多查询了一些其他的信息,比如上一次open resetlogs的时间,当时的scn;当然,我们现在关注的还是 checkpoint_change# (此处给它取了个别名CKPSCN);注意controlfile_change#是指“Last SCN in backup control file; null if the control file is not a backup”,
current_scn是指:当前系统的scn号,如果系统是没有启动的,此值为0.
2、查看当前数据文件中记录的checkpoint_change#:
select status, to_char(checkpoint_change#), to_char(checkpoint_time, 'DD-MON-YYYY HH24:MI:SS') as
checkpoint_time, count(*)
from v$datafile_header
group by status, checkpoint_change#, checkpoint_time
order by status, checkpoint_change#, checkpoint_time;
当然,我可以可以查看每个数据文件对应的检查点scn(先从数据文件里查看):
然后是从控制文件里查看:
感觉,一般来说,应该不会出现控制文件和数据文件内checkpoint_change#不一致的情况。
3、查看控制文件(control file)里记录redo的checkpoint_change# :
select groups,current_group#,sequence#,checkpoint_change#,checkpoint_time,last_redo_change#
from v$thread;
其中last_redo_change#是指redo log里,最后的scn值(实际上也是记录在控制文件里的)。
验证恢复过程:
--输入测试数据,验证备份恢复的过程,注意仔细观查插入到tt表中的dbms_flashback.get_system_change_number和v$log中的FIRST_CHANGE#之间的关系,我们通常理解备份恢复的原理是:事务对应的scn如果落在了哪个archivelog里,那么这个archivelog在恢复时就被用到,下面的大致试验过程也会验证这一点:
1、冷备份当前数据库
2、创建测试表:
SQL> conn scott/tiger
Connected.
SQL> desc tt
Name Null? Type
--------------------------------------- ----------------------------
ID NUMBER
NAME VARCHAR2(20)
SQL> insert into tt values(dbms_flashback.get_system_change_number,'a');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from tt;
ID NAME
---------- --------------------
1111433 a
--datafile header上记录的rba信息,rba的意义在下面做了详细解释,这里只需知道FHRBA_SEQ表示redo的sequence#=13对应的是当前联机日志,而该sequence#被
记录在了datafile header上
select f.member, v.thread#, v.sequence#, v.group#, v.status,v.archived,v.first_change#
from v$log v, v$logfile f where v.group# = f.group#;
下面我们插入第二条记录:
SQL> insert into tt values(dbms_flashback.get_system_change_number,'b');
ID NAME
---------- --------------------
1111433 a
1133720 b
现在看来,