理解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: 0x06SCN: 0x0000.00182f4a SUBSCN: 1 08/09/2012 21:47:52CHANGE #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')---------------------------- 53SQL> select to_number('0000c258','xxxxxxxx') from dualTO_NUMBER('0000C258','XXXXXXXX')-------------------------------- 49752SQL> select to_number('0010','xxxx') from dual;TO_NUMBER('0010','XXXX')------------------------ 16SQL> 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语句