數據文件internal分析
2024-07-21 02:39:50
供稿:網友
眾所周知,Oracle的數據是儲存在數據文件中的。那么Oracle是以什么格式來儲存數據的呢?相信大家都對其內部結構很感愛好。這篇文章就幫大家來了解Oracle數據文件的內部結構。
我們知道數據庫儲存的最小單位是數據塊,其他如extent,segment,tablespace等都是由數據塊組成,所以我們就從數據塊的結構來分析。典型的數據塊由3部分構成:1. 頭信息區 2. 這個區包括數據塊的地址,數據塊類型,檢查點信息,scn信息,數據塊版本號等。(以下是其大概的構造,稍后會做解釋)―――――――――――――――――――――――――――*** 2003-06-10 10:05:10.296Start dump data blocks tsn: 2 file#: 3 minblk 13107 maxblk 13107buffer tsn: 2 rdba: 0x00c03333 (3/13107)scn: 0x0000.00105d22 seq: 0x05 flg: 0x00 tail: 0x5d220605frmt: 0x02 chkval: 0x0000 type: 0x06=trans dataBlock header dump: 0x00c03333 Object id on Block? Y seg/obj: 0x6493 csc: 0x00.105d22 itc: 1 flg: O typ: 1 – DATAfsl: 0 fnx: 0x0 ver: 0x01――――――――――――――――――――――――――――2. 事務列表區事務列表去包括了在這個數據塊內的事務,也就是我們知道的ITL(interested transaction list),從中我們可以知道XID(transaction id),UBA(undo block address)等信息(以下是其大概的構造,稍后會做解釋)Itl Xid Uba Flag Lck Scn/Fsc0x01 xid: 0x0009.012.00000002 uba: 0x00800c84.0000.25 ---- 1 fsc 0x0000.000000003. 數據區,尾區數據區顧名思義是真正存儲數據的地方,在這里我們可以看到每一條記錄。至于尾區,這里儲存著數據塊的版本號,與數據頭信息區的版本號相對應,可以用來確定數據塊前后是否一致。(以下是其大概的構造,稍后會做解釋)―――――――――――――――――――――――――――data_block_dump===============tsiz: 0x1fb8hsiz: 0x14pbl: 0x0f3f7444bdba: 0x00c03333flag=-----------ntab=1nrow=1frre=-1fsbo=0x14fSEO=0x1fb2avsp=0x1f9btosp=0x1f9b0xe:pti[0] nrow=1 offs=00x12:PRi[0] offs=0x1fb2block_row_dump:tab 0, row 0, @0x1fb2tl: 6 fb: --H-FL-- lb: 0x1 cc: 1col 0: [ 2] c1 02(數據就在這里)end_of_block_dumpEnd dump data blocks tsn: 2 file#: 3 minblk 13107 maxblk 13107―――――――――――――――――――――――――――下面我們來做一個完整的實驗,首先創建一個新的表空間 SQL> create tablespace testblock datafile 'd:/oracle/oradata/test/testblock.ora' size 100m; 表空間已創建。 創建一個新用戶并指定默認表空間為testblock,臨時表空間為temp
SQL> create user testblock identified by testblock default tablespace testblock
temporary tablespace temp;
用戶已創建SQL> grant create session to testblock; 授權成功。SQL> grant resource to testblock; 授權成功。 SQL> connect testblock/testblock@test已連接。SQL> create table testblock (a number); 表已創建。SQL> insert into testblock values(1); 已創建 1 行。 SQL> insert into testblock values(2); 已創建 1 行。SQL> commit; 提交完成。SQL> connect internal/oracle@test已連接。SQL> select header_file,header_block from dba_segments where segment_name='TESTBLOCK'; HEADER_FILE HEADER_BLOCK----------- ------------11 2 從這里我們知道testblock表所在的數據文件號是11,數據頭塊號是2,下面我們dump出數據塊來看下――――――――――――――――――――――――――――――――――
*** 2003-06-12 11:36:22.437*** SESSION ID:(12.96) 2003-06-12 11:36:22.343Start dump data blocks tsn: 8 file#: 11 minblk 2 maxblk 2buffer tsn: 8 rdba: 0x02c00002 (11/2)scn: 0x0000.001148eb seq: 0x01 flg: 0x00 tail: 0x48eb1001frmt: 0x02 chkval: 0x0000 type: 0x10=DATA SEGMENT HEADER – UNLIMITED Extent Control Header ----------------------------------------------------------------- Extent Header:: spare1: 0 space2: 0 #extents: 1 #blocks: 4 last map 0x00000000 #maps: 0 offset: 4128 Highwater:: 0x02c00004 ext#: 0 blk#: 1 ext size: 4 #blocks in seg. hdr's freelists: 1 #blocks below: 1 mapblk 0x00000000 offset: 0 Unlocked Map Header:: next 0x00000000 #extents: 1 obj#: 25755 flag: 0x40000000 Extent Map ----------------------------------------------------------------- 0x02c00003 length: 4 nfl = 1, nfb = 1 typ = 1 nxf = 0 SEG LST:: flg: USED lhd: 0x02c00003 ltl: 0x02c00003
End dump data blocks tsn: 8 file#: 11 minblk 2 maxblk 2――――――――――――――――――――――――――――――――――這里我們看到表空間號是tsn: 8,數據文件號是file#: 11,相對數據塊地址是rdba: 0x02c00002 (11/2),SCN為scn: 0x0000.001148eb(SCN Base=0011,SCN Wrap=48eb),尾區版本號為tail: 0x48eb1001(tail=SCN Wrap: 48eb + type: 0x10+ seq: 0x01),由于這個塊是整個Segment的頭,所以它還包含整個Segment的一些存儲信息,比如extent數,block數,高水位地址 Highwater:: 0x02c00004,自由列表信息hdr's freelists: 1等等。假如才用本地治理表空間,則此塊的存儲信息通過位圖方式治理。真正的數據是儲存在下一個塊也就是0x02c00002+1=0x02c00003,我們來看看究竟。――――――――――――――――――――――――――――――――――*** 2003-06-12 12:00:41.781Start dump data blocks tsn: 8 file#: 11 minblk 3 maxblk 3buffer tsn: 8 rdba: 0x02c00003 (11/3)scn: 0x0000.001148ee seq: 0x01 flg: 0x02 tail: 0x48ee0601frmt: 0x02 chkval: 0x0000 type: 0x06=trans data Block header dump: 0x02c00003 Object id on Block? Y seg/obj: 0x649b csc: 0x00.1148eb itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc0x01 xid: 0x0006.03f.000000da uba: 0x00800ad2.00ae.04 --U- 2 fsc 0x0000.001148eedata_block_dump===============tsiz: 0x1fb8hsiz: 0x16pbl: 0x0ec77444bdba: 0x02c00003flag=-----------ntab=1nrow=2frre=-1fsbo=0x16fseo=0x1facavsp=0x1f90tosp=0x1f900xe:pti[0] nrow=2 offs=00x12:pri[0] offs=0x1fb20x14:pri[1] offs=0x1facblock_row_dump:tab 0, row 0, @0x1fb2tl: 6 fb: --H-FL-- lb: 0x1 cc: 1col 0: [ 2] c1 02tab 0, row 1, @0x1factl: 6 fb: --H-FL-- lb: 0x1 cc: 1col 0: [ 2] c1 03end_of_block_dumpEnd dump data blocks tsn: 8 file#: 11 minblk 3 maxblk 3――――――――――――――――――――――――――――――――――謎團解開了,ITL,數據都呈現出來了,開始分析!Block header dump: 0x02c00003 Object id on Block? Y seg/obj: 0x649b csc: 0x00.1148eb itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01 數據塊地址正是0x02c00002+1=0x02c00003segment/object id為0x649b,轉成10進制為25755,可以由obj#表中得知
SQL> select obj# from sys.obj$ where name='TESTBLOCK';
OBJ#---------- 25755 csc(SCN at last Block CleanOut): 0x00.1148eb表示最后一次塊清除(Block CleanOut)時候的SCN,關于塊清除的概念可以查閱Thomas Kyte 著的”eXPert one by one Oracle”。
itc: 1 表示Number of itl slots flg: O 表示此塊被放置在自由列表(freelist)中 typ: 1 – DATA,類型1表示數據,類型2表示索引 fsl: 0 ITL TX FREELIST SLOT
fnx: 0x0 自由列表中下一塊的地址――――――――――――――――――――――――――――――――――Itl Xid Uba Flag Lck Scn/Fsc0x01 xid: 0x0006.03f.000000da uba: 0x00800ad2.00ae.04 --U- 2 fsc 0x0000.001148ee這個事務列表中當前有一個事務,里面記載著slot號,事務id,undo block address,受影響的行數,事務遞交時的scn等Itl slot =0x01 事務id= xid: 0x0006.03f.000000da由于xid由3部分組成,xid= Undo Segment Number +Transaction Table Slot Number+ Wrap ,得到0x0006 – Undo Segment Number 03f – Transaction Table Slot Number 000000da– Wrap 回滾塊地址=uba: 0x00800ad2.00ae.04由于uba由3部分組成,uba= Address of the last undo block used+ Sequence+ Last Entry in UNDO record map得到0x00800ad2– Address of the last undo block used 00ae– Sequence 04– Last Entry in UNDO record map flag標志我引用www.ixora.com.au的一段解釋,這里的--U-表示已經遞交---- = transaction is active, or committed pending cleanoutC--- = transaction has been committed and locks cleaned out-B-- = this undo record contains the undo for this ITL entry--U- = transaction committed (maybe long ago); SCN is an upper bound---T = transaction was still active at block cleanout SCNLck(number of rows affected by this transaction)表示這個事務所影響的行數,這里是2行,正好對應2次insert Scn/Fsc 標志我引用www.ixora.com.au的一段解釋
If the transaction has been cleaned out, this is the commit SCN or an upper bound thereof. Otherwise the leading two bytes contain the free space credit for the transaction - that is, the number of bytes freed in the block by the transaction―――――――――――――――――――――――――――――――――――――――data_block_dump===============tsiz: 0x1fb8hsiz: 0x16pbl: 0x0ec77444bdba: 0x02c00003flag=-----------ntab=1nrow=2frre=-1fsbo=0x16fseo=0x1facavsp=0x1f90tosp=0x1f900xe:pti[0] nrow=2 offs=00x12:pri[0] offs=0x1fb20x14:pri[1] offs=0x1fac―――――――――――――――――――――――――――――――――――――――――這一部分記載著一些儲存參數,簡單得分析一些,給出各個標志的解釋tsiz:Total Data Area Size(數據塊的大小)hsiz:Data Header Size(數據塊頭大小)pbl: ptr to buffer holding the block(指向這個數據塊在內存中映象的指針)bdba: block dba / rdba(數據塊地址)flag: n=pctfree hit (clusters),f=dont put on freelist k=flushable cluster keysntab: number of tables (>1 is a cluster)nrow: number of rows
frre: first free row index entry, -1=you have to add one(沒有創建索引)fsbo: free space begin offset(從hsiz開始)fseo: free space end offset()avsp: available space in the block(可用空間)tosp: total available space when all txs commit0xe:pti[0] nrow=2 offs=0本塊儲存2條記錄0x12:pri[0] offs=0x1fb2---- 記錄的起始物理位置 ―――――――――――――――――――――――――――――――――――――――――終于見到到數據了,這個部分就存儲著對應的記錄,繼續分析block_row_dump:tab 0, row 0, @0x1fb2 tl: 6 fb: --H-FL-- lb: 0x1 cc: 1 ol 0: [ 2] c1 02tab 0, row 1, @0x1factl: 6 fb: --H-FL-- lb: 0x1 cc: 1col 0: [ 2] c1 03end_of_block_dumpEnd dump data blocks tsn: 8 file#: 11 minblk 3 maxblk 3―――――――――――――――――――――――――――――――――――――――tl表示Row Size(number of bytes plus data)fb:Flag Byte H-head of row piece F-first data piece L-last data piece Lb表示lock byte,表示這個事務在itl的入口Cc表示number of columns in this Row piece,表示這一行只有1列col 0: [ 2] c1 02 第一列,[2]表示長度,c1 02是數據(經過一套復雜的過程可以轉換成10進制數據)到此為止,數據塊的結構我們已經都把它展開并進行了分析,期待大家的繼續!