接上篇http://blog.csdn.net/ashic/article/details/44117867
上篇中我们dump出了L1 L2 L3块,现在来了解一下它们中包含的信息
内容 | 注释 |
---|---|
L1 | FIRST LEVEL BITMAP BLOCK |
L2 | SECOND LEVEL BITMAP BLOCK |
L3(段头) | PAGETABLE SEGMENT HEADER |
通过上面的表格再去看Dump文件我们可以很清楚的发现
在这个uniform size 1M的表空间中,一个区中又两个L1块,1个L2,1个L3
第一个L1块中
Dump of First Level Bitmap Block
--------------------------------
nbits : 4 nranges: 1 parent dba: 0x01800082 poffset: 0
unformatted: 60 total: 64 first useful block: 4
owning instance : 1
instance ownership changed at 03/07/2015 17:19:38
Last successful Search 03/07/2015 17:19:38
Freeness Status: nf1 0 nf2 0 nf3 0 nf4 0
Extent Map Block Offset: 4294967295
First free datablock : 4
Bitmap block lock opcode 9
Locker xid: : 0x0006.020.00000594
Dealloc scn: 2275418.0
Flag: 0x00000021 (OBJD/-/-/-/-/HWM)
Inc #: 0 Objd: 77412
HWM Flag: HWM Set
Highwater:: 0x01800084 ext#: 0 blk#: 4 ext size: 128
#blocks in seg. hdr‘s freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
parent dba: 0x01800082表是管理它的L2块位置
可以通过DBMS_UTILITY.DATA_BLOCK_ADDRESS包来得出L1块位置
[email protected]>select dbms_utility.data_block_address_file(TO_NUMBER(‘&entervalue‘, ‘XXXXXXXX‘)) file_id,dbms_utility.data_block_address_block(TO_NUMBER(‘&entervalue‘, ‘XXXXXXXX‘)) block_id from dual;
Enter value for entervalue: 01800082
Enter value for entervalue: 01800082
FILE_ID BLOCK_ID
---------- ----------
6 130
unformatted: 60 total: 64 first useful block: 4
表示未格式化的块有60个,此L1总共管理64个数据块,第一个可用的数据块是4号块,也就是6号文件的132号块
HWM Flag: HWM Set
Highwater:: 0x01800084 ext#: 0 blk#: 4 ext size: 128
高水位先在 0x01800084 也就是6号文件第132好块,这是因为FAN表在我刚才的试验中被TRUNCATE了没有数据,所以高水位线在第一个可用块
需要注意的一点是,ASSM中高水位线的移动规则是: 当在区中插入第一行时,高水点移到区的第一个 L1
块中最大的数据块后。然后在移动到第二个L2块中最大的数据块后,以此类推
ext#:0 表示第一个区
blk#:4 第四个块
ext size: 128 该区包含128个块
--------------------------------------------------------
DBA Ranges :
--------------------------------------------------------
0x01800080 Length: 64 Offset: 0
0:Metadata 1:Metadata 2:Metadata 3:Metadata
4:unformatted 5:unformatted 6:unformatted 7:unformatted
8:unformatted 9:unformatted 10:unformatted 11:unformatted
12:unformatted 13:unformatted 14:unformatted 15:unformatted
16:unformatted 17:unformatted 18:unformatted 19:unformatted
20:unformatted 21:unformatted 22:unformatted 23:unformatted
24:unformatted 25:unformatted 26:unformatted 27:unformatted
28:unformatted 29:unformatted 30:unformatted 31:unformatted
32:unformatted 33:unformatted 34:unformatted 35:unformatted
36:unformatted 37:unformatted 38:unformatted 39:unformatted
40:unformatted 41:unformatted 42:unformatted 43:unformatted
44:unformatted 45:unformatted 46:unformatted 47:unformatted
48:unformatted 49:unformatted 50:unformatted 51:unformatted
52:unformatted 53:unformatted 54:unformatted 55:unformatted
56:unformatted 57:unformatted 58:unformatted 59:unformatted
60:unformatted 61:unformatted 62:unformatted 63:unformatted
--------------------------------------------------------
0x01800080表示L1块的位置
可以通过DBMS_UTILITY.DATA_BLOCK_ADDRESS包来得出L1块位置
[email protected]>set verify off
[email protected]>select dbms_utility.data_block_address_file(TO_NUMBER(‘&entervalue‘, ‘XXXXXXXX‘)) file_id,dbms_utility.data_block_address_block(TO_NUMBER(‘&entervalue‘, ‘XXXXXXXX‘)) block_id from dual;
Enter value for entervalue: 01800080
Enter value for entervalue: 01800080
FILE_ID BLOCK_ID
---------- ----------
6 128
这里块号其实不用包可以直接算
继续看我们可以发现L1块中管理了64个数据块,即128~191块
通过>75%,50%-75%,25%-50%和<25%来标记块的使用情况
目前我们的L1中管理的64个块0~3号块为metadata块,就是128,129,130,131块
4~63这60个块是数据块,状态为unformatted未格式化
什么是未格式化?
在上一篇中我们说过,初始情况下,表ID和段ID是一样的
[email protected]>select object_id,data_object_id from dba_objects where object_name=‘FAN‘;
OBJECT_ID DATA_OBJECT_ID
---------- --------------
77411 77411
表ID一旦创建就不会变化,但是段ID会变化,比如当Truncate该表后
scott@PROD>truncate table fan;
Table truncated.
scott@PROD>select object_id,data_object_id from dba_objects where object_name=‘FAN‘;
OBJECT_ID DATA_OBJECT_ID
---------- --------------
77411 77412
段ID和表ID不同后,格式化了的块就是块中记录的seg/obj号为段ID
没格式化的就是和truncate前的段ID一样
可以dump一个未格式化的快查看seg/obj,比较一下就知道了,我就不做实验了
继续看L2块
第二个L1和第一个L1差不多,不说了,看L2
Dump of Second Level Bitmap Block
number: 2 nfree: 2 ffree: 0 pdba: 0x01800083
Inc #: 0 Objd: 77412
opcode:4
xid:
L1 Ranges :
--------------------------------------------------------
0x01800080 Free: 5 Inst: 1
0x01800081 Free: 5 Inst: 1
--------------------------------------------------------
L2块中记录了pdba也就是L3块的地址0x01800083和L1块的地址
这里Free:5啥意思我不知道,╮(╯_╰)╭,谁知道告诉我吧
L3块
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 128
last map 0x00000000 #maps: 0 offset: 2716
Highwater:: 0x018000c0 ext#: 0 blk#: 4 ext size: 128
#blocks in seg. hdr‘s freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Unlocked
--------------------------------------------------------
Low HighWater Mark :
Highwater:: 0x01800084 ext#: 0 blk#: 4 ext size: 128
#blocks in seg. hdr‘s freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Level 1 BMB for High HWM block: 0x01800080
Level 1 BMB for Low HWM block: 0x01800080
这里要注意的是 Highwater:: 0x018000c0 Low HighWater Mark
:0x01800084 低高水位线和高高水位线
低高水位线以下的时已经格式化了的块
低高水位和高高水位之间的块,则可能是格式化了的,也可能是没有
引一张官方文档的的说明
总之你要记住的是 全表扫描时,通常都是读至低高水位线,然后根据位图去读低高与高高之间格式化过的块,避开未格式化的块
查看高水位线的方法最简单的就是dump段头块
[email protected]>select header_file,header_block from dba_segments where segment_name=‘FAN‘ and owner=‘SCOTT‘;
HEADER_FILE HEADER_BLOCK
----------- ------------
6 131
通过上面的命令可以轻松找出段头块
--------------------------------------------------------
Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0
L2 Array start offset: 0x00001434
First Level 3 BMB: 0x00000000
L2 Hint for inserts: 0x01800082
Last Level 1 BMB: 0x01800081
Last Level II BMB: 0x01800082
Last Level III BMB: 0x00000000
Map Header:: next 0x00000000 #extents: 1 obj#: 77412 flag: 0x10000000
Inc # 0
内容 | 注释 |
---|---|
First Level 3 BMB: 0x00000000 | 库超大、区超多、块超多时才出现 |
Last Level 1 BMB: 0x01800081 | 最后一个L1 BMB的地址 |
Last Level II BMB: 0x01800082 | 最后一个L2 BMB的地址 |
Last Level III BMB: 0x0000000 | 最后一个L3 BMB的地址 |
Extent Map
-----------------------------------------------------------------
0x01800080 length: 128
L3中记录的区的信息
第一个区开始自0x01800080,但是需要注意的是全表扫描是Oracle读取的并不是这里的区地图
而是下面的
Auxillary Map
--------------------------------------------------------
Extent 0 : L1 dba: 0x01800080 Data dba: 0x01800084
--------------------------------------------------------
Second Level Bitmap block DBAs
--------------------------------------------------------
DBA 1: 0x01800082
区0 第一个L1为0x01800080 第一个非元数据数据块为0x01800084
Oracle 全扫描时,是按照“Data dba : **” 后的 DBA 查找区的。但这里没有区长度,所以,上面那部分区地图信息还是要读的。