ORACLE中段的HEADER_BLOCK示例詳析
前言
段(segment)是一種在數(shù)據(jù)庫(kù)中消耗物理存儲(chǔ)空間的任何實(shí)體(一個(gè)段可能存在于多個(gè)數(shù)據(jù)文件中,因?yàn)槲锢淼臄?shù)據(jù)文件
是組成邏輯表空間的基本物理存儲(chǔ)單位)
最近在學(xué)習(xí)段(segment)、區(qū)間(extent)時(shí),對(duì)段的HEADER_BLOCK有一些疑問(wèn),本文記錄一下探究的實(shí)驗(yàn)過(guò)程以及相關(guān)總結(jié),,如有不對(duì)的地方,敬請(qǐng)指出。以SCOTT.EMP表為例(下面測(cè)試環(huán)境為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個(gè)塊,區(qū)間的第一個(gè)塊的BLOCK_ID為第25個(gè)塊),這個(gè)的原因如下:
一個(gè)segment的第一個(gè)區(qū)的第一個(gè)塊是FIRST LEVEL BITMAP BLOCK,第二個(gè)塊是SECOND LEVEL BITMAP BLOCK,這兩個(gè)塊是用來(lái)管理free block的,第三個(gè)塊是PAGETABLE SEGMENT HEADER,這個(gè)塊才是segment里的HEADER_BLOCK,再后面的塊就是用來(lái)記錄數(shù)據(jù)的。所以25+2=27. 詳細(xì)可以參考《循序漸進(jìn)ORCLE:數(shù)據(jù)庫(kù)管理、優(yōu)化與備份》這本書(shū)的第5章。
下面我們創(chuàng)建一個(gè)表,測(cè)試一下是否也是這個(gè)規(guī)律,如下所示:
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
如上所示,段對(duì)象TEST1.MMM的header_block為11 ,而對(duì)應(yīng)的區(qū)間的第一個(gè)塊對(duì)象ID為9, 也是9+2=11,確實(shí)是如此,那么我們來(lái)DUMP數(shù)據(jù)塊看看,如下所示
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
第一個(gè)區(qū)的第一個(gè)塊(block_id=9)是FIRST LEVEL BITMAP BLOCK,第二個(gè)塊(block_id=10)是SECOND LEVEL BITMAP BLOCK,這兩個(gè)塊是用來(lái)管理free block的,第三個(gè)塊(block_id=11)是PAGETABLE SEGMENT HEADER,這個(gè)塊才是segment里的HEADER_BLOCK,再后面的塊就是用來(lái)記錄數(shù)據(jù)的
不過(guò)有一個(gè)奇怪的現(xiàn)象,對(duì)SCOTT.EMP其數(shù)據(jù)塊做dump,發(fā)現(xiàn)25、26、27數(shù)據(jù)塊的type都是trans data,0x06表示的Block Type為 Table/cluster/index segment data block 。 不知是否因?yàn)镾COTT.EMP對(duì)象位于USERS表空間下的緣故。不過(guò)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都是位于段的第三個(gè)block呢?是否還跟段空間管理的方式有關(guān)呢? 我們用如下實(shí)驗(yàn)來(lái)探究一下:創(chuàng)建一個(gè)手工段空間管理(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
如下所示,塊類(lèi)型為DATA SEGEMENT HEADER -UNLIMITED , rdba:( segment header的塊地址為)為 0x0ac6a431 .其實(shí)這是第一個(gè)塊(不是以block_id大小來(lái)看),因?yàn)槭止ざ慰臻g管理,這種技術(shù)的具體實(shí)現(xiàn)方式是通過(guò)在段頭(Segment Header)分配自由列表(freelist)來(lái)管理Block的使用。簡(jiǎn)單一點(diǎn),你可以把自由列表想象成一個(gè)數(shù)據(jù)結(jié)構(gòu)中的鏈表一樣的數(shù)據(jù)結(jié)構(gòu),ORACLE通過(guò)一系列算法向自由列表(freelist)中加入或移出Block來(lái)實(shí)現(xiàn)段管理。
Segment Header是一個(gè)Segment的第一個(gè)extent的頭塊(第一個(gè)塊)。在FLM管理的Segment中,header block始終是segment 的第一個(gè)塊。 如下所示,在Extent Map中,第一個(gè)區(qū)間的地址為0x0ac6a432, 恰恰跟segment header的塊地址 0x0ac6a431 相差為1,這意味著后面的分配是緊挨著segment header的塊地址。 所以在手工段空間管理(Manual Segment Space Management)的表空間,不能以block_id的大小順序來(lái)看區(qū)間分配順序。也就是說(shuō)FILE_ID=39 BLOCK_ID=427785的塊并不是第一個(gè)區(qū)間的第一個(gè)塊。這也是我在實(shí)驗(yàn)當(dāng)中糾結(jié)了好久的地方。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Oracle11.2 命令行手工最簡(jiǎn)創(chuàng)建數(shù)據(jù)庫(kù)的過(guò)程
Oracle 11.2命令行手工最簡(jiǎn)創(chuàng)建數(shù)據(jù)庫(kù)的過(guò)程 命令行手工最簡(jiǎn)創(chuàng)建數(shù)據(jù)庫(kù)的過(guò)程2009-09-09Oracle使用rownum分頁(yè)方式實(shí)例代碼
ROWNUM是一個(gè)序列,是oracle數(shù)據(jù)庫(kù)從數(shù)據(jù)文件或緩沖區(qū)中讀取數(shù)據(jù)的順序,這篇文章主要給大家介紹了關(guān)于Oracle使用rownum分頁(yè)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07oracle中if/else的三種實(shí)現(xiàn)方式詳解
本文給大家介紹了oracle中if/else的三種實(shí)現(xiàn)方式及注意事項(xiàng),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-10-10Oracle使用fy_recover_data恢復(fù)truncate刪除的數(shù)據(jù)
這篇文章主要介紹了Oracle使用fy_recover_data恢復(fù)truncate刪除的數(shù)據(jù),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-07-07Oracle往某表批量插入記錄的幾種實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于Oracle往某表批量插入記錄的幾種實(shí)現(xiàn)方法,Oracle批量插入語(yǔ)句與其他數(shù)據(jù)庫(kù)不同,文中通過(guò)代碼實(shí)例介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07實(shí)現(xiàn)oracle數(shù)據(jù)庫(kù)字段自增長(zhǎng)(兩種方式)
這篇文章主要通過(guò)兩種方式實(shí)現(xiàn)oracle數(shù)據(jù)庫(kù)字段自增長(zhǎng),第一種方式是序列+觸發(fā)器,第二種方式序列+顯示調(diào)用序列,需要的朋友可以參考下2015-07-07Oracle 11g Release (11.1) 索引底層的數(shù)據(jù)結(jié)構(gòu)
本文介紹關(guān)于 Oracle 索引的結(jié)構(gòu)。大概了解 Oracle 索引底層的數(shù)據(jù)結(jié)構(gòu),從而更好地理解 Oracle 索引對(duì)增、刪、改、查的性能2012-11-11oracle獲取上一旬的開(kāi)始時(shí)間和結(jié)束時(shí)間的實(shí)現(xiàn)函數(shù)
本文為大家介紹下oracle如何獲取上一旬的開(kāi)始時(shí)間和結(jié)束時(shí)間,實(shí)現(xiàn)函數(shù)如下,感興趣的朋友可以參考下2013-09-09oracle 數(shù)據(jù)庫(kù)數(shù)據(jù)遷移解決方案
大部分系統(tǒng)由于平臺(tái)和版本的原因,做的是邏輯遷移,少部分做的是物理遷移,接下來(lái)把心得與大家分享一下2012-12-12