Oracle資料塊格式

eric0435發表於2020-01-17

資料塊結構
Oracle 資料塊有三部分:
Cache layer
Transaction layer
Data layer

Oracle Data Block的結構簡圖如下,其中從Data header到Row Data部分合稱Data Layer:

---------------------
- Cache Layer -
---------------------
- Transaction Layer -
---------------------
- Data Header -
---------------------
- Table Directory -
---------------------
- Row Directory -
---------------------
- Free Space -
---------------------
- Row Data -
---------------------
- Tailchk -
---------------------
下面將使用bbed工具來顯示相關結構資訊

BBED> map
 File: /u01/app/oracle/oradata/shardcat/users01.dbf (7)
 Block: 135                                   Dba:0x01c00087
------------------------------------------------------------
 KTB Data Block (Table/Cluster)
 struct kcbh, 20 bytes                      @0
 struct ktbbh, 72 bytes                     @20
 struct kdbh, 14 bytes                      @100
 struct kdbt[1], 4 bytes                    @114
 sb2 kdbr[8]                                @118
 ub1 freespace[7983]                        @134
 ub1 rowdata[71]                            @8117
 ub4 tailchk                                @8188

資料塊元件
Oracle資料塊三層C結構,它被對映到SGA kcbh(核心快取資料塊頭)中的資料塊。Cache Layer包含關於塊格式,型別(資料,索引,頭等)資訊和序列資料。

BBED> p kcbh
struct kcbh, 20 bytes                       @0
   ub1 type_kcbh                            @0        0x06
   ub1 frmt_kcbh                            @1        0xa2
   ub2 wrp2_kcbh                            @2        0x0000
   ub4 rdba_kcbh                            @4        0x01c00087
   ub4 bas_kcbh                             @8        0x01286184
   ub2 wrp_kcbh                             @12       0x0000
   ub1 seq_kcbh                             @14       0x01
   ub1 flg_kcbh                             @15       0x06 (KCBHFDLC, KCBHFCKV)
   ub2 chkval_kcbh                          @16       0x0137
   ub2 spare3_kcbh                          @18       0x0000

Cache Layer:Block的第一部分,長度為20位元組,內部資料結構名為kcbh,包括
type_kcbh:塊型別(table/index,rollback segment,temporary segment等)
frmt_kcbh:塊格式(v6,v7,v8)
rdba_kcbh:塊地址DBA
bas_kcbh/wrp_kcbh:SCN
seq_kcbh:塊的序列號
flg_kcbh:塊的標誌

事務層儲存了關於資料塊的事務資訊
Transaction Layer:內部結構名ktbbh。分成兩部分,第一部分為固定長度,長度為24位元組,包含事務相關的一些基本資訊。第二部分為可變長度,包含itl,長度根據itl條目的個數變化,每個itl長度為24位元組,內部結構名ktbbhitl

BBED> p ktbbh
struct ktbbh, 72 bytes                      @20
   ub1 ktbbhtyp                             @20       0x01 (KDDBTDATA)
   union ktbbhsid, 4 bytes                  @24
      ub4 ktbbhsg1                          @24       0x0001af27
      ub4 ktbbhod1                          @24       0x0001af27
   struct ktbbhcsc, 8 bytes                 @28
      ub4 kscnbas                           @28       0x01286182
      ub2 kscnwrp                           @32       0x8000
      ub2 kscnwrp2                          @34       0x0000
   sb2 ktbbhict                             @36       7938
   ub1 ktbbhflg                             @38       0x32 (NONE)
   ub1 ktbbhfsl                             @39       0x00
   ub4 ktbbhfnx                             @40       0x01c00080
   struct ktbbhitl[0], 24 bytes             @44
      struct ktbitxid, 8 bytes              @44
         ub2 kxidusn                        @44       0x0006
         ub2 kxidslt                        @46       0x0012
         ub4 kxidsqn                        @48       0x000038f6
      struct ktbituba, 8 bytes              @52
         ub4 kubadba                        @52       0x010002d9
         ub2 kubaseq                        @56       0x10c9
         ub1 kubarec                        @58       0x09
      ub2 ktbitflg                          @60       0x8000 (KTBFCOM)
      union _ktbitun, 2 bytes               @62
         sb2 _ktbitfsc                      @62      -32768
         ub2 _ktbitwrp                      @62       0x8000
      ub4 ktbitbas                          @64       0x01228dbb
   struct ktbbhitl[1], 24 bytes             @68
      struct ktbitxid, 8 bytes              @68
         ub2 kxidusn                        @68       0x0008
         ub2 kxidslt                        @70       0x001b
         ub4 kxidsqn                        @72       0x00003a9a
      struct ktbituba, 8 bytes              @76
         ub4 kubadba                        @76       0x010002b5
         ub2 kubaseq                        @80       0x114f
         ub1 kubarec                        @82       0x20
      ub2 ktbitflg                          @84       0x2001 (KTBFUPB)
      union _ktbitun, 2 bytes               @86
         sb2 _ktbitfsc                      @86       10
         ub2 _ktbitwrp                      @86       0x000a
      ub4 ktbitbas                          @88       0x01286184

這種結構出現在資料庫每個資料塊的開頭部分。它甚至出現在不由redo改變的排序塊中。它也會出現在資料檔案頭塊和控制檔案頭塊的開頭部分。快取層提供了對壞資料的規模。它也用來確保正確的資料塊被讀取並且資料塊沒有破裂或損壞。所謂破裂的資料塊就是隻有一部分被寫入磁碟,資料塊的一部分保留了之前的版本。

Data Layer:包括Data Header,Table Directory,Row Directory,Free Space和Row Data。

Data Header:長度14位元組,內部資料結構名kdbh

BBED> p kdbh
struct kdbh, 14 bytes                       @100
   ub1 kdbhflag                             @100      0x00 (NONE)
   sb1 kdbhntab                             @101      1
   sb2 kdbhnrow                             @102      8
   sb2 kdbhfrre                             @104     -1
   sb2 kdbhfsbo                             @106      34
   sb2 kdbhfseo                             @108      8017
   sb2 kdbhavsp                             @110      7977
   sb2 kdbhtosp                             @112      7989

其中kdbhnrow是儲存在資料塊中的記錄數為8,而表中確實有8條記錄。(從ROWID可以判斷出來)

SQL> select dbms_rowid.rowid_block_number(rowid),t1.t_id,t1.t_name from jy.t1;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)       T_ID T_NAME
------------------------------------ ---------- ----------------------------------------
                                 134          9 YYL
                                 135          1 A
                                 135          2 B
                                 135          3 C
                                 135          4 D
                                 135          5 E
                                 135          6 F
                                 135          7 JYHY
                                 135          8 JYYYL
9 rows selected.

Table Directory: 一般table只有一個條目,cluster則有一個或多個條目。每個條目長4位元組,內部資料結構名kdbt

BBED> p kdbt
struct kdbt[0], 4 bytes                     @114
   sb2 kdbtoffs                             @114      0
   sb2 kdbtnrow                             @116      8

Row Directory:數目由塊中資料的行數決定,每個條目長2位元組,內部資料結構名kdbr

BBED> p kdbr
sb2 kdbr[0]                                 @118      8080
sb2 kdbr[1]                                 @120      8072
sb2 kdbr[2]                                 @122      8064
sb2 kdbr[3]                                 @124      8056
sb2 kdbr[4]                                 @126      8048
sb2 kdbr[5]                                 @128      8040
sb2 kdbr[6]                                 @130      8029
sb2 kdbr[7]                                 @132      8017

檢視錶中的記錄資料,一個重複計數也可以被指定用來重複執行examine命令來檢查後續的行記錄。下面的例子顯示了先使用print命令來設定最後一行記錄的偏移量,然後檢查後面的8行記錄的操作.

BBED> p *kdbr[7]
rowdata[0]
----------
ub1 rowdata[0]                              @8117     0x2c
BBED> x /8rnc
rowdata[0]                                  @8117
----------
flag@8117: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8118: 0x02
cols@8119:    2
col    0[2] @8120: 8
col    1[5] @8123: JYYYL
rowdata[12]                                 @8129
-----------
flag@8129: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8130: 0x00
cols@8131:    2
col    0[2] @8132: 7
col    1[4] @8135: JYHY
rowdata[23]                                 @8140
-----------
flag@8140: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8141: 0x00
cols@8142:    2
col    0[2] @8143: 6
col    1[1] @8146: F
rowdata[31]                                 @8148
-----------
flag@8148: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8149: 0x00
cols@8150:    2
col    0[2] @8151: 5
col    1[1] @8154: E
rowdata[39]                                 @8156
-----------
flag@8156: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8157: 0x00
cols@8158:    2
col    0[2] @8159: 4
col    1[1] @8162: D
rowdata[47]                                 @8164
-----------
flag@8164: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8165: 0x00
cols@8166:    2
col    0[2] @8167: 3
col    1[1] @8170: C
rowdata[55]                                 @8172
-----------
flag@8172: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8173: 0x00
cols@8174:    2
col    0[2] @8175: 2
col    1[1] @8178: B
rowdata[63]                                 @8180
-----------
flag@8180: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8181: 0x00
cols@8182:    2
col    0[2] @8183: 1
col    1[1] @8186: A

Free Space:表示資料塊中可用空間,內部資料結構名freespace

Row Data:表示實際的資料,內部資料結構名rowdata

BBED> p rowdata[0]
ub1 rowdata[0]                              @8117     0x2c
BBED> d /v offset 8117
 File: /u01/app/oracle/oradata/shardcat/users01.dbf (7)
 Block: 135     Offsets: 8117 to 8191  Dba:0x01c00087
-------------------------------------------------------
 2c020202 c109054a 5959594c 2c000202 l ,......JYYYL,...
 c108044a 5948592c 000202c1 0701462c l ...JYHY,......F,
 000202c1 0601452c 000202c1 0501442c l ......E,......D,
 000202c1 0401432c 000202c1 0301422c l ......C,......B,
 000202c1 02014101 068461            l ......A...a
 <16 bytes per line>

Tailchk:儲存在塊結尾用於校驗的資料,長度4個位元組,內部結構名tailchk。所有Oracle塊的最後四個位元組都是tail check(結尾檢查)。
對於一個Oracle 8以上版本的資料塊的tail它是由SCN base的低位兩位元組的內容,資料塊的型別與SCN序列號組成的。例如,如果SCN base為 0x01286184,資料塊型別為0x06,SCN序列號為0x01,那麼tail check將是0x61840601

BBED> p tailchk
ub4 tailchk                                 @8188     0x61840601
BBED> p kcbh
struct kcbh, 20 bytes                       @0
   ub1 type_kcbh                            @0        0x06
   ub1 frmt_kcbh                            @1        0xa2
   ub2 wrp2_kcbh                            @2        0x0000
   ub4 rdba_kcbh                            @4        0x01c00087
   ub4 bas_kcbh                             @8        0x01286184
   ub2 wrp_kcbh                             @12       0x0000
   ub1 seq_kcbh                             @14       0x01
   ub1 flg_kcbh                             @15       0x06 (KCBHFDLC, KCBHFCKV)
   ub2 chkval_kcbh                          @16       0x0137
   ub2 spare3_kcbh                          @18       0x0000

雖然tail check的值通常是由這三個元件級成,Oracle會對最終的值作為一個值(4位元組)以單無符號整數來儲存。在小位元組序編碼(little-endian)的構架機器中,比如Intel,這個值將以低位位元組優先的方式來儲存。因此如果使用標準塊編輯器或dump命令來檢查資料塊的tail check時,位元組順序可能不一樣。一個tail check為0x61840601,在Intel機器上它將以"01068461"的形式儲存在磁碟。

BBED> dump /v offset 8188
 File: /u01/app/oracle/oradata/shardcat/users01.dbf (7)
 Block: 135     Offsets: 8188 to 8191  Dba:0x01c00087
-------------------------------------------------------
 01068461                            l ...a
 <16 bytes per line>


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

相關文章