很多oracle大师对redo做了深入的研究,在此我谈谈自己对redo内部结构的理解 以下数据库的版本为10.2.0.1.0 ,首先看看概念.
Redo: 记录了数据库的所有历史变更,它包含数据文件的所有变更,但不包含参数文件和控制文件,
其应用主要有以下四方面:
1. 实例恢复
2. 日志挖掘
3. Oracle 的流复制
4. Oracle dataguard
以下条件能触发LGWR 进程将redo log buffer 写到 redo log
1. 提交的时候(commit)
2.达到1/3满或者是超过1M
3. 每隔3秒
4. 在dbwr进程些之前
Redo Threads:
每个在线重做日志都有一个线程号和一个序列号,在单实例环境中,
任何时刻只有一个线程号, 但是在多节点的RAC中就可能存在多个线程号
Redo log files:
一个日志文件是由一定数量的固定大小的块组成,日志文件的大小是在
日志组创建过程中指定,不同的平台,日志块的大小是不同的(主要依赖
操作系统 和 oracle 版本),在linux和Solaris 中 日志块的大小为 512 bytes,
在HP-U中日志块的大小为1024 bytes
每个日志文件都有一个固定的文件头,多数版本中此文件头占2个日志块大小,
第一个块为file header,第二个块为redo header
第二个块中记录的信息有:
1 数据库名
2 进程
3 一致性版本号
4 开始时间
5 结束时间
6 开始的SCN
7 结束的SCN (end SCN 实际上是下一个日志文件的start SCN)
以下为一个日志文件的dump信息的截取部分,如下:
DUMP OF REDO FROM FILE '/u01/app/oracle/oradata/gabriel/redo02.log'
Opcodes *.*
RBAs: 0x000000.00000000.0000 thru 0xffffffff.ffffffff.ffff //第一个日志块
SCNs: scn: 0x0000.00000000 thru scn: 0xffff.ffffffff
Times: creation thru eternity
FILE HEADER: // 文件头
Compatibility Vsn = 169869568=0xa200100 //一致性版本号
Db ID=3977367663=0xed11d06f, Db Name='GABRIEL' //数据库名
Activation ID=3977364079=0xed11c26f
Control Seq=2178=0x882, File size=102400=0x19000 //日志文件大小
File Number=2, Blksiz=512, File Type=2 LOG // 日志块大小
descrip:"Thread 0001, Seq# 0000000051, SCN 0x0000000c2c1c-0x0000000c2cb1"
thread: 1 nab: 0x97 seq: 0x00000033 hws: 0x2 eot: 0 dis: 0
resetlogs count: 0x2c713af2 scn: 0x0000.0006ce7b (446075)
resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
prev resetlogs count: 0x2184ef74 scn: 0x0000.00000001 (1)
prev resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
Low scn: 0x0000.000c2c1c (797724) 06/23/2011 12:08:43
Next scn: 0x0000.000c2cb1 (797873) 06/23/2011 12:13:17
Enabled scn: 0x0000.0006ce7b (446075) 03/12/2011 20:09:22
Thread closed scn: 0x0000.000c2c1c (797724) 06/23/2011 12:08:43
Disk cksum: 0x20ba Calc cksum: 0x20ba
Terminal recovery stop scn: 0x0000.00000000
Terminal recovery 01/01/1988 00:00:00
Most recent redo scn: 0x0000.00000000
Largest LWN: 55 blocks
End-of-redo stream : No
Unprotected mode
Miscellaneous flags: 0x0
Thread internal enable indicator: thr: 0, seq: 0 scn: 0x0000.00000000
REDO RECORD - Thread:1 RBA: 0x000033.00000002.0010 LEN: 0x0080 VLD: 0x06 //第一个记录块开始, 00000002表示第三个日志块
CHANGE #1 MEDIA RECOVERY MARKER SCN:0x0000.00000000 SEQ: 0 OP:23.1
Block Written - afn: 3 rdba: 0x00c00002 BFT:(1024,12582914) non-BFT:(3,2)
scn: 0x0000.000c296a seq: 0x02 flg:0x04
Block Written - afn: 3 rdba: 0x00c00003 BFT:(1024,12582915) non-BFT:(3,3)
scn: 0x0000.000c296a seq: 0x01 flg:0x04
……………..
Redo Blocks
日志块由两部分组成 16 bytes 的header 和 用来存储redo记录的body
REDO RECORD - Thread:1 RBA: 0x000033.00000002.01cc LEN: 0x0064 VLD: 0x02
SCN: 0x0000.000c2c1c SUBSCN: 1 06/23/2011 12:08:48
CHANGE #1 MEDIA RECOVERY MARKER SCN:0x0000.00000000 SEQ: 0 OP:23.1
Block Written - afn: 3 rdba: 0x00c076d2 BFT:(1024,12613330) non-BFT:(3,30418)
scn: 0x0000.000c2946 seq: 0x01 flg:0x04
Block Written - afn: 3 rdba: 0x00c076d3 BFT:(1024,12613331) non-BFT:(3,30419)
scn: 0x0000.000c2946 seq: 0x01 flg:0x04
Block Written - afn: 3 rdba: 0x00c076d4 BFT:(1024,12613332) non-BFT:(3,30420)
scn: 0x0000.000c2948 seq: 0x02 flg:0x04
REDO RECORD - Thread:1 RBA: 0x000033.00000003.0040 LEN: 0x0044 VLD: 0x02
SCN: 0x0000.000c2c1c SUBSCN: 1 06/23/2011 12:08:48
CHANGE #1 MEDIA RECOVERY MARKER SCN:0x0000.00000000 SEQ: 0 OP:23.1
Block Written - afn: 3 rdba: 0x00c00b6b BFT:(1024,12585835) non-BFT:(3,2923)
scn: 0x0000.000c2948 seq: 0x02 flg:0x06
假设RBA: 0x000033.00000002.01cc 为 record A , RBA: 0x000033.00000003.0040 为 record
B: 则A 在第三个日志块的 01cc(16*16+12*16+12= 464 bytes) + LEN: 0x0064(100bytes) +0001(16bytes)(redo block header) = 580 bytes– 512bytes(redo block size)= 0040 (48bytes) 由上计算可知其第四个日志块刚好为0040(与record B 的起始地址吻合) 也证明了 每个日志块的header 为 16bytes 其实从logfile 的第三个日志块也能判断出 header 为 16bytes
REDO RECORD - Thread:1 RBA: 0x000033.00000002.0010 LEN: 0x0080 VLD: 0x06 // 第三个日志块的offset 从0X0010(16) 开始。 呵呵
Redo record:
Redo record 是一个逻辑结构,最大上限为 65536bytes它包含一个 redo record header 和 N个Change vectors, 一个物理的redo block 包含 多个 redo records, 当然一个redo record也可以跨度多个日志块。关于redo record 如下:
…………..
REDO RECORD - Thread:1 RBA: 0x000033.0000008f.00c0 LEN: 0x00ec VLD: 0x01
SCN: 0x0000.000c2c99 SUBSCN: 3 06/23/2011 12:12:14
CHANGE #1 TYP:0 CLS:26 AFN:2 DBA:0x0080004f OBJ:4294967295 SCN:0x0000.000c2c99 SEQ: 1 OP:5.1
ktudb redo: siz: 104 spc: 1792 flg: 0x0022 seq: 0x013d rec: 0x32
xid: 0x0005.025.00000189
ktubu redo: slt: 37 rci: 49 opc: 10.22 objn: 239 objd: 239 tsn: 0
Undo type: Regular undo Undo type: Last buffer split: No
Tablespace Undo: No
0x00000000
index undo for leaf key operations
KTB Redo
op: 0x04 ver: 0x01
op: L itl: xid: 0x0001.024.00000118 uba: 0x00800014.00d6.1d
flg: C--- lkc: 0 scn: 0x0000.000c2c62
Dump kdilk : itl=2, kdxlkflg=0x1 sdc=0 indexid=0x400689 block=0x0040068a
(kdxlre): restore leaf row (clear leaf delete flags)
key :(15): 07 78 6f 06 17 0d 0d 0a 06 00 40 06 7a 00 00
CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x0040068a OBJ:239 SCN:0x0000.000c2c99 SEQ: 1 OP:10.4
index redo (kdxlde): delete leaf row
KTB Redo
op: 0x01 ver: 0x01
op: F xid: 0x0005.025.00000189 uba: 0x0080004f.013d.32
REDO: SINGLE / -- / --
itl: 2, sno: 0, row size 19
REDO RECORD - Thread:1 RBA: 0x000033.0000008f.01ac LEN: 0x00e4 VLD: 0x01
……………..
由上可知 此redo record 包含2个Change vectors, 由于日志块0000008f(8*16+15=143)包含多个redo record,后一个redo record 的偏量offset (01ac) RBA: 0x000033.0000008f.01ac 刚好等于前一个redo record RBA: 0x000033.0000008f.00c0 +LEN: 0x00ec
Change vectors:
记录了单个数据块的改变,包括 undo headers, undo blocks, data segment headers, data block. 一个向量包含以下三个部分:
A. 改变向量头 eg
CHANGE #1 TYP:0 CLS:26 AFN:2 DBA:0x0080004f OBJ:4294967295 SCN:0x0000.000c2c99 SEQ: 1 OP:5.1 相关内容的含义
CHANGE |
Change number |
TYP |
Change type |
CLS |
Class |
AFN |
Absolute File Number |
DBA |
Relative Database Block Address |
SCN |
System Change Number |
SEQ |
Sequence Number (relative to SCN) |
OP |
Operation Code |
B. 改变记录的长度
C. 改变记录的实际内容
Operation Codes
每个向量都包含一个操作码(简称OP) 如以上change#2 的OP 10.4 表示 delete leaf row , 随着数据库版本的更新,OP也在不断的增加,OP又两部分组成,第一部分为主码,后面部分子码 其主要编号的主题含义如下:
Level |
Description |
4 |
Block Cleanout |
5 |
Transaction Layer (Undo) |
10 |
Index Operation |
11 |
Table Operation (DML) |
13 |
Block Allocation |
14 |
Extent Allocation |
17 |
Backup Management |
18 |
Online Backup |
19 |
Direct Load |
20 |
Transaction Metadata (LogMiner) |
22 |
Space Management (ASSM) |
23 |
Block Write (DBWR) |
24 |
DDL Statement |
限于篇幅原因,关于详细的 redo record header,change vector, operation code 后续会详细介绍。上面内容纯属个人观点,错误之处欢迎大师们指正, 呵呵~~~
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8117479/viewspace-701770/,如需转载,请注明出处,否则将追究法律责任。