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:数据库管理、优化与备份》

时间: 2024-10-27 05:02:12

ORACLE关于段的HEADER_BLOCK的一点浅析的相关文章

javascript-麻烦看下这段JQ代码,一点性能问题

问题描述 麻烦看下这段JQ代码,一点性能问题 <head> <style type="text/css"> .scroll_div{width:1000px; height:370px; margin:0 auto; padding:10px;} .scroll_div .pic{width:820px; height:370px; overflow:hidden; position:relative; float:left;} .scroll_div .pic

c-麻烦看一下这一段正则表达式,有一点问题

问题描述 麻烦看一下这一段正则表达式,有一点问题 (?:(?:https?|ftp)://|www.)[-a-z0-9+&@#/%?=~_|!:.;]*[-a-z0-9+&@#/%=~_|]/i这段正则的功能是匹配URL这里的是为了什么-a a前面的- 是什么-a-z0-9+ 后面的一堆&@#/%?=~_|!:.; 这些是什么啊....如果是符号匹配的话,不需要加吗?* 后的[ ] 又是为了什么,不是已经有*了吗? 最后的 [ ] 后面的 /i 又是什么? 解决方案 :匹配单词边界

Oracle表段和索引段上的LOGGING与NOLOGGING

在有些情况下,对于表段和索引段可以采用记录日志的模式,也可以使用不记录日志的模式.如在对表段.索引段使用数据泵导入时,可以 使用NOLOGGING模式,而使用DATA GUARD或对可用性较高的场景中需要记录日志,甚至使用强制记录日志.本文介绍了在表段,索引段使用 LOGGING与NOLOGGING时产生redo的大小以及DIRECT INSERT APPEND 的使用方法. NOLOGGING跟数据库的运行模式有关,i和i的默认安装都是非归档模式,并且自动归档默认是禁用.在安装g.g时,可以选

ss2h+Oracle 一段时间后不能执行query

问题描述 系统登录后只操作两下,就不能操作报错信息:Causedby:java.sql.SQLException:Connectionscouldnotbeacquiredfromtheunderlyingdatabase![Cause:com.mchange.v2.resourcepool.CannotAcquireResourceException:AResourcePoolcouldnotacquirearesourcefromitsprimaryfactoryorsource.atcom

安装 oracle soa suite x86 101310 的一点经验

很多中文版xp用户安装这个版本是很常见碰到的问题就是装到WebService Application Management的时候失败, 无法继续下去, 找了一下资料, 是由于这个版本自带的oracle lite的问题, 解决方法是在快安装到这个组件的时候, 手工找到X:product\10.1.3.1\OracleAS_2\integration\esb\olite\template中的polite.ini, 将DB_CHAR_ENCODING=UTF8改成 B_CHAR_ENCODING=Na

Oracle内存结构(三)----Process Memory的详细信息

oracle The Process Memory: 除了SGA(System Global Area)之外,Oracle进程还使用下面三个全局区: The Process Global Area  (PGA) The User Global Area   (UGA) The Call Global Area   (CGA)   很多人都搞不清楚PGA和UGA两者之间的区别,实际上两者之间的区别跟一个进程和一个会话之间的区别是类似的.尽管说进程和会话之间一般都是一对一的关系,但实际上比这个更复杂

作为一个新手的Oracle(DBA)学习笔记

Oracle数据库笔记 Jack Chaing 作者QQ595696297 交流群 127591054 祝大家学习进步. 如果大家想看Word版本的可以去下载:Word排版比较清晰一些. http://download.csdn.net/detail/jack__chiang/9810532 此笔记是作者本人去年开始从一个DBA新人的学习笔记,积累至今,希望拿出来给那些对DBA有兴趣的童孩学习,大家一起努力嘛. 此笔记记录了作者工作学习中从零基础的学习的记录,和从中遇见的问题与问题的解决!很高兴

通过ASP.NET连接Oracle数据库实例教程

通过ASP.NET连接Oracle数据库实例教程 长期以来,我一直用的是 MS SQL Server / Access 数据库,通过.NET 访问MS自家的东西几乎没碰到过什么麻烦.最近项目中要用 Oracle 作为数据库,学习研究了一些 .NET 访问Oracle 的东西,发现问题倒真的不少. 1.System.Data.OracleClient 和 System.Data.OleDb 命名空间 虽然通过这两个命名空间的类都可以访问 Oracle 数据库,但和 SQL Server 类似的(S

Geometry 对象浅析

ArcEngine Geometry库定义了基本几何图形的矢量表达形式,顶级的几何图形有Points.Multipoints.Polylines.Polygons. Multipatches,Geodatabase和绘图系统使用这些几何图形来定义其他各种形状的特征和图形,提供了编辑图形的操作方法和地图符号系统符号化特征数据的途径. Geometry库中几个核心类和接口构成了Geometry对象的基本框架. GeometryEnvironment GeometryEnvironment提供了从不同