很多oracle大师对redo做了深入的研究,在此我谈谈自己对redo内部结构的理解以下数据库的版本为10.2.0.1.0,首先看看概念.
Redo:记录了数据库的所有历史变更,它包含数据文件的所有变更,但不包含参数文件和控制文件,
其应用主要有以下四方面:
1.实例恢复
2.日志挖掘
3.Oracle的流复制
4.Oracledataguard
以下条件能触发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
Lowscn: 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 recovery01/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
……………..
RedoBlocks
日志块由两部分组成16 bytes的header和用来存储redo记录的body
REDO RECORD - Thread:1RBA: 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:1RBA: 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)开始。呵呵
Redorecord:
Redorecord是一个逻辑结构,最大上限为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 #1TYP: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 undoUndo type:Last buffer split:No
Tablespace Undo:No
0x00000000
index undo for leaf key operations
KTB Redo
op: 0x04ver: 0x01
op: Litl: xid:0x0001.024.00000118 uba: 0x00800014.00d6.1d
flg: C---lkc:0scn: 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 #2TYP: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: 0x01ver: 0x01
op: Fxid:0x0005.025.00000189uba: 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 #1TYP: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后续会详细介绍。上面内容纯属个人观点,错误之处欢迎大师们指正,呵呵~~~