作者:grassbell
1. Data Block 物理結構圖:
2. 一次對block的dump過(guò)程:
SQL> create table t9 (a varchar(10));
Table created.
SQL> insert into t9 values(‘a(chǎn)‘);
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中完成讀和寫(xiě)操作的,所以它提供了20bytes的Cache Header和4bytes的 Tail給Cache,用來(lái)讀取和管理。
第2部分是為Transaction層提供的Header信息。它一共占據了48bytes,包括24bytes的控制信息,和一系列的Interested Transaction Slot (ITS)。
剩下的部分都叫Data Area,用來(lái)存儲用戶(hù)數據。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,應該是用來(lái)區分版本。Oracle 8之前值為1,之后為2。
Checksum: 占用2byte,跟db_block_checksum 參數有關(guān)系。
引用oracle document 的解釋?zhuān)?/span>”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,經(jīng)常用到的有,1=undo segment header block; 2=undo data block; 5= data segment header block; 6=data block
Unused: 保留的字節,占用4bytes,用來(lái)前后兼容。
Tail 包括了SCN中SCN base的低位(low-order)2bytes,然后是block type,還有Sequence number。每當block 被讀的時(shí)候,都要檢查Tail與 block header 是否一致,保證了這個(gè)block不是損壞的(corrupted)。
2) The Transaction Header:
一共占據48bytes,包括24bytes的控制信息,和一系列的Interested Transaction Slot (ITS)。這些ITS組合在一起稱(chēng)為Interested Transaction List (ITL)。初始的ITL slot 數量由 INITRANS 決定(index branch block 只有1個(gè)slot)。如果有足夠的剩余空間,oracle會(huì )根據需要動(dòng)態(tài)的分配這些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表示這個(gè)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中下一個(gè)block的RDBA
Version: 1 byte
Unused: 4bytes,用來(lái)前后兼容。
每個(gè)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. 如果這個(gè)事務(wù)已經(jīng)clean out,這個(gè)值就是SCN;否則,前兩個(gè)字節表示由這個(gè)事務(wù)釋放的此block中的空間數。
3)Data Area
包括14bytes的data header,4bytes/table的table dictionary,2bytes/row的row dictionary。table dictionary主要用于cluster block中,只不過(guò)table block中的table dictionary只有一個(gè)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. 對于一個(gè)沒(méi)有插入任何row的block來(lái)說(shuō),并且假設使用了默認的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
小結:
這篇文章的目的在于給大家一個(gè)對data block的大概認識,和碰到問(wèn)題時(shí)的一個(gè)參考。不是自己的,多研究,多做實(shí)驗,把心得寫(xiě)出來(lái),變成自己的。
聯(lián)系客服