Oracle Data block 的物理結構

jss001發表於2009-02-24
1. Data Block 物理結構圖:




2. 一次對block的dump過程:



SQL> create table t9 (a varchar(10));

Table created.



SQL> insert into t9 values('a');

1 row created.



SQL> commit;

Commit complete.



SQL> set serveroutput on

SQL> exec show_space('T9');

Free Blocks.............................1

Total Blocks............................8

Total Bytes.............................65536

Unused Blocks...........................6

Unused Bytes............................49152

Last Used Ext FileId....................3

Last Used Ext BlockId...................121

Last Used Block.........................2



PL/SQL procedure successfully completed.



SQL> alter system dump datafile 3 block 122;

System altered.



SQL> select * from v$tablespace;

TS# NAME INC

---------- ------------------------------ ---

0 SYSTEM YES

1 UNDOTBS1 YES

8 USERS YES

18 TEMP1 YES



Trace 檔案:

*** 2004-07-25 15:48:01.000

Start dump data blocks tsn: 8 file#: 3 minblk 122 maxblk 122

buffer tsn: 8 rdba: 0x00c0007a (3/122)

scn: 0x0000.0068d716 seq: 0x01 flg: 0x02 tail: 0xd7160601

frmt: 0x02 chkval: 0x0000 type: 0x06=trans data

Block header dump: 0x00c0007a

Object id on Block? Y

seg/obj: 0x806d csc: 0x00.68d714 itc: 2 flg: O typ: 1 - DATA

fsl: 0 fnx: 0x0 ver: 0x01



Itl Xid Uba Flag Lck Scn/Fsc

0x01 0x0004.00b.00000fac 0x00801885.008c.56 --U- 1 fsc 0x0000.0068d716

0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000



data_block_dump,data header at 0x552105c

===============

tsiz: 0x1fa0

hsiz: 0x14

pbl: 0x0552105c

bdba: 0x00c0007a

76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

fseo=0x1f9b

avsp=0x1f83

tosp=0x1f83

0xe:pti[0] nrow=1 offs=0

0x12:pri[0] offs=0x1f9b

block_row_dump:

tab 0, row 0, @0x1f9b

tl: 5 fb: --H-FL-- lb: 0x1 cc: 1

col 0: [ 1] 61

end_of_block_dump

End dump data blocks tsn: 8 file#: 3 minblk 122 maxblk 122



3. 先介紹資料塊中包括的3種頭資訊:



首先,資料塊是在data block buffer cache中完成讀和寫操作的,所以它提供了20bytes的Cache Header和4bytes的 Tail給Cache,用來讀取和管理。

第2部分是為Transaction層提供的Header資訊。它一共佔據了48bytes,包括24bytes的控制資訊,和一系列的Interested Transaction Slot (ITS)。

剩 下的部分都叫Data Area,用來儲存使用者資料。Data Area也包括data header,和row data及剩餘空間。但是Cluster blocks, table blocks, index block的data header,row data結構是不相同的,這裡主要介紹table blocks.



4. 結合trace檔案中的資訊,詳細介紹:



1) The Cache Header and Tail:

buffer tsn: 8 rdba: 0x00c0007a (3/122)

scn: 0x0000.0068d716 seq: 0x01 flg: 0x02 tail: 0xd7160601

frmt: 0x02 chkval: 0x0000 type: 0x06=trans data



Database block address: 佔用4 bytes,表示Tablespace relative database block address(RDBA)。包括tns=8,即Tablespace number (User 表空間),file#=3, block_id=122

SCN: 佔用6bytes,表示最後變化的scn。包括2bytes的高位位元組(SCN wrap),和4bytes的低位位元組(SCN base)

Sequence: 佔用1byte,用途不明確,可能是輔助SCN的變化

Flag: 佔用1byte

Format: 佔用1byte,應該是用來區分版本。Oracle 8之前值為1,之後為2。

Checksum: 佔用2byte,跟db_block_checksum 引數有關係。

引 用oracle document 的解釋:”DB_BLOCK_CHECKSUM determines whether DBWn and the direct loader will calculate a checksum (a number calculated from all the bytes stored in the block) and store it in the cache header of every data block when writing it to disk. Checksums are verified when a block is read-only if this parameter is true and the last write of the block stored a checksum. In addition, Oracle gives every log block a checksum before writing it to the current log.

If this parameter is set to false, DBWn calculates checksums only for the SYSTEM tablespace, but not for user tablespaces.”

Block type: 佔用1byte,經常用到的有,1=undo segment header block; 2=undo data block; 5= data segment header block; 6=data block

Unused: 保留的位元組,佔用4bytes,用來前後相容。



Tail 包括了SCN中SCN base的低位(low-order)2bytes,然後是block type,還有Sequence number。每當block 被讀的時候,都要檢查Tail與 block header 是否一致,保證了這個block不是損壞的(corrupted)。



2) The Transaction Header:



一 共佔據48bytes,包括24bytes的控制資訊,和一系列的Interested Transaction Slot (ITS)。這些ITS組合在一起稱為Interested Transaction List (ITL)。初始的ITL slot 數量由 INITRANS 決定(index branch block 只有1個slot)。如果有足夠的剩餘空間,oracle會根據需要動態的分配這些slot,直到受到空間限制或者達到了MAXTRANS。



Block header dump: 0x00c0007a

Object id on Block? Y

seg/obj: 0x806d csc: 0x00.68d714 itc: 2 flg: O typ: 1 - DATA

fsl: 0 fnx: 0x0 ver: 0x01



Itl Xid Uba Flag Lck Scn/Fsc

0x01 0x0004.00b.00000fac 0x00801885.008c.56 --U- 1 fsc 0x0000.0068d716

0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000



24bytes的控制資訊包括:

Object number(seg/obj): 佔用4bytes,指在OBJ$中記錄的segment 的 object number(0x806d=32877)

Cleanout SCN(csc): 佔用6bytes,最後一次 full cleanout 的scn

ITL count(itc): 佔用1byte,ITL 的slot數量。

Flag: 佔用2bytes。O表示這個block在freelist 上。否則flag為”-”

Block type: 佔用1byte。1=data; 2=index

ITL freelist slot(fsl): 佔用1byte。Index to the first slot on the ITL freelist

Next freelist block(fnx): 佔用4byte。Segment freelist中下一個block的RDBA

Version: 1 byte

Unused: 4bytes,用來前後相容。



每個ITL entry包括以下的內容:

Transaction id(Xid): 8bytes。其中包括rollback segment number, transaction table中的slot number等。

Undo block address(Uba): 8bytes。其中包括rollback segment block的DBA,sequence number等。

Flags: 1nibble。---- = transaction is active, or committed pending cleanout
C--- = 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 SCN

Locks: 3nibbles. 也就是所謂的行級鎖(row-level locks)

SCN or free space credit: 6bytes. 如果這個事務已經clean out,這個值就是SCN;否則,前兩個位元組表示由這個事務釋放的此block中的空間數。



3)Data Area



包 括14bytes的data header,4bytes/table的table dictionary,2bytes/row的row dictionary。table dictionary主要用於cluster block中,只不過table block中的table dictionary只有一個table。



data_block_dump,data header at 0x552105c

===============

tsiz: 0x1fa0 ==> total data area size

hsiz: 0x14 ==> data header size (14+ntabs*4 + nrows*2)

pbl: 0x0552105c ==> pointer to buffer holding the block

bdba: 0x00c0007a ==> block dba / rdba

76543210

flag=-------- ==> n=pctfree hit (clusters),f=don’t put on freelist, k=flushable cluster keys

ntab=1 ==> number of tables (>1 so this is a cluster)

nrow=1 ==> number of rows

frre=-1

fsbo=0x14 ==> free space begin offset

fseo=0x1f9b ==> free space end offset

avsp=0x1f83 ==> available space in the block

tosp=0x1f83 ==> total available space when all transactions commit

0xe:pti[0] nrow=1 offs=0

0x12:pri[0] offs=0x1f9b

block_row_dump:

tab 0, row 0, @0x1f9b ==> 3bytes row header

tl: 5 fb: --H-FL-- lb: 0x1 cc: 1

col 0: [ 1] 61 ==> column length(1 byte if length<250; otherwise 3 bytes) and values

end_of_block_dump



5. 對於一個沒有插入任何row的block來說,並且假設使用了預設的INITRANS,它的大小應該是:

db_block_size- (cache header+ transaction header +data header + Tail + table dictionary*ntab + row dictionary*row )=8192 - ( 20+48+14+4+4 +0)=8192 - 90 =8102 bytes



小結:

這篇文章的目的在於給大家一個對data block的大概認識,和碰到問題時的一個參考。不是自己的,多研究,多做實驗,把心得寫出來,變成自己的。[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/18921899/viewspace-1016905/,如需轉載,請註明出處,否則將追究法律責任。

相關文章