以SCOTT.EMP表为例
select file_id, block_id, blocks
from dba_extents
where owner = 'SCOTT'
and segment_name = 'EMP';
FILE_ID BLOCK_ID BLOCKS
4 344 8
select header_file, header_block, bytes, blocks, extents
from dba_segments
where owner = 'SCOTT'
and segment_name = 'EMP';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
4 346 65536 8 1
--select 8*8192 from dual --65536
如上所示,DBA_SEGMENTS 中的 HEADER_BLOCK 与 DBA_EXTENTS 的 BLOCK_ID 不同
(HEADER_BLOCK:文件ID为4的第346个块,区间的第一个块的BLOCK_ID为第344个块),
这个的原因如下:
一个segment的第一个区的第一个块是 FIRST LEVEL BITMAP BLOCK,第二个块是 SECOND LEVEL BITMAP BLOCK,
这两个块是用来管理free block的,第三个块是 PAGETABLE SEGMENT HEADER,这个块才是segment里的HEADER_BLOCK,
再后面的块就是用来记录数据的。所以344+2=346. 详细可以参考《循序渐进ORCLE:数据库管理、优化与备份》这本书的第5章。
下面我们创建一个表,测试一下是否也是这个规律,如下所示:
CREATE TABLE nick.MMM AS SELECT * FROM DBA_OBJECTS;
set line 222
COL SEGMENT_NAME FOR A32;
SELECT SEGMENT_NAME,FILE_ID,BLOCK_ID,BLOCKS
FROM DBA_EXTENTS
WHERE SEGMENT_NAME='MMM' AND OWNER='NICK'
ORDER BY BLOCK_ID ASC;
SELECT HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS
FROM DBA_SEGMENTS
WHERE OWNER = 'NICK'
AND SEGMENT_NAME = 'MMM';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
7 202 12582912 1536 27
如上所示,段对象 NICK.MMM 的header_block为202 ,而对应的区间的第一个块对象ID为200, 也是200+2=202,
确实是如此,那么我们来DUMP数据块看看,如下所示
alter system dump datafile 7 block 200;
alter system dump datafile 7 block 201;
alter system dump datafile 7 block 202;
select value from v$diag_info where name like 'De%';
第一个区的第一个块(block_id=9)是FIRST LEVEL BITMAP BLOCK,第二个块(block_id=10)是SECOND LEVEL BITMAP BLOCK,
这两个块是用来管理free block的,
第三个块(block_id=11)是PAGETABLE SEGMENT HEADER,
这个块才是segment里的HEADER_BLOCK,再后面的块就是用来记录数据的
Start dump data blocks tsn: 13 file#:7 minblk 200 maxblk 200
Block dump from cache:
Dump of buffer cache at level 3 for pdb=0 tsn=13 rdba=29360328
BH (0xdbf78cf0) file#: 7 rdba: 0x01c000c8 (7/200) class: 8 ba: 0xdb3d0000
set: 6 pool: 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 0,0
dbwrid: 0 obj: 87222 objn: 87222 tsn: [0/13] afn: 7 hint: f
hash: [0x99462408,0x99462408] lru: [0xdbf78c70,0xdbf79a80]
ckptq: [NULL] fileq: [NULL]
objq: [0x7b1545e0,0xdbf78c98] objaq: [0xdbf78ca8,0xdbf79ab8]
st: XCURRENT md: NULL fpin: 'ktspfwh6: ktspffbmb' fscn: 0x6dc8ca tch: 1
flags: block_written_once
LRBA: [0x0.0.0] LSCN: [0x0] HSCN: [0x6dc91a] HSUB: [30]
Printing buffer operation history (latest change first):
cnt: 12
01. sid:07 L192:kcbbic2:bic:FBD 02. sid:07 L191:kcbbic2:bic:FBW
03. sid:07 L602:bic1_int:bis:FWC 04. sid:07 L822:bic1_int:ent:rtn
05. sid:07 L832:oswmqbg1:clr:WRT 06. sid:07 L930:kubc:sw:mq
07. sid:07 L913:bxsv:sw:objq 08. sid:07 L608:bxsv:bis:FBW
09. sid:07 L607:bxsv:bis:FFW 10. sid:00 L464:chg1_mn:bic:FMS
11. sid:00 L778:chg1_mn:bis:FMS 12. sid:00 L353:gcur:set:MEXCL
13. sid:00 L464:chg1_mn:bic:FMS 14. sid:00 L778:chg1_mn:bis:FMS
15. sid:00 L353:gcur:set:MEXCL 16. sid:00 L464:chg1_mn:bic:FMS
buffer tsn: 13 rdba: 0x01c000c8 (7/200)
scn: 0x6dc91a seq: 0x03 flg: 0x04 tail: 0xc91a2003
frmt: 0x02 chkval: 0x0adc type: 0x20=FIRST LEVEL BITMAP BLOCK <<<<<<<
Start dump data blocks tsn: 13 file#:7 minblk 201 maxblk 201
Block dump from cache:
Dump of buffer cache at level 3 for pdb=0 tsn=13 rdba=29360329
BH (0xdbfc40b0) file#: 7 rdba: 0x01c000c9 (7/201) class: 9 ba: 0xdba80000
set: 5 pool: 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 0,0
dbwrid: 0 obj: 87222 objn: 87222 tsn: [0/13] afn: 7 hint: f
hash: [0x99718d68,0x99718d68] lru: [0xdbfc4030,0xdbfc48a0]
ckptq: [NULL] fileq: [NULL]
objq: [0x7b151428,0xdbfc4b98] objaq: [0x7b151418,0xdbfc4ba8]
st: XCURRENT md: NULL fpin: 'ktspswh4: ktspfsbmb' fscn: 0x6dc8ca tch: 1
flags: block_written_once
LRBA: [0x0.0.0] LSCN: [0x0] HSCN: [0x6dc91a] HSUB: [29]
Printing buffer operation history (latest change first):
cnt: 9
01. sid:07 L192:kcbbic2:bic:FBD 02. sid:07 L191:kcbbic2:bic:FBW
03. sid:07 L602:bic1_int:bis:FWC 04. sid:07 L822:bic1_int:ent:rtn
05. sid:07 L832:oswmqbg1:clr:WRT 06. sid:07 L930:kubc:sw:mq
07. sid:07 L913:bxsv:sw:objq 08. sid:07 L608:bxsv:bis:FBW
09. sid:07 L607:bxsv:bis:FFW 10. sid:00 L464:chg1_mn:bic:FMS
11. sid:00 L778:chg1_mn:bis:FMS 12. sid:00 L353:gcur:set:MEXCL
13. sid:00 L464:chg1_mn:bic:FMS 14. sid:00 L778:chg1_mn:bis:FMS
15. sid:00 L353:gcur:set:MEXCL 16. sid:00 L464:chg1_mn:bic:FMS
buffer tsn: 13 rdba: 0x01c000c9 (7/201)
scn: 0x6dc91a seq: 0x1d flg: 0x04 tail: 0xc91a211d
frmt: 0x02 chkval: 0xd3fa type: 0x21=SECOND LEVEL BITMAP BLOCK <<<<<<<
Start dump data blocks tsn: 13 file#:7 minblk 202 maxblk 202
Block dump from cache:
Dump of buffer cache at level 3 for pdb=0 tsn=13 rdba=29360330
BH (0xdbf78b88) file#: 7 rdba: 0x01c000ca (7/202) class: 4 ba: 0xdb3ce000
set: 6 pool: 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 0,0
dbwrid: 0 obj: 87222 objn: 87222 tsn: [0/13] afn: 7 hint: f
hash: [0x9956bd08,0x9956bd08] lru: [0xdbf78b08,0xdbf78dd8]
ckptq: [NULL] fileq: [NULL]
objq: [0xdbf78e00,0xdbf79aa8] objaq: [0x7b1545d0,0xdbf78e10]
st: XCURRENT md: NULL fpin: 'ktswh03: ktscts' fscn: 0x6dc8ca tch: 5
flags: block_written_once
LRBA: [0x0.0.0] LSCN: [0x0] HSCN: [0x6dc91c] HSUB: [2]
Printing buffer operation history (latest change first):
cnt: 6
01. sid:07 L192:kcbbic2:bic:FBD 02. sid:07 L191:kcbbic2:bic:FBW
03. sid:07 L602:bic1_int:bis:FWC 04. sid:07 L822:bic1_int:ent:rtn
05. sid:07 L832:oswmqbg1:clr:WRT 06. sid:07 L930:kubc:sw:mq
07. sid:07 L913:bxsv:sw:objq 08. sid:07 L608:bxsv:bis:FBW
09. sid:07 L607:bxsv:bis:FFW 10. sid:00 L464:chg1_mn:bic:FMS
11. sid:00 L778:chg1_mn:bis:FMS 12. sid:00 L327:chg1:set:MEXCL
13. sid:00 L464:chg1_mn:bic:FMS 14. sid:00 L778:chg1_mn:bis:FMS
15. sid:00 L353:gcur:set:MEXCL 16. sid:00 L464:chg1_mn:bic:FMS
buffer tsn: 13 rdba: 0x01c000ca (7/202)
scn: 0x6dc91c seq: 0x01 flg: 0x04 tail: 0xc91c2301
frmt: 0x02 chkval: 0xfe53 type: 0x23=PAGETABLE SEGMENT HEADER <<<<<<<
SELECT TABLESPACE_NAME,
SEGMENT_SPACE_MANAGEMENT,
ALLOCATION_TYPE,
EXTENT_MANAGEMENT
FROM DBA_TABLESPACES
WHERE TABLESPACE_NAME = 'NICK';
TABLESPACE_NAME SEGMEN ALLOCATIO EXTENT_MAN
------------------------------ ------ --------- ----------
NICK AUTO SYSTEM LOCAL
那么是否所有的HEADER_BLOCK都是位于段的第三个block呢?是否还跟段空间管理的方式有关呢?
我们用如下实验来探究一下:创建一个手工段空间管理(Manual Segment Space Management)的表空间。
CREATE TABLESPACE TBS_TEST_DATA DATAFILE '/oradata/DB02/tbs_test_data_001.dbf' SIZE 20M
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
SEGMENT SPACE MANAGEMENT MANUAL ONLINE;
create user test identified by test123456 default tablespace tbs_test_data;
grant connect, resource to test;
alter user test quota unlimited on tbs_test_data;
CREATE TABLE TEST.KKK AS SELECT * FROM DBA_OBJECTS;
set line 222
COL SEGMENT_NAME FOR A32;
SELECT SEGMENT_NAME, FILE_ID, BLOCK_ID, BLOCKS
FROM DBA_EXTENTS
WHERE SEGMENT_NAME = 'KKK'
AND OWNER = 'TEST'
ORDER BY BLOCK_ID ASC;
SELECT HEADER_FILE, HEADER_BLOCK, BYTES, BLOCKS, EXTENTS
FROM DBA_SEGMENTS
WHERE OWNER = 'TEST'
AND SEGMENT_NAME = 'KKK';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----------- ------------ ---------- ---------- ----------
8 128 12582912 1536 27
此时的 HEADER_BLOCK 不是第三个块
alter system dump datafile 8 block 128;
select value from v$diag_info where name like 'De%';
Start dump data blocks tsn: 14 file#:8 minblk 128 maxblk 128
Block dump from cache:
Dump of buffer cache at level 3 for pdb=0 tsn=14 rdba=33554560
BH (0xd9fa0890) file#: 8 rdba: 0x02000080 (8/128) class: 4 ba: 0xd9758000
set: 6 pool: 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 0,0
dbwrid: 0 obj: 87224 objn: 87224 tsn: [0/14] afn: 8 hint: f
hash: [0x99645788,0x99645788] lru: [0xdafe5960,0xd9f94498]
ckptq: [NULL] fileq: [NULL]
objq: [0x7b154298,0x7b154298] objaq: [0x7b154288,0x7b154288]
st: XCURRENT md: NULL fpin: 'ktswh03: ktscts' fscn: 0x6dd731 tch: 4
flags: block_written_once
LRBA: [0x0.0.0] LSCN: [0x0] HSCN: [0x6dd888] HSUB: [2]
Printing buffer operation history (latest change first):
cnt: 9
01. sid:07 L192:kcbbic2:bic:FBD 02. sid:07 L191:kcbbic2:bic:FBW
03. sid:07 L602:bic1_int:bis:FWC 04. sid:07 L822:bic1_int:ent:rtn
05. sid:07 L832:oswmqbg1:clr:WRT 06. sid:07 L930:kubc:sw:mq
07. sid:07 L913:bxsv:sw:objq 08. sid:07 L608:bxsv:bis:FBW
09. sid:07 L607:bxsv:bis:FFW 10. sid:05 L464:chg1_mn:bic:FMS
11. sid:05 L778:chg1_mn:bis:FMS 12. sid:05 L327:chg1:set:MEXCL
13. sid:05 L464:chg1_mn:bic:FMS 14. sid:05 L778:chg1_mn:bis:FMS
15. sid:05 L353:gcur:set:MEXCL 16. sid:05 L464:chg1_mn:bic:FMS
buffer tsn: 14 rdba: 0x02000080 (8/128)
scn: 0x6dd888 seq: 0x01 flg: 0x04 tail: 0xd8881001
frmt: 0x02 chkval: 0xb094 type: 0x10=DATA SEGMENT HEADER - UNLIMITED <<<<<<<
如下所示,块类型为DATA SEGEMENT HEADER -UNLIMITED , rdba:( segment header的块地址为)为 0x02000080 .
其实这是第一个块(不是以block_id大小来看),因为手工段空间管理,这种技术的具体实现方式是通过在段头
(Segment Header)分配自由列表(freelist)来管理Block的使用。
简单一点,你可以把自由列表想象成一个数据结构中的链表一样的数据结构,
ORACLE通过一系列算法向自由列表(freelist)中加入或移出Block来实现段管理。
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 27 #blocks: 1535
last map 0x00000000 #maps: 0 offset: 4128
Highwater:: 0x02000601 ext#: 26 blk#: 1 ext size: 128
#blocks in seg. hdr's freelists: 0
#blocks below: 1408
mapblk 0x00000000 offset: 26
Unlocked
Map Header:: next 0x00000000 #extents: 27 obj#: 87224 flag: 0x40000000
Extent Map
-----------------------------------------------------------------
0x02000081 length: 7
0x02000088 length: 8
Segment Header 是一个Segment的第一个extent的头块(第一个块)。
在FLM管理的Segment中,header block始终是segment 的第一个块。
如下所示,在Extent Map中,第一个区间的地址为0x02000081, 恰恰跟segment header的块地址 0x02000080 相差为1,
这意味着后面的分配是紧挨着segment header的块地址。
所以在手工段空间管理(Manual Segment Space Management)的表空间,
不能以block_id的大小顺序来看区间分配顺序。
也就是说FILE_ID=8 BLOCK_ID=128的块并不是第一个区间的第一个块。
参考资料:
http://blog.chinaunix.net/uid-7628732-id-119768.html
http://www.eygle.com/archives/2007/07/oracle_assm_level3_bmb.html
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




