ORACLE中段的HEADER_BLOCK示例详析

作者:潇湘隐者 时间:2024-01-26 02:35:09 

前言

段(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';

ORACLE中段的HEADER_BLOCK示例详析 


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

ORACLE中段的HEADER_BLOCK示例详析

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

ORACLE中段的HEADER_BLOCK示例详析

ORACLE中段的HEADER_BLOCK示例详析

ORACLE中段的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管理的。具体情况尚不清楚?

ORACLE中段的HEADER_BLOCK示例详析


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>

ORACLE中段的HEADER_BLOCK示例详析 


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来实现段管理。

ORACLE中段的HEADER_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的块并不是第一个区间的第一个块。这也是我在实验当中纠结了好久的地方。

ORACLE中段的HEADER_BLOCK示例详析

来源:http://www.cnblogs.com/kerrycode/p/6856582.html

标签:oracle,段,header,block
0
投稿

猜你喜欢

  • python扩展库numpy入门教程

    2022-05-05 14:28:05
  • python 对象真假值的实例(哪些视为False)

    2021-11-18 02:50:49
  • 常见数据库系统比较 Oracle数据库

    2024-01-26 04:18:57
  • python中进程间通信及设置状态量控制另一个进程

    2022-01-28 08:02:57
  • Pytorch 数据加载与数据预处理方式

    2021-06-12 11:07:05
  • table 行转列的sql详解

    2024-01-27 00:44:57
  • 合成大西瓜开发源码手把手教你运行和部署大西瓜游戏项目(附源码)

    2023-11-01 05:39:13
  • PyQt5+serial模块实现一个串口小工具

    2021-04-25 00:51:19
  • 基于node打包可执行文件工具_Pkg使用心得分享

    2024-05-08 09:37:47
  • Golang源码分析之golang/sync之singleflight

    2024-04-25 15:07:26
  • python 动态迁移solr数据过程解析

    2023-03-08 10:19:20
  • python异步存储数据详解

    2023-08-14 09:05:44
  • JavaScript字符串对象toLowerCase方法入门实例(用于把字母转换为小写)

    2024-05-08 10:10:47
  • Python统计文件中去重后uuid个数的方法

    2023-07-11 17:20:06
  • Python logging自定义字段输出及打印颜色

    2023-09-03 17:04:25
  • python 读取.csv文件数据到数组(矩阵)的实例讲解

    2023-08-10 12:12:36
  • 在MySQL中使用LIMIT进行分页的方法

    2024-01-20 22:27:58
  • Python 模拟购物车的实例讲解

    2021-01-13 05:24:08
  • 一些与网页密切相关的技术

    2010-09-05 21:16:00
  • 详解Python的迭代器、生成器以及相关的itertools包

    2022-07-24 01:03:44
  • asp之家 网络编程 m.aspxhome.com