You are on page 1of 7

1     数据结构

使用 MAP 命令查看如下:
BBED>map
 File: /home/oracle/toad01.dbf(75)
 Block: 133                        Dba:0x12c00085
 KTB Data Block (Table/Cluster)
 struct kcbh, 20bytes                     @0      --块头信息,cache layer
 struct ktbbh, 72bytes                    @20     --事务信息,transaction layer
 struct kdbh, 14bytes                     @100    --对应数据头,占用 14 字节
 struct kdbt[1], 4bytes                   @114    --表目录*kdbt[0]指针显示值
 sb2kdbr[3]                               @118    --行目录 *kdbr[0]指针值显示状态 flg
 ub1 freespace[8028]                       @124    --空闲空间
 ub1 rowdata[36]                           @8152   --行数据
 ub4tailchk                               @8188   --tail check

这个是文件 75,块 133 的,整个块的数据结构。可以看到行数据时从下开始增加的,空闲


的空间是在中间。后面@开头的表示在该块的偏移。@0 表示从该块首开始,@20 表示从第
20 个字节开始。那么 0~19 个字节就是 block-header 的信息了。

将 8KB 的数据展开后如下块内容部分,很难看。蛤蟆通过 BBED 知道了块的结构,我们将


块进行划分使用不同的颜色来标注,如下颜色标注。每行 32 个字节,例如 06a20000 有 4 个
字节,每两个 16 进制数就是 1 个字节(1 个 16 进制数是 4 位,2 个就是 8 位,8 位就是一
个字节)。

可以发现表目录只有一项,因为就保存了表 t1 的数据,行目录 3 项,因为就 3 行数据。


这两蛤蟆判断应该是可变的。

这个图和 MAP 出来的块结构信息是可以一一对应的,从上到下。不过在交易层也是有可变


的。
根据块的逻辑结构来分析下实际 DUMP 得到的数据块数据,看是否能够对应起来。
1.1 struct kcbh 块头 20 字节
06a20000 8500c012 dd6d5e81 00000106 97520000
第 1 个字节:TYPE=06
第 2 个字节:FMT=A2 (一般是 0x02,此处是 0xa2,用掩码 0x0f 与运算可以取出 0x02(掩码
是为了保护敏感信息))
第 5-8 个字节:RDBA=8500c012 换成从大到小就是 12C00085
第 9-12 个字节:SCNBase= dd6d5e81 换成从大到小就是 815E6DDD
第 13-14 个字节:SCNWrap=0000
第 15 个字节:Seq=01 当这个 byte 的数据为 0xff 的时候标志 block 坏调了,出现 ora-01578
第 16 个字节:Flg=06
Flg 描述如下,在 kcbh.h 头文件中定义:
0x01 /* new block -zeroed data area */
0x02 /* Delayed LoggingChange advance SCN/seq */
0x04 /* ChecK Valuesaved-block xor's to zero */
0x08 /* Temporary block*/
第 17-18 个字节:ChkVal=9752 换成从大到小就是 5297
Filler 当前都不使用 4 个字节都是 0000 了。
Tail=SCNBase(低位 2 字节)+块类型+SCN Seq=6DDD+06+01=6DDD0601

这 20 个字节的结构体如下图 3:
1.2 struct ktbbh 事务信息 80 个字节
0100000093720100 db6d5e81
?00000000 02003200 8000c01254010e00 e6a40000 7c068000 290a0f00 01200000
?dd6d5e81 af002100 2f450200 a40a8000 1311100000800000 d46d5e81 00000000
?00000000
第 21-24 个字节:Tyte=01000000 表示块类型换成从大到小就是 00000001 (1 是 DATA,2 是
INDEX)
第 25-28 个字节:Seg/obj=93720100 表示块对象换成从大到小就是 0x17293
第 29-36 个字节:CSC= db6d5e8100000000 块上次全清除的 SCN 号,换成从大到小就是
00000000815e6ddb
第 37 字节:Fsl=02,在 ITL 自由列表上的第一个槽位
第 38 字节:flg=00,
第 39-40 字节: itc=0x3200 换成从大到小就是 0x0032,占 2 个字节。值为 50(ITL 条目的个
数 max 255 超过会报 ORA-02207 ORA-00060 ORA-00054 可能是没空间分配 itl 条目了或它
的争用引起的,在 8i 中 INITRANS default 为 1 , 9.2.0 中 INITRANS default 为 2, 12c 是 50)
第 41-44 字节:自由列表下一块地址 8000c012 换成从大到小就是 12C00080
从 45 字节开始就是 ITL 记录,每个 ITL 占用 24 个字节
本块含有两个 ITL 记录
54010e00e6a40000 7c068000 290a0f00 01200000 dd6d5e81
af0021002f450200 a40a8000 13111000 00800000 d46d5e81
第 45-52 字节,XID=54010e00 e6a40000 转换过来就是 0x0154.00e.0000a4e6
第 53-60 字节,UBA=7c068000 290a0f00 转换过来就是 0x0080067c.0a29.0f
第 61-62 字节,lck flag=0120,即 0x2001,表示状态和锁住的行。2=0b0010,就是 - - U -,1 表示
锁住一行。
C = Committed; U = Commit Upper Bound; T =Active at CSC; B = Rollback of this UBA gives
before image of the ITL.
---- = transaction is active, or committedpending cleanout
C--- = transaction has been committed andlocks cleaned out
-B-- = this undo record contains the undofor this ITL entry
--U- = transaction committed (maybe longago); SCN is an upper bound
---T = transaction was still active atblock cleanout SCN
Lck 3 nibbles
The number of row-level locks held in theblock by this transaction.
第 63-68 字节,表示 scn/fsc: 0000dd6d5e81 , 转换后就是 0x0000.815e6ddd

1.3 struct kdbh 数据头 14 个字节


00010300 ffff1800 741f5c1f 5c1f
第 69 字节:flag=00,
第 70 字节:ntab=1,块中的表数量,大于 1 表示是簇。
第 71 字节:nrow=3,块中的行数量
第 72 字节:表示 frre,? First free row index entry. -1=you have toadd one
第 73 字节:fsbo=0x18 Free Space Begin offset 从数据头开始偏移 0X18 个字节,就是 24 个
字节后就是空闲空间了。
第 74-75 字节:fseo=0x1f74Free Space End offset 空闲空间结束的偏移 8052.
第 76-77 字节:avsp=0x1f5cAvailable space in the block (pctfree and pctused) 8028 个可以用字
节。
第 78-79 字节:tosp=0x1f5cTotal available space when all TXs commit 提交后可用字节。

1.4 struct kdbt[1]表目录 4 个字节


0000 0300

1.5 sb2 kdbr[3]行目录 6 个字节?


8c1f801f741f 每个两个字节,分别是 0x1f8c,0x1f80,0x1f74 分别是 8076,8064,,8052(块共
8192)

1.6 ub1 freespace 空闲空间 8028 个字节


都是 000000000。

1.7 ub1 rowdata 行数据 36 个字节


2c010202 c1040544? 444444442c000202 c1030542 42424242 2c000202 c1020541 42434544
在此块中每行占用 12 个字节。
如前面 12 个字节
2c010202 c1040544? 44444444
第一个字节:2c 表示--H-FL- -,用比特位表示就是 0010 1100 ,16 进制就是 2C,就是第一
个字节
第二个字节:01 ,是 lb(lock byte)是锁字节,和 ITL 中的行锁一样。影响了多少行
第三个字节:02,表示列数量,2 个列
第四个字节:02,表示第一个列的字节数是 2 个
第五,六字节:第一个列的内容:c1 04,3 存储在数据库就是 c1 04,如下测试:
SQL> select dump(3,16) from dual;
DUMP(3,16)
-----------------
Typ=2 Len=2: c1,4
第 7 字节:第二个列的字节数是 5 个
第 8~12 字节:第二个列的内容:44444444,就是字符串:DDDDD
1.8 ub4 tailchk?尾部检测 4 个字节
0106dd6d
Tail=SCNBase(低位 2 字节)+块类型+SCN Seq=6DDD+06+01=6DDD0601

2 BBED DUMP 的块内容


BBED> dump dba 75,133 offset 0 count8192
File: /home/oracle/toad01.dbf (75)
Block: 133 Offsets: 0 to 8191 Dba:0x12c00085
------------------------------------------------------------------------
06a20000 8500c012 dd6d5e8100000106 975200000100000093720100 db6d5e81
00000000 02003200 8000c01254010e00 e6a40000 7c068000 290a0f00 01200000
dd6d5e81 af002100 2f450200 a40a8000 1311100000800000 d46d5e81 00000000
00000000 00010300 ffff1800 741f5c1f5c1f0000 03008c1f 801f741f00000000
00000000 00000000 0000000000000000 00000000 00000000 00000000 00000000
00000000 00000000 0000000000000000 00000000 00000000 00000000 00000000
00000000 00000000 0000000000000000 00000000 00000000 00000000 00000000

00000000 00000000 0000000000000000 00000000 00000000 00000000 00000000


00000000 00000000 0000000000000000 00000000 000000002c010202 c1040544
44444444 2c000202 c103054242424242 2c000202 c1020541 424345440106dd6d
<32 bytes per line>

3 ALTER SYSTEM DUMP DATAFILE 内容


使用 ALTER SYSTEM DUMP 得到的值显示方式和使用 BBED DUMP 得到的有些不太一样。
这就是大小端的问题了。使用 ALTERSYSTEM DUMP 的,是 0000A206,是小端靠后,而
使用 BBED 的话已经是大段靠后了。
Start dump data blocks tsn: 13 file#:75minblk 133 maxblk 133
Block dump from cache:
Dump of buffer cache at level 4 for pdb=0tsn=13 rdba=314572933
Block dump from disk:
buffer tsn: 13 rdba: 0x12c00085 (75/133)
scn: 0x0.815e6ddd seq: 0x01 flg: 0x06 tail:0x6ddd0601
frmt: 0x02 chkval: 0x5297 type: 0x06=transdata
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00007FB63DBA0200 to0x00007FB63DBA2200
7FB63DBA0200 0000A206 12C00085 815E6DDD06010000 [.........m^.....]
7FB63DBA0210 00005297 00000001 00017293815E6DDB [.R.......r...m^.]
7FB63DBA0220 00000000 00320002 12C00080000E0154 [......2.....T...]
7FB63DBA0230 0000A4E6 0080067C 000F0A2900002001 [....|...).... ..]
7FB63DBA0240 815E6DDD 002100AF 0002452F00800AA4 [.m^...!./E......]
7FB63DBA0250 00101113 00008000 815E6DD400000000 [.........m^.....]
7FB63DBA0260 00000000 00030100 0018FFFF1F5C1F74 [............t.\.]
7FB63DBA0270 00001F5C 1F8C0003 1F741F8000000000 [\.........t.....]
7FB63DBA0280 00000000 00000000 0000000000000000 [................]
Repeat 500 times
7FB63DBA21D0 00000000 00000000 0202012C440504C1 [........,......D]
7FB63DBA21E0 44444444 0202002C 420503C142424242 [DDDD,......BBBBB]
7FB63DBA21F0 0202002C 410502C1 444543426DDD0601 [,......ABCED...m]
Block header dump: 0x12c00085
Object id on Block Y
seg/obj: 0x17293 csc: 0x00.815e6ddb itc: 2flg: E typ: 1 - DATA
brn: 0 bdba: 0x12c00080 ver: 0x01opc: 0
inc: 0 exflg: 0

ItlXid Uba FlagLck Scn/Fsc


0x010x0154.00e.0000a4e60x0080067c.0a29.0f --U- 1fsc 0x0000.815e6ddd
0x020x00af.021.0002452f 0x00800aa4.1113.10 C---0 scn 0x0000.815e6dd4
bdba: 0x12c00085
data_block_dump,data header at0x7fb63dba0264
===============
tsiz: 0x1f98
hsiz: 0x18
pbl: 0x7fb63dba0264
76543210
flag=--------
ntab=1
nrow=3
frre=-1
fsbo=0x18
fseo=0x1f74
avsp=0x1f5c
tosp=0x1f5c
0xe:pti[0] nrow=3 offs=0
0x12:pri[0] offs=0x1f8c
0x14:pri[1] offs=0x1f80
0x16:pri[2] offs=0x1f74
block_row_dump:
tab 0, row 0, @0x1f8c
tl: 12 fb: --H-FL-- lb: 0x0 cc: 2
col0: [ 2] c1 02
col1: [ 5] 41 42 43 45 44
tab 0, row 1, @0x1f80
tl: 12 fb: --H-FL-- lb: 0x0 cc: 2
col0: [ 2] c1 03
col1: [ 5] 42 42 42 42 42
tab 0, row 2, @0x1f74
tl: 12 fb: --H-FL-- lb: 0x1 cc: 2
col0: [ 2] c1 04
col1: [ 5] 44 44 44 44 44
end_of_block_dump
End dump data blocks tsn: 13 file#: 75minblk 133 maxblk 133
4DD 命令 DUMP 块内容
此外还可以使用操作系统的命令来 DUMP 块内容,命令如下:
#dd bs=8192 if=toad01.dbf skip=133 count=1 | od –x> file.out
Dump 数据文件 toad01.dbf 中的第 134 个 BLOCK(133#)
#vi file.out
内容如下,区别就是是 2 个字节一小段
0000000 a206 0000 0085 12c0 6ddd 815e 00000601
0000020 5297 0000 0001 0000 7293 0001 6ddb815e
0000040 0000 0000 0002 0032 0080 12c0 0154000e
0000060 a4e6 0000 067c 0080 0a29 000f 20010000
0000100 6ddd 815e 00af 0021 452f 0002 0aa40080
0000120 1113 0010 8000 0000 6dd4 815e 00000000
0000140 0000 0000 0100 0003 ffff 0018 1f74 1f5c

You might also like