分享

偷窥Data block 的物理结构

 bez 2006-08-26

偷窥Data block 的物理结构

作者:grassbell

 

 

1. Data Block 物理结构图:

2. 一次对blockdump过程:

 

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中完成读和写操作的,所以它提供了20bytesCache Header4bytes TailCache,用来读取和管理。

2部分是为Transaction层提供的Header信息。它一共占据了48bytes,包括24bytes的控制信息,和一系列的Interested Transaction Slot (ITS)

剩下的部分都叫Data Area,用来存储用户数据。Data Area也包括data header,和row data及剩余空间。但是Cluster blocks, table blocks, index blockdata headerrow 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 包括了SCNSCN base的低位(low-order2bytes,然后是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 只有1slot)。如果有足够的剩余空间,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 numberseg/obj: 占用4bytes,指在OBJ$中记录的segment object number(0x806d=32877)

Cleanout SCNcsc:  占用6bytes,最后一次 full cleanout scn

ITL countitc: 占用1byteITL slot数量。

Flag: 占用2bytesO表示这个blockfreelist 上。否则flag”-”

Block type: 占用1byte1=data; 2=index

ITL freelist slotfsl: 占用1byteIndex to the first slot on the ITL freelist

Next freelist blockfnx: 占用4byteSegment freelist中下一个blockRDBA

Version: 1 byte

Unused: 4bytes,用来前后兼容。

 

每个ITL entry包括以下的内容:

Transaction idXid: 8bytes。其中包括rollback segment number, transaction table中的slot number等。

Undo block addressUba: 8bytes。其中包括rollback segment blockDBAsequence 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中的空间数。

 

3Data Area

 

包括14bytesdata header4bytes/tabletable dictionary2bytes/rowrow dictionarytable 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.   对于一个没有插入任何rowblock来说,并且假设使用了默认的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的大概认识,和碰到问题时的一个参考。不是自己的,多研究,多做实验,把心得写出来,变成自己的。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多