oracle headerblock,ORACLE中段的HEADER_BLOCK示例详析

前言

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

8147249ef49a01062694aefa8abe6f32.png

SELECT HEADER_FILE

, HEADER_BLOCK

, BYTES

, BLOCKS

, EXTENTS

FROM DBA_SEGMENTS

WHERE OWNER='&OWNER' AND SEGMENT_NAME='&SEGMENT_NAME';

dc0117489ca8fea015f9a26c4f650787.png

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

066200285c3056fc9b386223cd20bac9.png

7536751f1fecc0fd2705f847d4f3f4cd.png

16a94101e7f47cc9c8f7d0499bd021f8.png

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

5754fb1540280dc6eb450ad27104105d.png

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>

2bf51129c4c603b54be42158a08189cd.png

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

dee1ce39441d2c2786baf140e35ab215.png

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

b52f09b70e8d57488c595b18731c7e44.png

总结

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 作为一名程序员,我在2023对自己的计划包括: 1. 不断学习和提升技能:我会继续学习新的编程语言和框架,以及不断提高编码能力。 2. 参加行业相关的培训和会议:我会参加各种行业相关的培训课程和会议,以便获得最新的行业知识和技能。 3. 参加项目并积累经验:我会参加各种项目,以便积累丰富的经验,并提升个人能力。 4. 在业内建立良好的人脉关系:我会努力与业内的同行建立良好的人脉关系,并与他们保持联系。 5. 寻找更好的发展机会:我会不断寻找更好的发展机会,以便在职业生涯中取得更大的成功。 总之,我在2023会努力工作,不断学习和提升,并寻找更好的发展机会,以在职业生涯中取得更大的成功。 ### 回答2: 2023的计划对于我作为一名程序员来说十分重要,我希望能够提升自己的技能水平并取得更好的职业发展。以下是我的计划: 首先,我计划继续学习并掌握新的编程语言和技术。随着科技的不断发展,编程语言和技术也在不断更新换代,作为一名程序员,保持学习的状态是必不可少的。我将花费更多的时间学习目前主流的编程语言,如Python、Java等,并尝试掌握最新的前端和后端技术。通过不断学习,我希望能够拥有更广泛的技术视野和更强大的技术能力。 其次,我计划参与更多的项目和实践。在理论学习之外,实践是提升技能的关键。我计划积极寻找项目机会,无论是个人项目还是团队项目,都可以提供宝贵的实践机会。通过参与各种项目,我可以锻炼解决问题的能力,提高编码和协作能力。同时,我也希望通过实践中的挑战和失败,不断完善自己,进一步提高自己的技术水平和经验。 第三,我计划参加相关的培训和技术交流活动。参加培训和技术交流活动可以与其他程序员交流和学习,了解行业最新动态和趋势。我计划参加各种技术研讨会、讲座和培训班,通过与行业专家和其他程序员的交流,深入了解各种编程技术和最佳实践。同时,我也希望能够积极参与技术社区,与其他程序员分享自己的经验和见解,不断提高自己的影响力和口碑。 最后,我计划在个人项目和开源社区上做出更多的贡献。通过自己的努力,我希望能够在个人项目中实现一些有意义的功能或解决一些实际问题,并将其开源。通过开源社区的贡献,我可以帮助他人解决问题,同时也能够借助其他人的反馈和指导,不断改进自己的代码和设计能力。 总之,2023对于我作为一名程序员来说是充满挑战和机遇的一。我将不懈努力,持续学习和实践,不断提升自己的技能水平和职业发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值