侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

ORACLE中段的HEADER_BLOCK示例详析

数据库  /  管理员 发布于 6年前   503

前言

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

 

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   8MMM          76   17   8MMM          76   25   8MMM          76   33   8MMM          76   41   8MMM          76   49   8MMM          76   57   8MMM          76   65   8MMM          76   73   8MMM          76   81   8MMM          76   89   8 SEGMENT_NAME      FILE_ID BLOCK_ID  BLOCKS-------------------------------- ---------- ---------- ----------MMM          76   97   8MMM          76  105   8MMM          76  113   8MMM          76  121   8MMM          76  129   8MMM          76  137  128MMM          76  265  128MMM          76  393  128MMM          76  521  128MMM          76  649  128MMM          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  128KKK          43  435249   8KKK          43  435257   8KKK          43  435265   8KKK          43  435273   8KKK          43  435281   8KKK          43  435289   8KKK          43  435297   8KKK          43  435305   8KKK          43  435313   8KKK          43  435321   8 SEGMENT_NAME      FILE_ID BLOCK_ID  BLOCKS-------------------------------- ---------- ---------- ----------KKK          43  435329   8KKK          48  436745   8KKK          48  436753   8KKK          48  436761   8KKK          48  436769   8KKK          48  436777   8KKK          48  436873  128KKK          40  444297  128KKK          43  447241  128KKK          52  449545  128KKK          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的块并不是第一个区间的第一个块。这也是我在实验当中纠结了好久的地方。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对AIDI的支持。


  • 上一条:
    Oracle 闪回 找回数据的实现方法
    下一条:
    ORACLE检查找出损坏索引(Corrupt Indexes)的方法详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 分库分表的目的、优缺点及具体实现方式介绍(0个评论)
    • DevDB - 在 VS 代码中直接访问数据库(0个评论)
    • 在ubuntu系统中实现mysql数据存储目录迁移流程步骤(0个评论)
    • 在mysql中使用存储过程批量新增测试数据流程步骤(0个评论)
    • php+mysql数据库批量根据条件快速更新、连表更新sql实现(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2017-06
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-01
    • 2018-05
    • 2018-10
    • 2018-11
    • 2020-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2021-02
    • 2021-04
    • 2021-07
    • 2021-08
    • 2021-11
    • 2021-12
    • 2022-02
    • 2022-03
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客