您好,登錄后才能下訂單哦!
Oracle block的詳細(xì)物理結(jié)構(gòu)圖:
本文主要說明oracle block的物理結(jié)構(gòu),它是oracle的最小存儲(chǔ)單元,由多個(gè)os數(shù)據(jù)塊組成。主要由三個(gè)邏輯層組成(通過c語(yǔ)言描繪的結(jié)構(gòu),如下圖一所示):the cache layer,the transaction layer,data layer。如果再細(xì)化,data layer又分為很多結(jié)構(gòu),如table directory,row directory,free space,row data等
Oracle的block被映射到SGA kcbh(kernel cache block header)的對(duì)應(yīng)的block上 。
the cache layer:它是block header的第一部分,占用20個(gè)bytes。用于檢查數(shù)據(jù)的正確性,即被讀的block是否斷裂或損壞。它包含如下結(jié)構(gòu)
1. the data block address(DBA)
2. the block type (例如Table/Index, Rollback Segment, Temporary)
3. the block format (8i~9i 都是0x02 10.1.0 2k: 0x62 4k:0x82 8k:0xa2 16k:0xc2 (logfile 0x22 512 bytes))
4. a system change number(SCN)used for ordering purposes during recovery
the transaction layer: 用戶存儲(chǔ)數(shù)據(jù)塊里transaction信息的,包含兩部分信息
1. 一個(gè)是a fixed component ,KTBBH(TRANSACTION FIXED HEADER),包含關(guān)于數(shù)據(jù)塊的類型,數(shù)據(jù)塊的最 新cleanout時(shí)間,ITL(Interested Transcation List)的數(shù)量,空閑列表的鏈接,還有空閑空間lock。
2. 另一個(gè)是 a variable portion,KTBIT(TRANSACTION VARIABLE HEADER),包含一個(gè)進(jìn)程在一個(gè)block里要編輯行所需要的ITLs。默認(rèn)的包含一個(gè)表的數(shù)據(jù)塊只有一個(gè)ITL,ITL的多少是通過存儲(chǔ)參數(shù)INITRANS來設(shè)置的,設(shè)置較大的值會(huì)減少row data的可用空間,這個(gè)參數(shù)是可以動(dòng)態(tài)修改的,但只影響新的block,對(duì)已經(jīng)存在的block沒有作用(可以用imp/exp,move等方法可以讓其對(duì)存在的block起作用)
The data layer:包含data header 結(jié)構(gòu),KDBH(kernel data block header,是DATA HEADER,占用14bytes),和row data。其中data header包含表的數(shù)量(在表索引中,即table directory),數(shù)據(jù)行的數(shù)量,第一個(gè)空閑行的條目(在行索引中,即row directory),指向空閑區(qū)域的開始和結(jié)束的偏移量,可用的空閑空間。數(shù)據(jù)行是從block的底部開始insert的,伴隨insert和delete操作,行數(shù)據(jù)是隨機(jī)存儲(chǔ)的。
如下圖所示:
假設(shè)初始化5行數(shù)據(jù),每行10bytes大小,按offsets排序是5,4,3,2,1。現(xiàn)在刪除2,4行,再insert一行20bytes的數(shù)據(jù),在row directory 中slot2被使用,但實(shí)際的row data存儲(chǔ)在row5之上。這個(gè)時(shí)候再按offsets排序就是2,5,3,1 。隨著你在數(shù)據(jù)塊上的DML操作的越頻繁,這種行的隨機(jī)性就更強(qiáng)。
下面說下data block的設(shè)計(jì),如下圖所示
下面是oracle block的dump文件,結(jié)合上面這個(gè)圖片來驗(yàn)證下oracle block的存儲(chǔ)情況
Dump file e:/oracle/product/10.2.0/admin/test/udump/test_ora_4820.trc
Thu Aug 19 13:01:36 2010
ORACLE V10.2.0.4.0 - Production vsnsta=0
vsnsql=14 vsnxtr=3
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Windows XP Version V5.1 Service Pack 3, v.3300
CPU : 2 - type 586, 2 Physical Cores
Process Affinity : 0x00000000
Memory (Avail/Total): Ph:313M/1918M, Ph+PgF:2399M/3812M, VA:1289M/2047M
Instance name: test
Redo thread mounted by this instance: 1
Oracle process number: 21
Windows thread id: 4820, image: ORACLE.EXE (SHAD)
*** 2010-08-19 13:01:36.593
*** ACTION NAME:() 2010-08-19 13:01:36.578
*** MODULE NAME:(SQL*Plus) 2010-08-19 13:01:36.578
*** SERVICE NAME:(test) 2010-08-19 13:01:36.578
*** SESSION ID:(201.21830) 2010-08-19 13:01:36.578
Error: alter system dump datafile/tempfile: invalid input file # 0
*** 2010-08-19 13:02:41.375
Error: alter system dump datafile/tempfile: invalid input file # 0
*** 2010-08-19 13:03:17.296
Start dump data blocks tsn: 4 file#: 4 minblk 29347 maxblk 29347
buffer tsn: 4 rdba: 0x010072a3 (4/29347)
scn: 0x0000.009b876f seq: 0x01 flg: 0x04 tail: 0x876f2301
frmt: 0x02 chkval: 0x4671 type: 0x23=PAGETABLE SEGMENT HEADER
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x0A2A8400 to 0x0A2AA400
A2A8400 0000A223 010072A3 009B876F 04010000 [#....r..o.......]
A2A8410 00004671 00000000 00000000 00000000 [qF..............]
A2A8420 00000000 00000001 00000008 00000A9C [................]
A2A8430 00000000 00000004 00000008 010072A5 [.............r..]
..r......
..r......
A2A9850 00000000 00000000 00000000 00000000 [................]
Repeat 185 times
A2AA3F0 00000000 00000000 00000000 876F2301 [.............#o.]
這里說明下TAIL用于驗(yàn)證block的完整性的,它是由SCNBase,block type,SCN seq number組成。
876F2301=876F(last two bytes of SCN Base)+ 23(type)+ 01(seq)
紅色的字是offset(偏移量)
首先來看前20個(gè)bytes,也就是the cache layer,16進(jìn)制的數(shù)據(jù)如下:
0000A223 010072A3 009B876F 04010000 00004671
第一和第二個(gè)字節(jié)是filler,也就是未被使用(
ub1 spare1_kcbh this field is no longer used (old inc#, now always 0)
ub1 spare2_kcbh this field is no longer used (old ts#, now always 0)
),未被定義(和前面的圖有點(diǎn)出入)
第三個(gè)字節(jié)是frmt,一般是0x02,這里是0xa2,用掩碼0x0f與運(yùn)算可以取出0x02(掩碼是為了保護(hù)敏感信息)
第四個(gè)字節(jié)是type,這里是23,代表PAGETABLE SEGMENT HEADER
第五個(gè)到第八個(gè)字節(jié)是rdba,這里是0x010072a3
第九個(gè)到第十二字節(jié)是SCNBase ,這里是 0x009B876F
第十三個(gè)字節(jié)是flg,這里是0x04
(
as defined in kcbh.h
#define KCBHFNEW 0x01 /* new block - zeroed data area */
#define KCBHFDLC 0x02 /* Delayed Logging Change advance SCN/seq */
#define KCBHFCKV 0x04 /* ChecK Value saved-block xor's to zero */
#define KCBHFTMP 0x08 /* Temporary block */
這是一個(gè)可以組合的值 也就是說有為 6 的時(shí)候是 2,4 兩種情況的組合
)
第十四個(gè)字節(jié)seq,這里是 0x01。
(A sequence number incremented for each change to a block at the same SCN
A new SCN is allocated if the sequence number wraps.
同一個(gè)SCN影響這個(gè)block中的行數(shù)大于 254 行就會(huì)為這個(gè)事務(wù)分配一個(gè)新的SCN
如下面的操作就可能引起同一個(gè)SCN但影響的同一個(gè)block 中的行超過254行
"delete from table_name"
影響的行數(shù)(最大254) 是用從 0x01 到 0xfe 表示的
當(dāng)這個(gè)byte 的數(shù)據(jù)為 0xff 的時(shí)候標(biāo)志這個(gè) block 壞調(diào)了---> ora-01578
Sequence number:
SEQ -> 0 /* non-logged changes - do not advance seq# */
SEQ -> (UB1MAXVAL-1)/* maximum possible sequence number */
SEQ -> (UB1MAXVAL) /* seq# to indicate a block is corrupt,equal to FF. soft corrupt*/
0xff : When present it indicates that the block has been marked as corrupt by Oracle. either by the db_block_checking functionality or the equivalent events (10210 for data blocks, 10211 for index blocks, and 10212 for cluster blocks) when making a database change, or by the DBMS_REPAIR.FIX_CORRUPT_BLOCKS procedure, or by PMON after an unsuccessful online block recovery attempt while recovering a failed process, or by RMAN during a BACKUP, COPY or VALIDATE command with the CHECK LOGICAL option. Logical corruptions are normally due to either recovery through a NOLOGGING operation, or an Oracle software bug.)
第十五和第十六字節(jié)是SCNWrap ,這里是0x0000
第十七和第十八字節(jié)是spare3_kcbh,這里未使用
第十九和第二十字節(jié)是checksum,這里是0x4671
正好和dump的內(nèi)容一樣
buffer tsn: 4 rdba: 0x010072a3 (4/29347)
scn: 0x0000.009b876f seq: 0x01 flg: 0x04 tail: 0x876f2301
frmt: 0x02 chkval: 0x4671 type: 0x23=PAGETABLE SEGMENT HEADER
相關(guān)說明:
Rdba:block的相對(duì)地址(DBA)
Scn: SCN number
Seq:sequence number incremented for each change made to the block at the same SCN
Flg:flag
Tail:驗(yàn)證block的完整性,通過檢查block的開始和結(jié)束是否是同一版本
Frmt:block format 通常是0x02
Chkval:如果db_block_checksum=true時(shí),block的核查值
Type:block的類型,如data,index等
到此block的前20bytes都已經(jīng)解讀了,然后再看看緊跟其后的kttbh 的24bytes內(nèi)容解讀
BBED> p ktbbh
struct ktbbh, 48 bytes @20
ub1 ktbbhtyp @20 0x01 (KDDBTDATA)
union ktbbhsid, 4 bytes @24
ub4 ktbbhsg1 @24 0x0000001c
ub4 ktbbhod1 @24 0x0000001c
struct ktbbhcsc, 8 bytes @28
ub4 kscnbas @28 0x805c12df
ub2 kscnwrp @32 0x0000
b2 ktbbhict @36 1
ub1 ktbbhflg @38 0x02 (NONE)
ub1 ktbbhfsl @39 0x00
ub4 ktbbhfnx @40 0x00000000
struct ktbbhitl[0], 24 bytes @44
struct ktbitxid, 8 bytes @44
ub2 kxidusn @44 0x0002
ub2 kxidslt @46 0x0025
ub4 kxidsqn @48 0x0006e714
struct ktbituba, 8 bytes @52
ub4 kubadba @52 0x00801ba0
ub2 kubaseq @56 0xaa14
ub1 kubarec @58 0x10
ub2 ktbitflg @60 0x2001 (KTBFUPB)
union _ktbitun, 2 bytes @62
b2 _ktbitfsc @62 0
ub2 _ktbitwrp @62 0x0000
ub4 ktbitbas @64 0x805c12e0
以下是16進(jìn)制文件內(nèi)容:
Start dump data blocks tsn: 4 file#: 4 minblk 29348 maxblk 29348
buffer tsn: 4 rdba: 0x010072a4 (4/29348)
scn: 0x0000.00e66a1e seq: 0x02 flg: 0x06 tail: 0x6a1e0602
frmt: 0x02 chkval: 0x4590 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x061E8400 to 0x061EA400
61E8400 0000A206 010072A4 00E66A1E 06020000 [.....r...j......]
61E8410 00004590 00000001 0000ED65 009B8769 [.E......e...i...]
61E8420 00000000 00320003 010072A1 0000FFFF [......2..r......]
61E8430 00000000 00000000 00000000 00008000 [................]
61E8440 009B8769 00190001 00001B03 0080027B [i...........{...]
61E8450 002C0E55 00002001 00E66A1E 00000000 [U.,.. ...j......]
61E8460 00000000 00000000 00000000 00000000 [................]
61E8470 00000000 00000000 00000000 00090100 [................]
61E8480 0024FFFF 1C291C4D 00001C29 1F1E0009 [..$.M.).).......]
61E8490 1E6C1EC3 1DB71E13 1D021D5B 1C4D1CA7 [..l.....[.....M.]
61E84A0 00000000 00000000 00000000 00000000 [
.
.
.
61EA3E0 38302D35 3A30332D 353A3331 30333A30 [5-08-30:13:50:30]
61EA3F0 4C415605 4E014449 4E014E01 6A1E0602 [.VALID.N.N.N...j]
其中buffer tsn: 數(shù)據(jù)文件對(duì)應(yīng)的 tablespace 的 number ,這只是dump文件中記錄的數(shù)據(jù)而已,block 中是沒有記錄 tablespace 的number 的
第21-24字節(jié),即0x00000001,表示typ ,占4個(gè)bytes
(
1 : DATA , 2: index
改成3了在10.1.0 上引起了ora-600[2032]然后ORA-27101: shared memory realm does not exist
oracle進(jìn)行查詢的時(shí)候是根據(jù) obj$表中的情況來判斷對(duì)象的類型的,不是根據(jù)這個(gè)typ
也就是說如果有一個(gè)表但改變表中block的這個(gè)標(biāo)志位,一樣可以查詢出數(shù)據(jù)來,
但dump block 時(shí)會(huì)出錯(cuò),ORA-00600: 內(nèi)部錯(cuò)誤代碼,自變量: [4555], [0], [], [], [], [], [], []
錯(cuò)誤中的 [0] 就是typ對(duì)應(yīng)的數(shù)據(jù)
在10G中改變它后update這個(gè)block的數(shù)據(jù)commit可以但rollback的報(bào)錯(cuò))
第25-28字節(jié),即0x0000ED65,表示seg/obj,占4個(gè)字節(jié)
第29-36字節(jié),即 0x009B8769.00000000,表示csc ,占6個(gè)字節(jié)(The SCN at which the last full cleanout was performed on the block)
第37字節(jié),即0x00 表示 fsl (Index to the first slot on the ITL freelist. ITL TX freelist slot)
第38字節(jié),即0x32 表示flg
(
indicates that the block is on a freelist. Otherwise the flag is -
9i 的ASSM 的情況下這個(gè)值為 E
ixora 上說他占用 2 bytes 但我下面的試驗(yàn)和他的結(jié)果有一定的出入
我觀察到的情況是 : Object id on Block? Y flg: O ver: 0x01
上面的3項(xiàng)是用同一個(gè) byte 來表示的
flg: O ver: 0x01 Object id on Block? Y
從我的觀察中 dump 出來的文件中 flg ver Object id on Block
他們共同占用的這個(gè)一個(gè)字節(jié) 他的規(guī)律可以從下面的情況看出
2進(jìn)制數(shù)據(jù) flg ver Object id on Block?
0x00 - 0x00 N
0x01 0 0x00 N
0x02 - 0x01 Y
0x03 0 0x01 Y
0x04 - 0x02 Y
0x05 0 0x02 Y
0x06 - 0x03 Y
0x07 0 0x03 Y
0x08 - 0x04 N
0x09 0 0x04 N
0x0a - 0x05 Y
0x0b 0 0x05 Y
0x0c - 0x06 Y
0x0d 0 0x06 Y
0x0e - 0x07 Y
0x0f 0 0x07 Y
0x10 ... 類似上面的循環(huán)了 這種情況在9i上已經(jīng)改變因?yàn)?span lang="EN-US">ASSM的出現(xiàn)
)
第39-40字節(jié),即0x0003 表示 itc ,占2個(gè)字節(jié)。用0x00ff掩碼取值,值為3(ITL 條目的個(gè)數(shù) max 255超過會(huì)報(bào)ORA-02207 ORA-00060 ORA-00054 可能是沒空間分配itl條目了或它的爭(zhēng)用引起的,在8i中 INITRANS default為1 , 9.2.0中 INITRANS default為2)
第41-44字節(jié),即0x010072A1 表示 (自由列表中下一塊的地址 Null if this block is not on a freelist)
從44字節(jié)以后就是ITL的記錄,每個(gè)itl所占24bytes
第45-52字節(jié),即0x0000.FFFF.00000000,表示xid
(
Transaction ID (UndoSeg.Slot.Wrap)
值可以用select XIDUSN, XIDSLOT,XIDSQN from v$transaction;查到
This is comprised of the rollback segment number (2 bytes), the slot number
in the transaction table of that rollback segment (2 bytes), and the number
of times use of that transaction table has wrapped (4 bytes).
)
第53-60字節(jié),即0x00000000.000000.00,表示uba
(
Undo address (UndoDBA.SeqNo.RecordNo)
The location of the undo for the most recent change to this block by this transaction. This is comprised of the DBA of the rollback segment block (4 bytes), the sequence number (2 bytes), and the record number for the change in that undo block (1 byte), plus 1 unused byte.
)
第63-64字節(jié),即0x8000 ,表示lck flag
(
Lck 鎖定的row數(shù) 這里還用到了下一個(gè) byte 的數(shù)據(jù)
2 對(duì)應(yīng)的二進(jìn)制表示為 0010 正好和dump文件中的 --U- 吻合
flag 1 nibble
C = Committed; U = Commit Upper Bound; T = Active at CSC; B = Rollback of this UBA gives before image of the ITL.
---- = 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
Lck 3 nibbles
The number of row-level locks held in the block by this transaction.)
第61-62和65-68字節(jié),即 0x0000.009B8769 表示Scn/Fsc:
(
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
Scn = SCN of commited TX; Fsc = Free space credit (bytes)
)
再往下分析,
Block header dump: 0x010072a4
Object id on Block? Y
seg/obj: 0xed65 csc: 0x00.9b8769 itc: 3 flg: E typ: 1 - DATA
brn: 0 bdba: 0x10072a1 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.009b8769
0x02 0x0001.019.00001b03 0x0080027b.0e55.2c --U- 1 fsc 0x0000.00e66a1e
0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
因?yàn)檫@里有三個(gè)itls,所有共占用24×3=72bytes空間,再加上20+24+8(這個(gè)可能是保留的,具體做什么,不是很清楚?),總124字節(jié)
16進(jìn)制文件如下:
61E8470 00000000 00000000 00000000 00090100 [................]
61E8480 0024FFFF 1C291C4D 00001C29 1F1E0009 [..$.M.).).......]
61E8490 1E6C1EC3 1DB71E13 1D021D5B 1C4D1CA7 [..l.....[.....M.]
第125字節(jié),即0x00 表示flag
(
N=pctfree hit(clusters), F=don't put on free list
K=flushable cluster keys. 當(dāng)然還有別的標(biāo)記: A ...
)
第126字節(jié),即0x09,表示nrow (block 有多少行數(shù)據(jù))
第127字節(jié),即0x01,表示ntab (這block中有幾個(gè)table的數(shù)據(jù) cluster這個(gè)就可能大于1)
第128-129字節(jié),即0x0000,表示frre (First free row index entry. -1=you have to add one.)
第130字節(jié),即0x24,表示fsbo
(Free Space Begin offset 出去row dict 后面的可以放數(shù)據(jù)的空間的起始位置
也可以看成是從這個(gè)區(qū)域的開始"flag"到最后一個(gè) "row offs"占用的空間)
第135-136字節(jié),即 0x1C4D,表示fseo
(
Free Space End offset ( 9.2.0 )參與db_block_checking的計(jì)算剩余空間
select 的時(shí)候oracle不是簡(jiǎn)單的根據(jù)offset定位row.這個(gè)值也是參與了定位row的
)
第139-140字節(jié),即0x1C29,表示tosp(Total available space when all TXs commit ( 9.2.0 )參與db_block_checking)
第133-134字節(jié),即0x1C29,表示avsp(Available space in the block (pctfree and pctused) ORA-01578)
Oracle的dsi文檔里和bbed查看block的結(jié)構(gòu),都表明kdbh占14字節(jié),但我的這個(gè)測(cè)試和其有些出入,希望高人指出
其中第141-142字節(jié),即0x1F1E,表示offsets (偏移量 用 cluster 的時(shí)候可以看出值)
第143-144字節(jié),即0x0009,表示nrow(這個(gè)table有多少行數(shù)據(jù))
和下面的Block的dump文件是對(duì)應(yīng)符合的
data_block_dump,data header at 0x61e847c
//data_block_dump,data header at 0x61e847c
//其實(shí)這個(gè)block不是直接從 data buffer 中 dump 出來的這個(gè)表示真正dump時(shí) block 的數(shù)//據(jù)區(qū)的起始位置
//也就是下面這部分開始的位置
=============== //// tsiz: hsiz: pbl: bdba: 在數(shù)據(jù)文件都是沒有存儲(chǔ)的
tsiz: 0x1f80 //// Total data area size ---8k的block: 8192-20(block head)-24(Transaction Header)-24*2(一個(gè)事務(wù)條)-8(我不太清楚的8個(gè)字節(jié))-4(block tail)=8072(0x1f80)
hsiz: 0x24 //// Data header size 數(shù)據(jù)塊頭20個(gè)字節(jié)+數(shù)據(jù)塊尾4個(gè)字節(jié)=24字節(jié)(0x14)
pbl: 0x061e847c //// Pointer to buffer holding the block
bdba: 0x010072a4
76543210
flag=--------
ntab=1 ---這block中有幾個(gè)table的數(shù)據(jù) cluster這個(gè)就可能大于1
nrow=9 ---block 有多少行數(shù)據(jù)
frre=-1
fsbo=0x24
fseo=0x1c4d
avsp=0x1c29
tosp=0x1c29
0xe:pti[0] nrow=9 offs=0
0x12:pri[0] offs=0x1f1e
0x14:pri[1] offs=0x1ec3
0x16:pri[2] offs=0x1e6c
0x18:pri[3] offs=0x1e13
0x1a:pri[4] offs=0x1db7
0x1c:pri[5] offs=0x1d5b
0x1e:pri[6] offs=0x1d02
0x20:pri[7] offs=0x1ca7
0x22:pri[8] offs=0x1c4d
block_row_dump:
tab 0, row 0, @0x1f1e
tl: 98 fb: --H-FL-- lb: 0x2 cc: 15
col 0: [ 5] c4 02 07 4c 0c
col 1: [ 4] 32 30 30 31
col 2: [ 3] 53 59 53
col 3: [16] 53 4e 41 50 5f 4c 4f 41 44 45 52 54 49 4d 45 24
col 4: *NULL*
col 5: [ 3] c2 02 3f
col 6: [ 3] c2 02 3e
col 7: [ 5] 54 41 42 4c 45
col 8: [ 7] 78 69 08 1e 0e 33 1f
col 9: [ 7] 78 69 08 1e 0e 33 1f
col 10: [19] 32 30 30 35 2d 30 38 2d 33 30 3a 31 33 3a 35 30 3a 33 30
col 11: [ 5] 56 41 4c 49 44
col 12: [ 1] 4e
col 13: [ 1] 4e
col 14: [ 1] 4e
1.gif
2.gif
3.gif
4.gif
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。