闪回原理测试(二)(r11笔记第23天)
公众号:杨建荣的学习笔记 · 作者:杨建荣 · 发布:2016-12-24 23:39:19 · 原文链接
对于闪回部分,Oracle本身提供了非常多相关的特性,我个人对于闪回数据库这个特性最为喜爱,尤其是应用再Data Guard环境中,真是一大杀器。
而对于DML的闪回部分其实也相对比较容易理解,毕竟就是原操作的逆操作,之前通过logminer的方式来读取redo来间接得以印证。Oracle闪回原理-Logminer解读redo(r11笔记第17天)
但是对于DDL的闪回,这个特性真是非常强悍了。比如一个truncate操作,它的逆操作改怎么定义,就很难去界定了。当然这个里面肯定有一些很有意思的实现方式值得好好玩味。
我简单测试了truncate和delete的操作,虽然步骤简单,但是是带着特定的眼光来审视这个过程。
我们来创建一些数据,先创建200万的数据压压惊。
SQL> create table test_fb as select level object_id,'obj_'||level object_name from dual connect by level <=2000000;Table created.
然后持续插入一些数据,目的是保证这个表的数据量足够大。
SQL> insert into test_fb select *from test_fb;2000000 rows created.SQL> /4000000 rows created.SQL> /8000000 rows created.SQL> select count(*)from test_fb; COUNT(*)---------- 16000000SQL> commit;Commit complete.数据准备工作就这些,简单看看对应的段,会发现段的大小在近400M的样子。
SQL> select segment_name,bytes/1024/1024 size_MB from user_segments where segment_name='TEST_FB';SEGMENT_NAME SIZE_MB------------------------------ ----------TEST_FB 384虽然看起来不是特别大的段,不过已经能够说明问题了。我们开启闪回数据库的功能。
alter database flashback on;这个时候查看闪回区,会发现突然多出了两个闪回日志。
[oracle@newtest flashback]$ lltotal 102420-rw-r--r-- 1 oracle oinstall 171 Aug 21 20:37 a.sql-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:34 o1_mf_d5x1vjlb_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:34 o1_mf_d5x1vjvc_.flb可以理解这是一个初始化的过程。因为从alert日志可以看到启动了RVWR进程,SGA里面其实也分配了闪回区的缓存.Sat Dec 24 22:34:24 2016 alter database flashback onStarting background process RVWRSat Dec 24 22:34:24 2016RVWR started with pid=37, OS id=21314 Flashback Database Enabled at SCN 192530049424Completed: alter database flashback on这个时候数据库标示,闪回数据库是基于某一个SCN的。
下面我们来做一个truncate操作,为了让闪回的过程看起来自然一些,我们就创建一个还原点,毕竟基于SCN,基于时间戳还是有些取巧的感觉。
create restore point fb_recover_trunc guarantee flashback database;
对于还原点更多的信息可以联系v$restore_point来查看,其实从数据字典里查看,这部分信息也会清晰不少。
col NAME for a20 col TIME for a35 set lines 200 col STORAGE_SIZE for a50 SELECT NAME, SCN, TIME, DATABASE_INCARNATION# DI,GUARANTEE_FLASHBACK_DATABASE, STORAGE_SIZE/1024/1024/1024 FROM V$RESTORE_POINT WHERE GUARANTEE_FLASHBACK_DATABASE='YES';NAME SCN TIME DI GUARAN STORAGE_SIZE/1024/1024/1024---------------- ----------------------------- ----------------------------------- ---------- ------ ---------------------------FB_RECOVER_TRUNC 192530049487 24-DEC-16 10.35.16.000000000 PM 10 YES .048828125
这个过程,闪回日志没有大小的任何变化,但是闪回日志的时间戳会发生变化,证明是在持续更新。
我们来操作truncate,这个操作绝对是很多数据库灾难的源头。
truncate table test_fb;
但是操作完成之后查看闪回日志,竟然还是没有任何大小的变化。
可见truncate的操作,在闪回日志中不会记录逆操作的信息,这个应该是在其它的地方来做的。
我们来开启闪回数据库,尝试闪回到指定的还原点
shutdown immediate;startup mount
从启动日志可以清晰的看到,SGA里面是分配了60多M的flashback generation buffer.
Successful mount of redo thread 1, with mount id 806293483Allocated 63749952 bytes in shared pool for flashback generation bufferStarting background process RVWRSat Dec 24 22:38:39 2016RVWR started with pid=23, OS id=21403开始闪回到指定的还原点
flashback database to restore point fb_recover_trunc;这个时候闪回日志还是没有任何大小的变化。不过数据库日志需要格外关注。
Sat Dec 24 22:39:17 2016flashback database to restore point fb_recover_truncFlashback Restore StartFlashback Restore CompleteFlashback Media Recovery Start started logmerger processParallel Media Recovery started with 24 slavesSat Dec 24 22:39:18 2016Recovery of Online Redo Log: Thread 1 Group 3 Seq 11412 Reading mem 0 Mem# 0: /U01/app/oracle/oradata/newtest2/redo03.logIncomplete Recovery applied until change 192530049488 time 12/24/2016 22:35:16Flashback Media Recovery CompleteCompleted: flashback database to restore point fb_recover_trunc
这段日志很宝贵,可以看到是几个阶段,restore,media recovery,其中恢复的过程中是使用logmerger来处理的。这些个过程是后续进行分析的重要内容了。
为了简单验证,我们启动数据库至read only状态
alter database open read only;确认无误,后续的操作就是启动数据库,纠结的部分还是到来是,是一个resetlogs的操作。
shutdown immediatestartup mountalter database open resetlogs;在主库上还是有些纠结,所以我喜欢在备库上来玩闪回数据库。
整个resetlogs的过程会重置redo.
但是闪回日志的大小依旧不会有任何的变化。
听起来闪回日志的作用还是不大明显,如果你做了DML的操作,那这个过程的影响就会放大数倍。
当前的这个测试表数据量在1600万。
SQL> select count(*)from test_fb; COUNT(*)---------- 16000000
我们做一个大动作,闪回1000万数据。
SQL> delete from test_fb where rownum<10000000;9999999 rows deleted.
这个过程会持续一些时间,可以看到后台的redo非常忙,切换了近90次。
而闪回日志是否很忙呢,这下终于忙起来了,而且非常忙,生成了非常多的闪回日志。
[oracle@newtest flashback]$ lltotal 2446012-rw-r--r-- 1 oracle oinstall 171 Aug 21 20:37 a.sql-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:49 o1_mf_d5x1vjlb_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:49 o1_mf_d5x1vjvc_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:49 o1_mf_d5x2qv3h_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:49 o1_mf_d5x2r454_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:50 o1_mf_d5x2rf6s_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:50 o1_mf_d5x2rm8d_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:50 o1_mf_d5x2rwb0_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:50 o1_mf_d5x2s5co_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:50 o1_mf_d5x2sgfb_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:50 o1_mf_d5x2sngx_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:50 o1_mf_d5x2sxjk_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:50 o1_mf_d5x2t6l6_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:51 o1_mf_d5x2thmt_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:51 o1_mf_d5x2toof_.flb-rw-r----- 1 oracle oinstall 52436992 Dec 24 22:51 o1_mf_d5x2tyq2_.flb-rw-r----- 1 oracle oinstall 104865792 Dec 24 22:51 o1_mf_d5x2v4rn_.flb-rw-r----- 1 oracle oinstall 209723392 Dec 24 22:52 o1_mf_d5x2vfvm_.flb-rw-r----- 1 oracle oinstall 389283840 Dec 24 22:53 o1_mf_d5x2vx2o_.flb-rw-r----- 1 oracle oinstall 453705728 Dec 24 22:54 o1_mf_d5x2wyhs_.flb-rw-r----- 1 oracle oinstall 560545792 Dec 24 22:53 o1_mf_d5x2yxz0_.flb
而且尤其值得关注的是,后面生成的闪回日志不是按照原有的50M而是逐步递增的节奏。
如果你继续使用truncate的方式清理数据,闪回日志的大小还是没有任何的变化。这应该不是巧合,也是故弄玄虚,flashback restore,flashback media recovery这些需要关注,后台进程RVWR来维护整个闪回数据库的过程,自有它的道理。
