ORACLE关于段的HEADER_BLOCK的一点浅析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\'; 

 

clip_image001

 

SELECT HEADER_FILE
     , HEADER_BLOCK
     , BYTES
     , BLOCKS
     , EXTENTS 
FROM DBA_SEGMENTS 
WHERE OWNER=\'&OWNER\' AND SEGMENT_NAME=\'&SEGMENT_NAME\';

 

clip_image002

 

如上所示,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,再后面的块就是用来记录数据的

clip_image003

clip_image004

clip_image005

 

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

clip_image006

 

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.
 
关于oracle的一点备忘

关于oracle中number类型的长度和精度的一点整理.mark

关于CLASSPATH的一点感想

Java 关于类的构造方法的一点认识

关于 truncate table 的一点学习札记

Oracle 数据库坏块处理