摘要: 本文通过对oracle redo log文件分析,说明oracle redo log文件包含了oracle数据库所有事务信息和物理操作信息。根据oracle redo log文件分析,我们可以通过redo log对oracle 数据库进行跟踪和监控,从而可应用于数据库审计、复制、备份、排错等方面。
关键词: 数据库 oracle redo log 事务 监控
一、引言
Oracle数据库的一个重要的特性就是使用redo log。Oracle通过redolog技术实现事务(transaction)恢复和数据库恢复,而且是实现oracle事务完整性的一个重要手段。除此以外,还可通过redo log对数据库所有事务进行跟踪,对数据库所有操作进行监控。因为redo log保留数据库所有事务信息和物理操作信息。
要通过redo log对数据库进行跟踪和监控,就需要对redo log有深入的了解。Oracle通过循环写设定的几个Redo log文件来保存过去和现在的事务信息。如果使用了归档(Archive)模式,则通过归档保存所有Redo log信息。
二、Redo log文件分析
Redo log为二进制格式文件,文件分为文件头和文件体两个部分。
我们首先对redo log的文件头进行分析。
Redo log 文件按块存储,每块大小为512bytes或1K、2K等,其中文件的第一、二块为文件头,第一块含文件块大小,总共块的个数信息。下面为第一块的示例:
00000000 00 00 00 00 00 02 00 00 00 08 00 00 6D 6C 6B 6A
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
。。。。。
其中块大小为00 02 0000 即512 bytes,redo log文件总共有00 08 00 00即2048块。其中数据的字节长度和字节顺序要根据cpu、机器不同,有所不同。这里和下面均根据cpu为Intel Pentium cpu,系统为windows2000操作系统的环境为例。
C语言表示的结构如下
typedef struct filehead0
{
unsigned long nouse;
unsigned long blocksize;
unsigned long blockcount;
unsigned long xlabel;
} redoblock0;
第二块为redo log文件的版本号,兼容版本号,数据库ID号,数据库名,控制顺序号,文件大小,redo log文件序号,文件块大小,文件类型等redo基本信息。
下面为第二块的示例:
00000200 B1 02 00 0001 00 00 00 7D 69 E1 1A 00 00 11 0C
00000210 00 00 10 0800 00 10 08 60 BD 45 3A 4F 52 43 4C
00000220 00 00 00 004E 08 00 00 00 08 00 00 00 02 00 00
00000230 01 00 02 0000 00 00 00 00 00 00 00 00 00 00 00
00000240 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00
00000250 00 00 00 0000 00 00 00 00 00 00 00 54 68 72 65
00000260 61 64 20 3030 30 31 2C 20 53 65 71 23 20 30 30
00000270 30 30 30 3030 36 38 39 2C 20 53 43 4E 20 30 78
00000280 30 30 37 6433 31 31 63 33 37 64 37 2D 30 78 66
00000290 66 66 66 6666 66 66 66 66 66 66 00 FF FF FF FF
000002A0 E0 71 D0 1A01 00 00 00 00 00 00 00 02 00 00 00
000002B0 01 00 00 00D7 37 1C 31 7D 00 1C 01 7C 69 E1 1A
000002C0 FF FF FF FFFF FF 00 00 41 7E DE 1A 01 00 00 00
000002D0 01 00 00 0000 00 00 00 E5 71 D0 1A D7 37 1C 31
000002E0 7D 00 1C 017C 69 E1 1A 00 00 00 08 00 00 00 00
000002F0 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00
00000300 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00
从第二块起,每块都有一个块头,含redo log顺序号,块号等信息,此例的块头为B1 02 00 00 01 00 0000 7D 69 E1 1A 00 00 11 0C,其中redo log顺序号为0x000002B1,块号为0x00000001。
下面就是文件版本号为0x08100000,兼容版本号为0x08100000,数据库ID号为0x3a45bd60,数据库名为'ORCL',控制顺序号为0xa68,文件大小为0x800块,redo log文件序号为1,文件块大小为512 bytes,文件类型为2即redolog文件类型。
C语言表示的结构如下:
struct blockhead
{
unsigned long blocksequence;
unsigned long blocknumber;
unsigned long time;
unsigned short offset;
unsigned short checksum;
};
struct scn1
{
unsignedlong SCNbase;
unsigned shortSCNwrapper;
unsigned shortfiller;
};
struct filehead1
{
structblockhead head1_blockhead;
unsigned long software_vsn;
unsigned long compatibility_vsn;
unsigned long DBid;
byte DBname[8];
unsigned long controlseq;
unsigned long filesize;
unsigned long blocksize;
unsigned short filenumber;
unsigned short filetype;
byte filler4[0x28];
byte descript[0x40];
unsigned long nab; //nextavailable block
unsigned long resetcount;
struct scn1 resetscn;
unsigned long hws; //hdrwrite seq
unsigned long thread;
struct scn1 lowscn;
unsigned long lowscntime;
struct scn1 nextscn;
unsigned long nextscntime;
unsigned short eot; //end of thread
unsigned short dis; //true if thread disabled at end of thislog
struct scn1 enablescn;
unsigned long enablescntime;
struct scn1 threadclosescn;
unsigned long tcstime;
unsigned long logformat_vsn;
};
第三块以后为文件体,下面我们对文件体进行分析:
文件体由redo记录组成,redo记录又散布到redolog文件的数据块当中。redo记录可能在一个数据块中,也可能在多个数据块中,一个数据块也可能含有多个redo记录。
文件体的每个数据块由块头和数据组成,块头由redo log顺序号sequence,块号blocknumber,块更新时间,第一个redo记录的位置offset,以及校验和checksum组成,块头含有redo记录的redo块地址rba(redoblock address: sequence.blocknumber.offset)。
块头示例如下:
00000600 B1 02 00 00 03 00 00 00 80 69 E1 1A 10 00 00 00
sequence= 0x2B1
blocknumber=0x3
write time=0x1AE16980
offset = 0x10
块头C语言的结构如下:
struct blockhead
{
unsigned long sequence;
unsigned long blocknumber;
unsigned long time;
unsigned short offset;
unsigned short checksum;
};
块的数据为redo记录。Redo记录含有oracle数据库所有事务的信息和所有物理操作的信息。
我们通过具体分析下面一个示例来说明redo记录的结构。
00000600 B1 02 00 00 03 00 00 00 80 69 E1 1A 10 00 00 00
00000610 5C 02 00 00 01 00 7D 00 D9 37 1C 31 05 02 0B 00
00000620 01 00 00 00 02 00 40 00 B3 E9 1B 31 7D 00 00 00
00000630 01 00 00 00 04 00 20 00 2C 00 00 00 22 00 00 00
00000640 10 00 40 00 1F 00 1A 31 12 04 D4 00 00 10 A9 00
00000650 00 00 00 00 00 00 00 00 05 01 0C 00 01 00 00 00
00000660 10 00 40 00 B2 E9 1B 31 7D 00 00 00 01 00 00 00
00000670 22 00 14 00 30 00 1C 00 1E 00 16 00 03 00 02 00
00000680 02 00 02 00 06 00 03 00 03 00 03 00 01 00 02 00
00000690 02 00 00 00 D4 00 F0 0A 12 00 00 00 00 00 2C 00
000006A0 22 00 00 00 1F 00 1A 00 0F 00 00 00 0F 00 00 00
000006B0 00 00 00 00 00 00 00 00 0B 01 2C 00 08 00 01 00
000006C0 10 00 40 00 1F 00 19 31 D8 C7 01 00 00 00 00 00
000006D0 D9 C7 01 00 00 00 00 00 04 01 00 00 00 00 22 00
000006E0 22 00 00 00 10 00 40 00 1F 00 19 31 00 80 7D 00
000006F0 B3 E9 1B 31 3A 00 40 00 39 00 40 00 FF 12 05 01
00000700 01 00 7C 03 2C 00 00 00 02 00 0C 0B 00 00 00 00
00000710 00 00 00 00 01 00 02 00 03 00 04 00 05 00 06 00
00000720 07 00 08 00 09 00 0A 00 0B 00 00 00 52 42 30 00
00000730 C1 02 00 00 C1 03 00 00 C1 03 00 00 C5 09 18 5A
00000740 1D 34 00 00 C2 02 1A 00 C2 02 16 00 C2 02 2A 00
00000750 80 00 00 00 C1 04 00 00 C1 02 00 00 0B 05 01 00
00000760 01 00 00 00 3A 00 40 00 B3 E9 1B 31 7D 00 00 00
00000770 01 02 00 00 1E 00 3C 00 1E 00 16 00 03 00 02 00
00000780 02 00 02 00 06 00 03 00 03 00 03 00 01 00 02 00
00000790 02 00 00 00 11 01 00 00 00 00 2C 00 22 00 00 00
000007A0 10 00 40 00 1F 00 1A 31 00 00 00 00 00 00 00 00
000007B0 00 00 00 00 00 00 00 00 00 00 00 00 02 01 01 00
000007C0 D9 37 1C 31 7D 00 00 00 01 02 7D 00 B3 E9 1B 31
000007D0 3A 00 40 00 39 00 40 00 FF 12 05 01 01 00 7C 03
000007E0 2C 01 00 00 02 00 0C 0B 00 00 00 00 00 00 00 00
000007F0 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00
redo记录由记录头,change项组成,记录头的C语言结构表示为
struct recordhead
{
unsigned long recordlength;
unsigned short VLD;
unsigned short recscnwrapper;
unsigned long recscnbase;
};
recordlength 为redo记录的长度,recscnwrapper、recscnbase合起来为redo 记录的SCN(system change number),SCN是oracle数据库中最重要的数据之一,SCN由一个单独的线程产生,相当于系统的一个时间戳,oracle的操作可根据SCN来排序,系统分配每一个事务唯一的一个SCN值,事务可根据SCN来排序。
示例中 recordlength=0x025c
VLD=1
Recscnwrapper=0x7d
Recscnbase=0x311c37d9
change项由change头, change索引表,change数据体组成。
change头的C语言结构表示为
struct changehead
{
struct opcode OP;
unsigned short CLS;
unsigned long AFN; //absolatefile number
unsigned long DBA; //10Bit=FileNO. and 22Bit=Block NO.
struct scn1 SCN;
byte SEQ; //sequence
byte TYP; //1=data2=index 0=others
unsigned short filler;
};
OP为操作码表示oracle不同的数据操作。AFN为数据所在文件号,DBA(Data block address)为数据块的地址,前10个bit表示文件号,后22个bit表示块号。TYP表示数据类型。
示例中第一个change项的change头的值为:
OP = 5.2
CLS =0x0b
AFN =1
DBA = 0x00400002
SCN =0x007d.311be9b3
SEQ = 1
TYP = 0
change索引表由索引表大小项(2个字节)(表示索引表字节长度),索引表项(各两个字节)(表示change各项的字节长度)组成。
如上例所示第一个change项的索引表为04 00 20 00 可以看出,索引表大小为0x0004个字节,表示只有一个表项,0x0020,表示change第一项的大小为0x0020个字节。
change数据体的结构根据change头操作码OP不同而不同。
由于操作码OP较多,下面只说明最常见的,也是最重要的几种操作码OP,其change数据体的结构。
1、 OP=5.2 xid header
CHANGE #1 TYP:0 CLS:11 AFN:1 DBA:0x00400002SCN:0x007d.3122328a SEQ: 1 OP:5.2
ktudh redo: slt: 0x0023 sqn: 0x00000025 flg: 0x0412 siz:212 fbi: 0
uba: 0x00400091.0020.08 pxid: 0x0000.000.00000000
OP=5.2 修改回滚段(rollback segment)的头,主要是在rollback segment头的事务表(xid table)中添加事务信息,一个事务的开始一定会在事务表中添加一条信息。此例显示rollbacksegment的事务表的slt(slot)0x0023中添加事务信息,其事务的undo block address为0x00400091.0020.08,其中0x00400091为文件块地址,0020为顺序号,08为记录号。回滚记录的大小为212个字节。
同时DBA=0x00400002表示此数据块地址,显示此rollback segment的事务表在文件的第二块中。
2、 OP=5.1 rollback segment
CHANGE #2 TYP:0CLS:12 AFN:1 DBA:0x00400091 SCN:0x007d.31223289 SEQ: 1 OP:5.1
ktudb redo: siz: 212spc: 6652 flg: 0x0012 seq: 0x0020 rec: 0x08
xid: 0x0000.023.00000025
ktubl redo: slt: 35rci: 0 opc: 11.1 objn: 15 objd: 15 tsn: 0
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
TablespaceUndo: No
0x00000000 prev ctl uba: 0x00400091.0020.07
prev ctl max cmtscn: 0x007d.311ffcad prev tx cmt scn: 0x007d.31206e62
KDO undo record:
KTB Redo
op: 0x04 ver: 0x01
op: L itl: scn: 0x0000.015.00000025 uba: 0x00400091.0020.07
flg: C--- lkc: 0 scn: 0x007d.3122328a
KDO Op code:URP xtype: XA bdba: 0x0040003a hdba: 0x00400039
itli: 1 ispac: 0 maxfr: 4863
tabn: 0 slot: 3(0x3)flag: 0x2c lock: 0 ckix: 0
ncol: 12 nnew: 11size: 0
col 1: [ 3] 52 42 31
col 2: [ 2] c1 02
col 3: [ 2] c1 03
col 4: [ 2] c1 35
col 5: [ 6] c5 09 19 1d 2f 5b
col 6: [ 3] c2 02 1a
col 7: [ 3] c2 02 16
col 8: [ 3] c2 02 32
col 9: [ 1] 80
col 10: [ 2] c1 03
col 11: [ 2] c1 02
OP=5.1 为rollback segment的数据变化,包含数据库操作前的旧数据,用于一致性读和回滚。
此第一项中 rollback记录的大小为siz:212,顺序号为seq: 0x0020,记录号为rec 0x08,事务ID号为 xid: 0x0000.023.00000025,xid唯一标识一个事务。
这些数据刚好与OP=5.2的数据相对应。
第二项数据表示操作的数据对应的数据库对象, 数据块对象号objn: 15 数据块数据对象号objd: 15 表空间号tsn: 0 slot号slt: 35 记录索引数rci: 0 对数据的操作码opc: 11.1
第三项记录详细的数据信息,有详细的数据块信息,有数据操作码URP,dba(data block address), flag, lock,slot 及数据列的信息。
3、 OP=11.5 UPDATE
CHANGE #3 TYP:2 CLS:1 AFN:1 DBA:0x0040003a SCN:0x007d.3122328a SEQ: 1 OP:11.5
KTB Redo
op: 0x11 ver: 0x01
op: F xid: 0x0000.023.00000025 uba:0x00400091.0020.08
Block cleanoutrecord, scn: 0x007d.3122328b ver: 0x01,entries follow...
itli: 1 flg: 2 scn: 0x007d.3122328a
KDO Op code:URP xtype: XA bdba: 0x0040003a hdba: 0x00400039
itli: 1 ispac: 0 maxfr: 4863
tabn: 0 slot: 3(0x3)flag: 0x2c lock: 1 ckix: 0
ncol: 12 nnew: 11size: 0
col 1: [ 3] 52 42 31
col 2: [ 2] c1 02
col 3: [ 2] c1 03
col 4: [ 2] c1 35
col 5: [ 6] c5 09 19 1d 2f 5b
col 6: [ 3] c2 02 1a
col 7: [ 3] c2 02 16
col 8: [ 3] c2 02 32
col 9: [ 1] 80
col 10: [ 2] c1 03
col 11: [ 2] c1 02
OP=11.5 记录,数据块数据更改(UPDATE)的详细信息,还包括事务ID号(xid)的信息。这里xid: 0x0000.023.00000025 Undo Block Address(UBA): 0x00400091.0020.08
4、 OP=5.19 session info & username
CHANGE #4 MEDIARECOVERY MARKER SCN:0x0000.00000000 SEQ: 0 OP:5.19
session number = 17
serial number = 1
current username =SYS
login username =
client info =
OS username =
Machine name =
OS terminal =
OS process id =
OS program name =
OP=5.19 记录事务对应的Session信息,包括session number = 17 ,用户名current username = SYS 等。
5、 OP=5.4 commit
CHANGE #1 TYP:0CLS:11 AFN:1 DBA:0x00400002 SCN:0x007d.3122328b SEQ: 1 OP:5.4
ktucm redo: slt:0x0023 sqn: 0x00000025 srt: 0 sta: 9 flg: 0x2
ktucf redo: uba:0x00400091.0020.08 ext: 2 spc: 6438 fbi: 0
OP=5.4 记录事务提交信息,包括commit SCN, 事务表块号DBA,及事务其他信息slot, sequence,UBA等。
6、 OP=11.2 insert
CHANGE #3 TYP:2 CLS:1 AFN:1 DBA:0x004048be SCN:0x007d.3122811d SEQ: 1 OP:11.2
KTB Redo
op: 0x11 ver: 0x01
op: F xid: 0x0004.050.00000079 uba:0x008007b9.00a3.40
Block cleanout record,scn: 0x007d.3122cf6d ver: 0x01, entriesfollow...
itli: 1 flg: 2 scn: 0x007d.3122811d
KDO Op code:IRP xtype: XA bdba: 0x004048be hdba: 0x0040003d
itli: 1 ispac: 0 maxfr: 4863
tabn: 0 slot:59(0x3b) size/delt: 65
fb: --H-FL-- lb: 0x1cc: 14
null:
01234567890123456789012345678901234567890123456789012345678901234567890123456789
-----N-----NN-
col 0: [ 4] c3 02 1f 13
col 1: [ 4] c3 02 1f 13
col 2: [ 2] c1 23
col 3: [10] 54 55 53 45 52 5f 54 59 50 45
col 4: [ 2] c1 06
col 5: *NULL*
col 6: [ 2] c1 04
col 7: [ 7] 78 66 02 07 10 2c 20
col 8: [ 7] 78 66 02 07 10 2c 20
col 9: [ 7] 78 66 02 07 10 2c 20
col 10: [ 2] c1 02
col 11: *NULL*
col 12: *NULL*
col 13: [ 1] 80
OP=11.2记录数据块数据插入(Insert)的详细信息
7、 OP=11.3 delete
CHANGE #3 TYP:0 CLS:1 AFN:1 DBA:0x00404f14 SCN:0x007d.3122329b SEQ: 1 OP:11.3
KTB Redo
op: 0x01 ver: 0x01
op: F xid: 0x0004.055.00000079 uba:0x008007b9.00a3.03
KDO Op code:DRP xtype: XA bdba: 0x00404f14 hdba: 0x00404f13
itli: 2 ispac: 0 maxfr: 4863
tabn: 0 slot: 1(0x1)
OP=11.3记录数据块数据删除(delete)的详细信息
三、事务跟踪
从上一节的分析可以看出,redo log不仅记录所有的数据操作信息,还记录下所有的事务的信息。
下面说明一个完整事务的跟踪过程,
当一个事务开始时,事务的第一条redo记录,含有OP=5.1 OP=5.2 OP=5.19的change项,OP=5.2有xid号为事务的唯一标识,OP=5.1的DBA为此事务表的rollback segment块地址 OP=5.1还含有slt, sqn。 DBA,slt,sqn也唯一标识这个事务。
OP=5.19含有此事务的Session信息。
以后此事务上的所有数据操作,其redo log记录都有xid,可以通过xid号来跟踪此事务。
因为SCN号标识了操作顺序,可根据SCN将操作排序。
事务都以OP=5.4结束, OP=5.4也含有唯一此事务的DBA,slt,sqn。对应事务开始时OP=5.2的DBA,slt,sqn.
从而可跟踪数据库完整的事务过程。
四、结论
本文详细分析了redo log文件格式和内容,并分析了redo log中包含的数据操作信息,事务操作信息等。利用这些内容,从而可通过 redolog文件(或归档Archive文件,归档文件为redolog文件的复制品)配合数据库的控制文件来实时监控数据库的所有操作。这种跟踪和监控,因为只进行文件操作,速度快,不受数据库本身功能的影响,也不会影响数据库的性能。对oracle数据库的这种跟踪和监控,可应用于数据库审计、复制、备份、排错等方面。