ORACLE关于段的HEADER_BLOCK的一点浅析
在学习段(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章。
下面我们创建一个表,测试一下是否也是这个规律,如下所示:
SQL> 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
-------------------------------- ---------- ---------- ----------
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
-------------------------------- ---------- ---------- ----------
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数据块看看,如下所示
SQL> 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管理的。具体情况尚不清楚?
SQL> 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)的表空间。
SQL> 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 ,FILE_ID
3 ,BLOCK_ID
4 ,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 , HEADER_BLOCK
3 , BYTES
4 , BLOCKS
5 , 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>
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, '_'
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_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的块并不是第一个区间的第一个块。这也是我在实验当中纠结了好久的地方。

参考资料:
http://blog.chinaunix.net/uid-7628732-id-119768.html
http://www.eygle.com/archives/2007/07/oracle_assm_level3_bmb.html
《循序渐进ORACLE:数据库管理、优化与备份》
ORACLE关于段的HEADER_BLOCK的一点浅析的更多相关文章
- ipcs命令以及oracle内存段
今天是2014-01-06,在没过春节之前重新复习一下2013年学习的内容,关于oracle内存段在我之前写的blog中有详细操作.在此记录一下ipcs命令的用法. http://blog.csdn. ...
- oracle数据段详解
Tablespace(表空间):表空间是数据库的逻辑划分,一个表空间只能属于一个数据库.所有的数据库对象都放在指定的表空间中,但主要存放的对象是表,所以称为表空间. 默认的系统表空间:system.s ...
- Oracle表字段的增加、删除、修改和重命名
本文主要是关于Oracle数据库表中字段的增加.删除.修改和重命名的操作. 增加字段语法:alter table tablename add (column datatype [default val ...
- Oracle 学习笔记 19 -- 触发器和包浅析(PL/SQL)
触发器是存放在数据库中的一种特殊类型的子程序.不能被用户直接调用,而是当特定事件或操作发生时由系统自己主动 调用执行.触发器不能接受參数.所以执行触发器就叫做触发或点火.Oracle事件指的是数据库的 ...
- 查询oracle表字段信息
表字段的信息咱们可以称之为元数据,今天有人问怎么把表字段的信息导出来,说实话我还不会用plsql develper把表的结构导出来,像下图所示: 在写数据库设计说明书的时候,想要把这个表格拷贝出来,这 ...
- 关于oracle中varchar2与nvarchar2的一点认识
今天在oracle 10g下测试了下varchar2与nvarchar2这两种类型,网上有很多关于这两种类型的区别的帖子,我还是自己测试了下. varchar2(size type),size最大为4 ...
- oracle 表字段添加 修改 删除语法
修改列名 alter table 表明 rename column rename 老列名 to 新列名添加 字段alter table 表名 add(字段名 类型):删除字段alter table 表 ...
- oracle表字段为汉字,依据拼音排序
在order by后面使用NLSSORT函数转化汉字列,如下 select * from student order by NLSSORT(name,'NLS_SORT=SCHINESE_PINYIN ...
- oracle单字段拆分成多行
已上图为例 先以逗号分隔拆分 拆分函数: CREATE OR REPLACE FUNCTION SPLIT(P_STRING VARCHAR2, P_SEP VARCHAR2 := ',') RETU ...
随机推荐
- 【转】matlab图形句柄详解(一)
在matlab中,每一个对象都有一个数字来标识,叫做句柄.当每次创建一个对象时,matlab就为它建立一个唯一的句柄,句柄中包含有该对象的相关信息参数,可以在后续程序中进行操作,改变其中的参数,以便达 ...
- 在UITableView顶部制作简单的UISegmentControl实例方法
// http://www.tuicool.com/articles/yUfURj 使用方法 如上图: 分两步: 一.创建320长度背景,高不超过40最好 //segment背景图 UIImageVi ...
- APP测试(转载)
(1) 非功能测试 app测试的一个重要方面是app的非功能需求.移动app在推出市场或进行进一步开发前,测试人员有一定的职责做该类需求的跟踪工作. 早期开发阶段要进行的第一个测试应该是实用性测试.通 ...
- 反向代理和HTTP重定向
1.什么是正向代理(前向代理)? 在NAT技术(Network Address Translation)出现之前,所有主机无法直接与外网相连,要想上网,需要连接到一台能够访问外网的Web服务器,再通过 ...
- *C语言有关指针的变量声明中的几个易错点
转至:http://my.oschina.net/ypimgt/blog/108265 Technorati 标签: 指针, typedef, const, define 我们都知道,至少听说过 ...
- c# Char && string
char 支持的方法 字符串 声明字符串 String str = [null]; 可以用此方法声明一个空字符串 连接字符串 str +"" + str1; 比较两个字符串 C ...
- 14_Python字符串操作方法总结
字符串方法总结 #s = '**i love you\n\t' 测试s.strip()使用的字符串 s = 'i love you' #1.首字符大写,其余字符小写 print(s.capitaliz ...
- 前端 js技术
1.JavaScript代码存在形式 <!-- 方式一 --> <script type"text/javascript" src="JS文件" ...
- iOS-Runtime之关于页面跳转的捷径【Runtime获取当前ViewController】
写在前面 在我们操作页面跳转时,如果当前的类不是UIViewcontroller(下面用VC表示),你会不会写一个代理,或者block给VC传递信息,然后在VC里面进行 ///假如targetVc是将 ...
- SSH 面试题集锦
1. BeanFactory的作用是什么? [中] BeanFactory是配置.创建.管理bean的容器,有时候也称为bean上下文.Bean与bean的依赖关系,也是由BeanFactory ...






