在学习段(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的一点浅析的更多相关文章

  1. ipcs命令以及oracle内存段

    今天是2014-01-06,在没过春节之前重新复习一下2013年学习的内容,关于oracle内存段在我之前写的blog中有详细操作.在此记录一下ipcs命令的用法. http://blog.csdn. ...

  2. oracle数据段详解

    Tablespace(表空间):表空间是数据库的逻辑划分,一个表空间只能属于一个数据库.所有的数据库对象都放在指定的表空间中,但主要存放的对象是表,所以称为表空间. 默认的系统表空间:system.s ...

  3. Oracle表字段的增加、删除、修改和重命名

    本文主要是关于Oracle数据库表中字段的增加.删除.修改和重命名的操作. 增加字段语法:alter table tablename add (column datatype [default val ...

  4. Oracle 学习笔记 19 -- 触发器和包浅析(PL/SQL)

    触发器是存放在数据库中的一种特殊类型的子程序.不能被用户直接调用,而是当特定事件或操作发生时由系统自己主动 调用执行.触发器不能接受參数.所以执行触发器就叫做触发或点火.Oracle事件指的是数据库的 ...

  5. 查询oracle表字段信息

    表字段的信息咱们可以称之为元数据,今天有人问怎么把表字段的信息导出来,说实话我还不会用plsql develper把表的结构导出来,像下图所示: 在写数据库设计说明书的时候,想要把这个表格拷贝出来,这 ...

  6. 关于oracle中varchar2与nvarchar2的一点认识

    今天在oracle 10g下测试了下varchar2与nvarchar2这两种类型,网上有很多关于这两种类型的区别的帖子,我还是自己测试了下. varchar2(size type),size最大为4 ...

  7. oracle 表字段添加 修改 删除语法

    修改列名 alter table 表明 rename column rename 老列名 to 新列名添加 字段alter table 表名 add(字段名 类型):删除字段alter table 表 ...

  8. oracle表字段为汉字,依据拼音排序

    在order by后面使用NLSSORT函数转化汉字列,如下 select * from student order by NLSSORT(name,'NLS_SORT=SCHINESE_PINYIN ...

  9. oracle单字段拆分成多行

    已上图为例 先以逗号分隔拆分 拆分函数: CREATE OR REPLACE FUNCTION SPLIT(P_STRING VARCHAR2, P_SEP VARCHAR2 := ',') RETU ...

随机推荐

  1. CURL post/get提交

    public function curlss($url){ $curl = curl_init(); // 设置你需要抓取的URL curl_setopt($curl, CURLOPT_URL, $u ...

  2. python--批量下载豆瓣图片之升级版本

    周末下雨没法出门,刷刷豆瓣看看妹子,本想拿以前脚本下载点图片,结果发现运行失败,之前版本为<python--批量下载豆瓣图片>,报错HTTP Error 403: Forbidden,网上 ...

  3. java foreach遍历的前提条件

    自我总结,欢迎拍砖,不胜感激! 目的: 加深foreach遍历的影响 证明:foreach遍历的前提条件是:list !=null ,而不是:list !=null && list.s ...

  4. 跨进程的mutex

    1.操作系统分为ring0(内核层)和ring3(应用层)两层. ring0层出错会蓝屏,ring3层出错程序就会挂了. event和mutex创建他的指针是应用层,但是它的内部是ring0层,rin ...

  5. redis通过pipeline提升吞吐量

    案例目标 简单介绍 redis pipeline 的机制,结合一段实例说明pipeline 在提升吞吐量方面发生的效用. 案例背景 应用系统在数据推送或事件处理过程中,往往出现数据流经过多个网元: 然 ...

  6. python之作业--------购物车优化

    Read Me:继上次简单购物车的实现,有再一次的升级优化了下,现实现以下几个功能: 1.有客户操作和商家操作,实现,客户可以买东西,当金额不足提醒,最后按q退出,打印购物车列表 2.商家可以添加操作 ...

  7. MVC思想概述

    一. 传统Model1和Model2 Model1:整个web应用几乎全部用JSP页面组成,JSP页面接收处理客户端请求,对请求处理后直接作出响应.用少量的javaBean来处理数据库链接,数据库访问 ...

  8. HDU [P1704] Rank

    传递闭包裸题 但是本题的Floyd一定要优化,不然会T cpp #include <iostream> #include <cstdio> #include <cstri ...

  9. 济南清北学堂游记 Day 5.

    十一月的第一天.算下来在济南已经呆了接近一星期了...... 还剩九天...看着洛谷的倒计时心里直发慌. 也许我不该过多纠结于高级算法,基础也是很重要的. 今天晚上就自由的敲一些板子吧.最后的九天,让 ...

  10. BZOJ 4518: [Sdoi2016]征途 [斜率优化DP]

    4518: [Sdoi2016]征途 题意:\(n\le 3000\)个数分成m组,一组的和为一个数,求最小方差\(*m^2\) DP方程随便写\(f[i][j]=min\{f[k][j-1]+(s[ ...