说到闪回日志,我们都知道闪回日志中记录的都是逆操作,那么就有两个问题需要解释了。
闪回日志和回滚段保存的数据有什么差别?
如果做了truncate操作,闪回日志是怎么记录的,怎么能够通过闪回恢复数据。
第一个问题是一个同学问的,第二个问题是我偶然想起来的,当然这两个问题还是蛮有意思。我们的目标就是解释清楚下面的两个问题。
当然要深刻理解这个问题,一个重要的部分就是得先明白redo的基本情况。
借用大师Jonathan Lewis的话说,Oracle里面最重要的特性是在V6提出的改变向量,改变向量是描述数据块变化的机制,是redo和undo的关键内容。
说实在话要深入解析,非常透彻的理解这部分内容得花很多的时间,冰冻三尺绝非一日之寒,有一种较为快速的理解redo的基本流程,有两种简单的途径,一种是通过dump logfile来得到,另外一种就是解析日志文件来得到。明白了redo里面的一些变化,再回过头来看看闪回的部分,就会理解顺畅许多。
闪回日志的部分和redo的部分相比有一些相似之处。redo的机制中有的,闪回的部分也有相应的处理方式。
dump logfile其实输出还是比较枯燥,晦涩难懂的,另外一种较为清晰的方式就是logminer了。
为了让Logminer的日志处理信息更全面,还是建议打开supplemental log,这个在OGG中也有如出一辙的设置。
当然解析工作这么繁琐,我们想更加自如一些,那就和shell脚本联系起来。
脚本1:
sqlplus -s / as sysdba <<EOF
execute dbms_logmnr.add_logfile(logfilename=>'$1',options=>dbms_logmnr.new);
execute dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
col xid_scn format a30
col username format a10
col timestamp format a20
col sql_redo format a35
col sql_undo format a35
set pages 1500
set linesize 200
select username,xid||':'||scn xid_scn,timestamp,sql_redo,sql_undo from v\$logmnr_contents where sql_redo not like '%AUD$%';
execute dbms_logmnr.end_logmnr;
EOF
使用如上的脚本,输入对应的redo日志就会解析出里面的内容来。
要得到当前的日志信息也很容易,写个脚本,写个SQL分分钟搞定。
脚本2:
sqlplus -s / as sysdba <<EOF
set linesize 150
col member format a50
select l.sequence#,l.status ,l.bytes/1024/1024 size_MB,f.member from v\$log l ,v\$logfile f where l.group#=f.group#;
EOF
脚本1中直接调用即可,比如
sh showlog.sh /U01/app/oracle/oradata/newtest2/redo02.log我们使用如下的方式来做一个简单的测试。创建一个表,插入1行数据。
SQL> create table test_log (id number,name varchar2(30));
Table created.
SQL> insert into test_log values(100,'aaa');
1 row created.
SQL> commit;
Commit complete.
通过这种方式可以很容易读到一些关键的日志信息。
最开始的几个步骤可以很明显看到deferred_segment_creation的痕迹,
然后可以看到在基表中插入了元数据信息,基本是按照seg$,tab$,seg$的方式插入数据的。
通过上面的步骤可以看到,最后的insert,对应的undo_sql会基于ROWID来做一个反向的操作,即删除1条记录。
在这个基础上去解析闪回日志,就有了一些基本的思路。
查看闪回日志的信息可以使用SQL
select * from v$flashback_database_logfile;
解析闪回日志可以采用如下的方式:
alter system dump flashback logfile '/U01/app/oracle/fast_recovery_area/NEWTEST2/flashback/o1_mf_d2tp6v82_.flb' ;
或者基于对应的dba的方式,也就是数据块地址
alter system dump flashback logfile '/U01/app/oracle/fast_recovery_area/NEWTEST2/flashback/o1_mf_d2tp6v82_.flb' dba 8 594285;
当然解读闪回日志发现比自己想得还要曲折一些,因为Logminer还解析不了闪回日志,想更细节的解析还是要花一些功夫,所以上面的两个问题还需要不断的深入理解才可以回答清楚。
个人公众号如下,欢迎扫码关注。