理解redo(2)redo内容:change vector和redo entries

    redo log file由redo records(又名redo entries)组成。一条redo record由一组change vectors构成。

    redo record:是change vector的集合。每个redo record是由多个change vector组成的。oracle在恢复过程中,会保证一个transaction要么被全部恢复,要么全部不恢复。实际上就是通过恢复redo record中的全部change vector来做到的,只要有一个change vector恢复失败,这个redo record的所有change vector都将失败。所以,redo record是构成数据库变更的最小恢复单位。

    change vector:表示数据库内某一个数据块所做的一次变更。一个CV只针对一个数据块的变更,一个CV只包含一个变化。

            这个数据块可以是:

                数据块data block
                回滚块undo block
                数据段头块data segment header block
                回滚段头块undo header block   

   

    Change vector的结构,包含一个头信息和身体信息。
        change vector header主要包括:
                 change #n:同一个redo record中的change vector的编号
                 TYP:变更类型
                 CLS:本次修改对应的block的类别,等于x$bh.class
                 AFN:绝对文件号
                 DBA:回滚块地址
                 SCN:修改时的SCN
                 SEQ:同一个SCN的不同修改以seq编号,注意:在oracle中,序列号的本质是,不同序列号都是对应不同的内容
                 OP:操作码,由两部分组成,layer code. sub code

       change vector body主要包括:
                1)变更数据块的版本号:在建立change vector时oracle会从data block copy其版本号,在做前滚的时候,通过REDO LOG文件里记录的change vector,根据SCN的比对,提交到相关的数据文件上,从而使数据文件的状态向前滚动,被恢复的数据块版本号加一(临时段的数据块不会生成change vector)。注意,重新运用redo来recover,这是个二元运算的过程,并不会产生sql!
               2)DBA:回滚块地址
               3)事务操作代码
               4)更新后的数据

 

    每次修改cache buffer中的这些block时,需要先在PGA中生成对应的change vector,然后由server process从PGA copy到SGA REDO LOG BUFFER。user process修改数据时产生redo entries,此时redo存于pga中,将PGA中redo copy到 redo log buffer 需要redo copy latch,LGWR只有等待进程COPY 完成才能把目标log buffer block写入redo log file。redo entries在内存中是占用连续的顺序的空间,他是按顺序写入到redo log file,其块大小不同于数据块大小是由db_block_size参数设置的,而是在Oracle源代码中固定的,和os相关,大部分os中都是512字节。只有当一个事务所包含的全部redo records被安全着陆到磁盘,user process才能得到commit completed的通告。redo log buffer里面的redo records,或者全部被写、或者全部不写。

   

    由于user process 向redo log buffer写数据,所以需要latch保护:
    redo copy latch:写redo 到redo log buffer
    redo allocation latch:控制log buffer分配
    在将PGA中redo copy到 log buffer时,获取redo copy latch,获取后接着获取redo allocation latch 分配redo log buffer空间,分配后释放redo allocation latch,然后server process 将PGA中redo信息 COPY 到redo log buffer,OK 后redo copy latch释放。

 

    下面做个小实验。

    1)以hr连接,并创建一张表

SQL> conn hr/hr
已连接。
SQL> drop table t1;
drop table t1
           *
第 1 行出现错误:
ORA-00942: 表或视图不存在


SQL> create table t1(a number);

表已创建。


    2)查看一下当前的SCN是什么

SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER
------------------------
                 1584957


    3)执行一条INSERT语句,然后以这条语句进行分析:

SQL> insert into t1 values(1);

已创建 1 行。

SQL> commit;

提交完成。

SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER
------------------------
                 1584996


    4)通过这两个SCN值,我们对当前的REDO LOG进行DUMP:

SQL> alter system dump logfile 'g:\oracle\product\10.2.0\oradata\ORCL\ONLINELOG\O1_MF_1_80YR2HGQ_.LOG'
  2  scn min 1584957 scn max 1584996;

系统已更改。
SQL> select spid from v$process where addr in (select paddr from v$session where sid in (select sid from  v$mystat where rownum=1));

SPID
------------------------
1324


    5)下面的内容就是我们刚才的INSERT语句产生的,下面是第一个REDO RECORD:

REDO RECORD - Thread:1 RBA: 0x000035.0000c258.0010 LEN: 0x0070 VLD: 0x06
SCN: 0x0000.00182f4a SUBSCN:  1 08/09/2012 21:47:52
CHANGE #1 MEDIA RECOVERY MARKER SCN:0x0000.00000000 SEQ:  0 OP:23.1
 Block Written - afn: 3 rdba: 0x00c07179 BFT:(1024,12611961) non-BFT:(3,29049)
                   scn: 0x0000.00182f38 seq: 0x02 flg:0x06


    对上面的16进制数转换成10进制数

SQL> select to_number('000035','xxxxxx') from dual;

TO_NUMBER('000035','XXXXXX')
----------------------------
                          53

SQL> select to_number('0000c258','xxxxxxxx') from dual

TO_NUMBER('0000C258','XXXXXXXX')
--------------------------------
                           49752

SQL> select to_number('0010','xxxx') from dual;

TO_NUMBER('0010','XXXX')
------------------------
                      16

SQL> select to_number('0070','xxxx') from dual;

TO_NUMBER('0070','XXXX')
------------------------
                     112


    由此,可知:
    这个REDO RECORD的RBA是0x000035.0000c258.0010,翻译成10进制是53.49752.16。LOG SEQUENCE号是53,在REDO LOG中的块号是49752,起始字节是块内的16字节.
    这个REDO RECORD的长度LEN: 0x0070为112个字节
    CHANGE #1,这就是这个REDO RECORD的第一个CV,我们看到OP:23.1,根据上面的OPCODE清单,可以知道是Dummy block written callback (DBWn写出数据块)

 

    常见的OP附录:

   

    4块清除

        4.1块清除
    5事务管理,如commit/rollback

         5.1修改undo header中的事务信息
     5.2
事务开始
     5.4 commit
     5.19
事务审计
     5.20
子事务审计

   10索引操作

    10.2插入页块记录
    10.3
清除页块记录
    10.4
删除页块中的记录
    10.5
还原页块日志
    10.6
锁定索引块
    10.7
提交时清除块中的操作码
    10.8
初始化头部
    10.9 ITL1
上应用XAT
    10.10
设置页块指向下一个页块的指针

    10.11
设置页块指向上一个页块的指针
    10.12 root
块分裂后重新初始化

       10.13清空页块
       10.15
分支块中插入记录
       10.16
清除分支块中的记录
       10.18
更新记录中的键值
       10.19
清除分裂标志
       10.21
撤销分支块操作
       10.22
撤销页块操作
       10.24
收缩ITL
       10.30
更新非键值

       10.31
创建/装载索引
       10.34
清空页块
   11行数据操作

    11.2插入一条数据
    11.3
删除一条数据
    11.4
锁定数据(select for update)
    11.5
更新记录

    11.6
行链接
    11.9 cluster
键索引操作
    11.10
设置cluster键指针
    11.11
插入多条记录
    11.12
删除多条记录

   13段管理操作

   14区块管理操作
   17表空间管理操作

       17.1 end backup
   18块映像(手工热备期间产生)

   18.1 begin backup
   19直接路径装载

    19.1直接路径装载(归档模式)
    19.2 nologging
设置

   20 Compatibility Segment
   22
本地管理表空间操作
   23 block写出

   23.1 dbwr写出block(9.0.1开始)
   24 DDL语句

  

 

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值