Oracle   发布时间:2019-11-05  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ORACLE中段的HEADER_BLOCK示例详析大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

前言@H_772_3@

段(segment)是一种在数据库中消耗物理存储空间的任何实体(一个段可能存在于多个数据文件中,因为物理的数据文件

是组成逻辑表空间的基本物理存储单位)

最近在学习段(segment)、区间(extent)时,对段的HEADER_BLOCK有一些疑问,本文记录一下探究的实验过程以及相关总结,,如有不对的地方敬请指出。以SCOTT.EMP表为例(下面测试环境为Oracle Database 10g Release 10.2.0.5.0 - 64bit Production):

SELECT file_id,BLOCK_ID,BLOCKS FROM DBA_extents WHERE owneR ='&owneR' AND SEGMENT_NAME = '&TABLE_NAME';

SELECT HEADER_FILE,HEADER_BLOCK,BYTES,BLOCKS,extents FROM DBA_SEGMENTS WHERE owneR='&owneR' AND SEGMENT_NAME='&SEGMENT_NAME';

如上所示,DBA_SEGMENTS 中的HEADER_BLOCK 与DBA_extents的BLOCK_ID不同(HEADER_BLOCK:文件ID为4的第27个块,区间的第一个块的BLOCK_ID为第25个块),这个的原因如下:

一个segment的第一个区的第一个块是FIRST LEVEL BITMAP BLOCK,第二个块是SECOND LEVEL BITMAP BLOCK,这两个块是用来管理free block的,第三个块是PAGETABLE SEGMENT HEADER,这个块才是segment里的HEADER_BLOCK,再后面的块就是用来记录数据的。所以25+2=27. 详细可以参《循序渐进ORCLE:数据库管理、优化与备份》这本书的第5章。

下面我们创建一个表,测试一下是否也是这个规律,如下所示:

create table TEST1.MMM 2 AS 3 SELECT * FROM dba_objecTS;

Table created.

SQL> COL SEGMENT_NAME FOR A32;
SQL> SELECT SEGMENT_NAME
2,file_id
3,BLOCK_ID
4,BLOCKS
5 FROM DBA_extents
6 WHERE SEGMENT_NAME='MMM' AND owneR='TEST1'
7 ORDER BY BLOCK_ID ASc;

SEGMENT_NAME file_id BLOCK_ID BLOCKS


@H_777_0@mMM 76 9 8
MMM 76 17 8
MMM 76 25 8
MMM 76 33 8
MMM 76 41 8
MMM 76 49 8
MMM 76 57 8
MMM 76 65 8
MMM 76 73 8
MMM 76 81 8
MMM 76 89 8

SEGMENT_NAME file_id BLOCK_ID BLOCKS


@H_777_0@mMM 76 97 8
MMM 76 105 8
MMM 76 113 8
MMM 76 121 8
MMM 76 129 8
MMM 76 137 128
MMM 76 265 128
MMM 76 393 128
MMM 76 521 128
MMM 76 649 128
MMM 76 777 128

22 rows SELEcted.

SQL> SELECT HEADER_FILE
2,HEADER_BLOCK
3,BYTES
4,BLOCKS
5,extents
6 FROM DBA_SEGMENTS
7 WHERE owneR='TEST1' AND SEGMENT_NAME='MMM';

HEADER_FILE HEADER_BLOCK BYTES BLOCKS extents


76 11 7340032 896 22

如上所示,段对象TEST1.MMM的header_block为11 ,而对应的区间的第一个块对象ID为9, 也是9+2=11,确实是如此,那么我们来DUMP数据块看看,如下所示

alter system dump DATAFILE 76 block 9;

System altered.

SQL> alter system dump DATAFILE 76 block 10;

System altered.

SQL> alter system dump DATAFILE 76 block 11;

System altered.

SQL> SELEct user_dump.value
2 || '/'
3 || lower(instance.value)
4 || 'ora'
5 || v$process.spid
6 || NVL2(v$process.tracEID,'_'
7 || v$process.tracEID,null)
8 || '.trc'"trace file"
9 from v$parameter user_dump
10 cross join v$parameter instance
11 cross join v$process
12 join v$session
13 on v$process.addr = v$session.paddr
14 where user_dump.name = 'user_dump_dest'
15 and instance.name = 'instance_name'
16 and v$session.audsid = sys_context('userenv','sessionid');

trace file

/u01/app/Oracle/admin/SCM2/udump/scm2_ora_22642.trc

第一个区的第一个块(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,再后面的块就是用来记录数据的

不过有一个奇怪的现象,对SCOTT.EMP其数据块做dump,发现25、26、27数据块的type都是trans data,0x06表示的Block Type为 Table/cluster/index segment data block 。 不知是否因为SCOTT.EMP对象位于USERS表空间下的缘故。不过USER表空间也是ASSM管理的。具体情况尚不清楚?

SELECT tablespace_name 2,SEGMENT_SPACE_MANAGEMENT 3,ALLOCATION_TYPE 4,EXTENT_MANAGEMENT 5 FROM DBA_TABLESPACES 6 WHERE tablespace_name='USERS';

tablespace_name SEGMEN ALLOCATIO EXTENT_MAN


USERS AUTO SYSTEM LOCAL

那么是否所有的HEADER_BLOCK都是位于段的第三个block呢?是否还跟段空间管理的方式有关呢? 我们用如下实验来探究一下:创建一个手工段空间管理(Manual Segment Space Management)的表空间

create tableSPACE TBS_test_DATA 2 DATAFILE '/u03/oradata/gsp/tbs_test_data_001.dbf' 3 SIZE 20M 4 EXTENT MANAGEMENT LOCAL AUTOALLOCATE 5 SEGMENT SPACE MANAGEMENT MANUAL ONLINE;

Tablespace created.

SQL> create user test identified by test123456
2 default tablespace tbs_test_data;

User created.

SQL> grant connect,resource to test;

Grant succeeded.

SQL> create table TEST.KKK
2 AS
3 SELECT * FROM dba_objecTS;

Table created.

SQL> COL SEGMENT_NAME FOR A32;
SQL> SELECT SEGMENT_NAME
2,BLOCKS
5 FROM DBA_extents
6 WHERE SEGMENT_NAME='KKK' AND owneR='TEST'
7 ORDER BY BLOCK_ID ASc;

SEGMENT_NAME file_id BLOCK_ID BLOCKS


KKK 39 427785 128
KKK 43 435249 8
KKK 43 435257 8
KKK 43 435265 8
KKK 43 435273 8
KKK 43 435281 8
KKK 43 435289 8
KKK 43 435297 8
KKK 43 435305 8
KKK 43 435313 8
KKK 43 435321 8

SEGMENT_NAME file_id BLOCK_ID BLOCKS


KKK 43 435329 8
KKK 48 436745 8
KKK 48 436753 8
KKK 48 436761 8
KKK 48 436769 8
KKK 48 436777 8
KKK 48 436873 128
KKK 40 444297 128
KKK 43 447241 128
KKK 52 449545 128
KKK 2 458249 128

22 rows SELEcted.

SQL> SELECT HEADER_FILE
2,extents
6 FROM DBA_SEGMENTS
7 WHERE owneR='TEST' AND SEGMENT_NAME='KKK';

HEADER_FILE HEADER_BLOCK BYTES BLOCKS extents


43 435249 7340032 896 22

SQL>

alter system dump DATAFILE 43 block 435249;

System altered.

SQL> SELEct user_dump.value
2 || '/'
3 || lower(instance.value)
4 || 'ora'
5 || v$process.spid
6 || NVL2(v$process.tracEID,'sessionid');

trace file

/u01/app/Oracle/admin/SCM2/udump/scm2_ora_27792.trc

如下所示,块类型为DATA SEGEMENT HEADER -UNLIMITED , rdba:( segment header的块地址为)为 0x0ac6a431 .其实这是第一个块(不是以block_id大小来看),因为手工段空间管理,这种技术的具体实现方式是通过在段头(Segment Header)分配自由列表(FREELIst)来管理Block的使用。简单一点,你可以把自由列表想象成一个数据结构中的链表一样的数据结构,OracLE通过一系列算法向自由列表(FREELIst)中加入或移出Block来实现段管理。

Segment Header是一个Segment的第一个extent的头块(第一个块)。在FLM管理的Segment中,header block始终是segment 的第一个块。 如下所示,在Extent Map中,第一个区间的地址为0x0ac6a432, 恰恰跟segment header的块地址 0x0ac6a431 相差为1,这意味着后面的分配是紧挨着segment header的块地址。 所以在手工段空间管理(Manual Segment Space Management)的表空间,不能以block_id的大小顺序来看区间分配顺序。也就是说file_id=39 BLOCK_ID=427785的块并不是第一个区间的第一个块。这也是我在实验当中纠结了好久的地方。

总结@H_772_3@

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参学习价值,如果有疑问大家可以留言交流,谢谢大家对菜鸟教程的支持。

大佬总结

以上是大佬教程为你收集整理的ORACLE中段的HEADER_BLOCK示例详析全部内容,希望文章能够帮你解决ORACLE中段的HEADER_BLOCK示例详析所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:oracle