• 为什么Flashback Log产生量要远少于Redo Log?


    有同学提问关于闪回数据库日志为什么远少于redo log?   RVWR( Recovery Writer)每3s检查flashback generate buffer中的block before image的具体算法是如何的? 是否每一次block change都需要RVWR写出block before image 到flashback log?   为了实现闪回数据库,Oracle需要记录数据块的前景象before image到一种新的日志中,这种日志被命名为flashback database logs闪回日志。   闪回日志总是被循环复用,连续写出。   在一个实例中当一个数据块首次被修改时,前台进程会将该数据块的before image拷贝到位于shared pool中的flashback log buffer中,RVWR进程定期地将flashback log buffer中的记录刷新到磁盘上。 在DBWR进程可以写出相关脏块到磁盘之前,DBWR必须保证该buffer header相关FBA(Flashback Byte Address)的flashback log buffer已经写出到闪回日志。 这被称作 先写闪回日志 机制。   在常规的闪回日志维护操作中 , RVWR进程定期地插入闪回标记(flashback markers)到flashback database logs中。 闪回标记(flashback markers)的作用是在闪回数据库是告知Oracle如何flashback 到之前的某个时间点。  在闪回操作执行过程中, Oracle 会用闪回标记(flashback markers)中的信息来决定多大范围的flashback database log需要用来还原数据块景象block image; 之后Oracle 会利用前向恢复(forward recovery)的方式把数据库穿越到用户指定闪回的SCN或者时间点。   flashback markers for example:  
     **** Record at fba: (lno 1 thr 1 seq 1 bno 4 bof 8184) ****
        RECORD HEADER:
          Type: 3 (Skip)  Size: 8132
        RECORD DATA (Skip):
     **** Record at fba: (lno 1 thr 1 seq 1 bno 4 bof 52) ****
        RECORD HEADER:
          Type: 7 (Begin Crash Recovery Record)  Size: 36
        RECORD DATA (Begin Crash Recovery Record):
          Previous logical record fba: (lno 1 thr 1 seq 1 bno 3 bof 316)
          Record scn: 0x0000.00000000 [0.0]
     **** Record at fba: (lno 1 thr 1 seq 1 bno 3 bof 8184) ****
        RECORD HEADER:
          Type: 3 (Skip)  Size: 7868
        RECORD DATA (Skip):
     **** Record at fba: (lno 1 thr 1 seq 1 bno 3 bof 316) ****
        RECORD HEADER:
          Type: 2 (Marker)  Size: 300
        RECORD DATA (Marker):
          Previous logical record fba: (lno 0 thr 0 seq 0 bno 0 bof 0)
          Record scn: 0x0000.00000000 [0.0]
          Marker scn: 0x0000.0060e024 [0.6348836] 06/13/2012 15:56:35
          Flag 0x0
          Flashback threads: 1, Enabled redo threads 1
          Recovery Start Checkpoint:
            scn: 0x0000.0060e024 [0.6348836]  06/13/2012 15:56:12
            thread:1 rba:(0x80.180.10)
          Flashback thread Markers:
             Thread:1 status:0 fba: (lno 1 thr 1 seq 1 bno 2 bof 8184)
          Redo Thread Checkpoint Info:
             Thread:1 rba:(0x80.180.10)
     **** Record at fba: (lno 1 thr 1 seq 1 bno 2 bof 8184) ****
        RECORD HEADER:
          Type: 3 (Skip)  Size: 8168
        RECORD DATA (Skip):
      End-Of-Thread reached
          需要注意的是不是数据库中的每一次block change 都会触发before image被记录到闪回日志flashback log中。 如果每一次block change都记录flashback log record 那么闪回日志会要比 redo log大的多!因为毕竟flashback log 是记录整个块的before image 而 redo log只记录 change vector 。  Oracle对于闪回日志使用一种即能够保证可以讲数据库一致地穿越到某个历史时间点的状态,又不过分造成I/O损耗和生成大量闪回日志的方法: 对于hot block热块,Oracle仅在一段时间内记录一次block image到闪回日志; Oracle 内部通过闪回分界线(flashback barriers)实现这一点。在常规数据库状态下,flashback barriers被周期性的触发(一般为15分钟),对应每一个闪回分界线(flashback barriers)会有一个(flashback markers)被写出到闪回日志。   对于热块, 即那些频繁被change的数据库块, 闪回日志算法要求限制其写出到闪回日志的版本数。举例来说, 在15分钟内对于某个数据块仅限其写出一个版本到flashback log。虽然更多版本的before image有助于减少闪回数据库的时间,但是最小化有效闪回日志的容量是更重要的因素,比起实际闪回所用的时间来说。 为了实现这个目标,闪回日志算法引入了闪回分界线(flashback barriers), flashback barriers会被定期地触发,典型的例如15分钟一次。 对应每一个flashback barriers会有一个闪回标记(flashback markers)被插入到闪回日志中。常规情况下,对于每一个被修改的数据块在一个闪回区域(被分界线barriers分割的区域)内仅记录一个block image ,无论这个数据块在这段区域内被修改了多少次、被写出过多少次到磁盘上。 这就是为什么闪回日志flashback log要原少于redo log的产生量!   好了说了,这么多如果不亲身体验一下就太虚了, 我们来做以下的测试。    
    SQL> select * from v$version;
    
    BANNER
    --------------------------------------------------------------------------------
    Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
    PL/SQL Release 11.2.0.3.0 - Production
    CORE    11.2.0.3.0      Production
    TNS for Linux: Version 11.2.0.3.0 - Production
    NLSRTL Version 11.2.0.3.0 - Production
    
    SQL> select * from global_name;
    
    GLOBAL_NAME
    --------------------------------------------------------------------------------
    www.oracledatabase12g.com
    
    SQL> create table flash_maclean (t1 varchar2(200)) tablespace users;
    
    Table created.
    
    SQL> insert into flash_maclean values('MACLEAN LOVE HANNA');
    
    1 row created.
    
    SQL> commit;
    
    Commit complete.
    
    SQL> startup force;
    ORACLE instance started.
    
    Total System Global Area  939495424 bytes
    Fixed Size                  2233960 bytes
    Variable Size             713034136 bytes
    Database Buffers          218103808 bytes
    Redo Buffers                6123520 bytes
    Database mounted.
    Database opened.
    
    SQL> update flash_maclean set t1='HANNA LOVE MACLEAN';
    
    1 row updated.
    
    commit;
    Commit complete.
    
    SQL> alter system checkpoint;
    
    System altered.
    
    SQL> select dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_relative_fno(rowid) from flash_maclean;
    
    DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID)
    ------------------------------------ ------------------------------------
                                  140431                                    4
    
    datafile 4 block 140431 对应RDBA rdba: 0x0102248f (4/140431)
    
    SQL> ! ps -ef|grep rvwr|grep -v grep
    oracle   26695     1  0 15:56 ?        00:00:00 ora_rvwr_G11R23
    
    SQL> oradebug setospid  26695
    Oracle pid: 20, Unix process pid: 26695, image: oracle@nas.oracle.com (RVWR)
    
    SQL> ORADEBUG DUMP FBTAIL 1;
    Statement processed.
    
    To dump the last 2000 flashback records , 以上ORADEBUG DUMP FBTAIL 1命令可以转出最近2000条的闪回记录
    
    SQL> oradebug tracefile_name
    /s01/orabase/diag/rdbms/g11r23/G11R23/trace/G11R23_rvwr_26695.trc
    
    在 TRACE文件中可以找到对应block的 before image 
    
     **** Record at fba: (lno 1 thr 1 seq 1 bno 55 bof 2564) ****
        RECORD HEADER:
          Type: 1 (Block Image)  Size: 28
        RECORD DATA (Block Image):
          file#: 4 rdba: 0x0102248f
          Next scn: 0x0000.00000000 [0.0]
          Flag: 0x0
          Block Size: 8192
        BLOCK IMAGE:
          buffer rdba: 0x0102248f
          scn: 0x0000.00609044 seq: 0x01 flg: 0x06 tail: 0x90440601
          frmt: 0x02 chkval: 0xc626 type: 0x06=trans data
    Hex dump of block: st=0, typ_found=1
    Dump of memory from 0x00002B1D94183C00 to 0x00002B1D94185C00
    2B1D94183C00 0000A206 0102248F 00609044 06010000  [.....$..D.`.....]
    2B1D94183C10 0000C626 00000001 00014AD4 0060903A  [&........J..:.`.]
    2B1D94183C20 00000000 00320002 01022488 00090006  [......2..$......]
    2B1D94183C30 00000CC8 00C00340 000D0542 00008000  [....@...B.......]
    2B1D94183C40 006040BC 000F000A 00000920 00C002E4  [.@`..... .......]
    2B1D94183C50 0017048F 00002001 00609044 00000000  [..... ..D.`.....]
    2B1D94183C60 00000000 00010100 0014FFFF 1F6E1F77  [............w.n.]
    2B1D94183C70 00001F6E 1F770001 00000000 00000000  [n.....w.........]
    2B1D94183C80 00000000 00000000 00000000 00000000  [................]
            Repeat 500 times
    2B1D94185BD0 00000000 00000000 2C000000 4D120102  [...........,...M]
    2B1D94185BE0 454C4341 4C204E41 2045564F 4E4E4148  [ACLEAN LOVE HANN]
    2B1D94185BF0 01002C41 43414D07 4E41454C 90440601  [A,...MACLEAN..D.]
    Block header dump:  0x0102248f
     Object id on Block? Y
     seg/obj: 0x14ad4  csc: 0x00.60903a  itc: 2  flg: E  typ: 1 - DATA
         brn: 0  bdba: 0x1022488 ver: 0x01 opc: 0
         inc: 0  exflg: 0
    
     Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
    0x01   0x0006.009.00000cc8  0x00c00340.0542.0d  C---    0  scn 0x0000.006040bc
    0x02   0x000a.00f.00000920  0x00c002e4.048f.17  --U-    1  fsc 0x0000.00609044
    bdba: 0x0102248f
    data_block_dump,data header at 0x2b1d94183c64
    ===============
    tsiz: 0x1f98
    hsiz: 0x14
    pbl: 0x2b1d94183c64
         76543210
    flag=--------
    ntab=1
    nrow=1
    frre=-1
    fsbo=0x14
    fseo=0x1f77
    avsp=0x1f6e
    tosp=0x1f6e
    0xe:pti[0]      nrow=1  offs=0
    0x12:pri[0]     offs=0x1f77
    block_row_dump:
    tab 0, row 0, @0x1f77
    tl: 22 fb: --H-FL-- lb: 0x2  cc: 1
    col  0: [18]  4d 41 43 4c 45 41 4e 20 4c 4f 56 45 20 48 41 4e 4e 41
    end_of_block_dump
    
    SQL> select dump('MACLEAN LOVE HANNA',16) from dual;
    
    DUMP('MACLEANLOVEHANNA',16)
    --------------------------------------------------------------------
    Typ=96 Len=18: 4d,41,43,4c,45,41,4e,20,4c,4f,56,45,20,48,41,4e,4e,41
        若我们在短期内在多个事务内反复更新同样的数据块,其在flashback log中的before image版本也不会大幅增长  
    create table flash_maclean1 (t1 int) tablespace users;
    
    SQL>      select vs.name, ms.value
      2       from v$mystat ms, v$sysstat vs
      3       where vs.statistic# = ms.statistic#
      4         and vs.name in ('redo size','db block changes');
    
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    db block changes                                                          0
    redo size                                                                 0
    
    SQL>      select name,value from v$sysstat where name like 'flashback log%';
    
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    flashback log writes                                                     49
    flashback log write bytes                                           9306112
    
    SQL>      begin
      2       for i in 1..5000 loop
      3       update flash_maclean1 set t1=t1+1;
      4       commit;
      5       end loop;
      6       end;
      7       /
    
    PL/SQL procedure successfully completed.
    
    SQL>     select vs.name, ms.value
      2       from v$mystat ms, v$sysstat vs
      3       where vs.statistic# = ms.statistic#
      4         and vs.name in ('redo size','db block changes');
    
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    db block changes                                                      20006
    redo size                                                           3071288
    
    SQL>      select name,value from v$sysstat where name like 'flashback log%';
    
    NAME                                                                  VALUE
    ---------------------------------------------------------------- ----------
    flashback log writes                                                     52
    flashback log write bytes                                          10338304
        在以上的测试中可以看到 对于hot block,在产生20006 个block changes的情况下 产生了 3000k 的redo log 和 大约1000k的 flashback log 。
  • 相关阅读:
    盛最多水的容器
    除自身以外数组的乘积
    组合总和
    旋转图像
    找到所有数组中消失的数字
    RSA加密、签名机制
    SpringBoot-从新建一个项目看起
    linux下vi命令修改文件及保存的使用方法
    集合
    第一个注解式的SpringMVC项目
  • 原文地址:https://www.cnblogs.com/macleanoracle/p/2968304.html
Copyright © 2020-2023  润新知