dump資料塊

llnnmc發表於2017-10-30

一、dump資料檔案

 

dump資料檔案需要知道表的儲存資訊:資料檔案號(file#)和資料塊號(block#)。

以下查詢表所在的表空間、檔案號、區段分佈、塊分佈資訊

col segment_name for a20

col tablespace_name for a20

select segment_name, segment_type, tablespace_name, extent_id, file_id, block_id, blocks, bytes from dba_extents where owner = 'SCOTT' and segment_name = 'EMP';

 

SEGMENT_NAME         SEGMENT_TYPE       TABLESPACE_NAME       EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS      BYTES

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

EMP                  TABLE              USERS                         0          4        144          8      65536

 

再看錶記錄的塊分佈資訊

select dbms_rowid.rowid_block_number(rowid) block#, count(*) block_records from scott.emp group by dbms_rowid.rowid_block_number(rowid) order by block#;

 

    BLOCK# BLOCK_RECORDS

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

       151            14

 

可見表段開始的前幾個塊是用於儲存段頭資訊的,行記錄資料從後面塊開始。

 

使用以下命令可以dump一個或多個資料塊:

alter system dump datafile <file#> block <block#>;

alter system dump datafile <file#> block min <block#_min> block max <block#_max>;

 

先看一下當前會話對應的跟蹤檔案

col trace_file_name for a80

select a.value || b.symbol || c.instance_name || '_ora_' || d.spid ||

       '.trc' trace_file_name

  from (select value from v$parameter where name = 'user_dump_dest') a,

       (select substr(value, -6, 1) symbol

          from v$parameter

         where name = 'user_dump_dest') b,

       (select instance_name from v$instance) c,

       (select spid

          from v$session s, v$process p, v$mystat m

         where s.paddr = p.addr

           and s.sid = m.sid

           and m.statistic# = 0) d;

 

TRACE_FILE_NAME

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

c:\oracle\diag\rdbms\mes\mes\trace\mes_ora_3912.trc

 

現在dump檔案塊

alter system dump datafile 4 block 151;

 

檢視跟蹤檔案內容

Start dump data blocks tsn: 4 file#:4 minblk 151 maxblk 151

Block dump from cache:

Dump of buffer cache at level 4 for tsn=4, rdba=16777367

Block dump from disk:

buffer tsn: 4 rdba: 0x01000097 (4/151)

scn: 0x0000.001ef9e3 seq: 0x01 flg: 0x06 tail: 0xf9e30601

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

Hex dump of block: st=0, typ_found=1

Dump of memory from 0x000000000D186E00 to 0x000000000D188E00

00D186E00 0000A206 01000097 001EF9E3 06010000  [................]

...

00D188DF0 0101110C 09C20201 15C102FF F9E30601  [................]

Block header dump:  0x01000097

 Object id on Block? Y

 seg/obj: 0x11dec  csc: 0x00.1ef9cc  itc: 2  flg: E  typ: 1 - DATA

     brn: 0  bdba: 0x1000090 ver: 0x01 opc: 0

     inc: 0  exflg: 0

 

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x000a.009.0000044c  0x00c00f07.012e.20  --U-    1  fsc 0x0000.001ef9e3

0x02   0x000a.004.0000044d  0x00c00f07.012e.1c  C---    0  scn 0x0000.001ef98a

 

資料塊主要資訊如下:

tsn:表空間編號

file#:檔案編號

minblk和maxblk:匯出塊編號的範圍

rdba:相對塊地址資訊

 

這裡rdba列出了十六進位制形式和十進位制形式,這個地址可以使用如下查詢透過檔案號和塊號進行轉換

select dbms_utility.make_data_block_address(4, 151) from dual;

 

DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS(4,151)

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

                                   16777367

 

它的十六進位制形式

select to_char(16777367, 'xxxxxxxx') from dual;

 

TO_CHAR(1

---------

  1000097

 

反過來,也可以透過塊地址轉換得到檔案號和塊號

select dbms_utility.data_block_address_file(16777367) file#, dbms_utility.data_block_address_block(16777367) block# from dual;

 

     FILE#     BLOCK#

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

         4        151

 

scn:資料塊的SCN資訊

tail:由SCN的最後兩位元組、塊型別type和序列號seq組成

 

Oracle利用資料塊的tail來判斷資料塊內容的一致性,如果這裡的tail分解後和SCN的最後兩位元組、塊型別和序列號三者不匹配,Oracle可以判斷這個塊處於不一致狀態,需要恢復。這裡的tail資訊雖然顯示在塊跟蹤檔案的開始部分,而事實上它物理的儲存在資料塊的最末端,這也是tail名稱的由來。

 

塊型別type的有效取值有以下幾種:

0x02undo block

0x06trans data

0x0eundo segment header

0x10data segment header block

0x17bitmapped data segment header

0x20first level bitmap block

0x21second level bitmap block

0x23pagetable segment header

 

Object id on Block? Y:資料塊上儲存的資料庫物件是否存在於sys.obj$資料字典

seg/obj:資料庫物件的ID資訊,以下查詢可以驗證

col object_name for a30

select owner, object_name from dba_objects where object_id = to_number('11dec', 'xxxxx');

 

OWNER                          OBJECT_NAME

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

SCOTT                          EMP

 

csc:塊清理時的SCNcleanout SCN),注意觀察它是否匹配資料塊的SCN

itc:事務槽(ITL slot)的數量,下面的兩行正是ITL的資訊,對應兩個事務,用xid標識。

flag:標識資料塊是否存在於段的freelist,“-”表示該塊不在freelist中,“o”代表on,表示該塊存在於freelist,可用於insert記錄。

 

以下是資料頭部分

data_block_dump,data header at 0xd186e64

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

tsiz: 0x1f98

hsiz: 0x2e

pbl: 0x0d186e64

     76543210

flag=--------

ntab=1

nrow=14

frre=-1

fsbo=0x2e

fseo=0x1d61

avsp=0x1d33

tosp=0x1d33

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

0x12:pri[0]        offs=0x1f72

0x14:pri[1]        offs=0x1f47

0x16:pri[2]        offs=0x1f1c

0x18:pri[3]        offs=0x1ef3

0x1a:pri[4]        offs=0x1ec6

0x1c:pri[5]        offs=0x1e9d

0x1e:pri[6]        offs=0x1e74

0x20:pri[7]        offs=0x1e4c

0x22:pri[8]        offs=0x1e26

0x24:pri[9]        offs=0x1dfb

0x26:pri[10]        offs=0x1dd5

0x28:pri[11]        offs=0x1daf

0x2a:pri[12]        offs=0x1d88

0x2c:pri[13]        offs=0x1d61

 

這裡含義如下:

tsiz:資料塊用於儲存資料部分的總空間(total data area size

hsiz:頭尺寸(header size

pbl:資料塊在快取中的地址指標(pointer to buffer holding the block),下面一行則是其塊地址bdba

ntabnumber of tables,如果該值大於1,說明該資料塊屬於cluster的儲存塊。

nrownumber of rows,資料塊中儲存的記錄數量。

fsbofseofree space begin offsetfree space end offset,兩者給出了塊中自由空間的起始位置。

avspavailable space in the block

tosptotal available space when all transactions commit

 

再往後就是行記錄資訊,以下是第一條記錄

block_row_dump:

tab 0, row 0, @0x1f72

tl: 38 fb: --H-FL-- lb: 0x1  cc: 8

col  0: [ 3]  c2 4a 46

col  1: [ 5]  53 4d 49 54 48

col  2: [ 5]  43 4c 45 52 4b

col  3: [ 3]  c2 50 03

col  4: [ 7]  77 b4 0c 11 01 01 01

col  5: [ 2]  c2 09

col  6: *NULL*

col  7: [ 2]  c1 15

 

這裡含義如下:

tab 0, row 0, @0x1f72:表在cluster中的標識、行標識和行地址。

tl:指示該行共佔用的位元組空間,十進位制表示,包含行的其他開銷。

fb:行標記,H表示head of rowFL分別表示行的first piecelast piece,說明此行涉及匯出的資料塊,不存在行連結,又由於塊中存在行頭,說明也存在行遷移。

lbITL事務槽編號

cc:列的數量

col  n: [ k]:第n+1列的資料,佔用k個位元組。

 

以下驗證第二列資料col  1: [ 5]  53 4d 49 54 48,資料以十六進位制ASCII碼形式給出,透過以下查詢轉換為字元

select chr(to_number('53', 'xx')) || chr(to_number('4d', 'xx')) || chr(to_number('49', 'xx')) || chr(to_number('54', 'xx')) || chr(to_number('48', 'xx')) from dual;

 

CHR(TO_NUM

----------

SMITH

 

或者使用以下程式包轉換

set serveroutput on

declare c varchar2(30);

begin

    dbms_stats.convert_raw_value('534d495448', c);

    dbms_output.put_line(c);

end;

/

SMITH

 

對於第一列資料col  0: [ 3]  c2 4a 46,該列是number型別,可以透過以上程式包轉換為十進位制數

set serveroutput on

declare n number;

begin

    dbms_stats.convert_raw_value('c24a46', n);

    dbms_output.put_line(n);

end;

/

7369

 

scott.emp表上可以查詢驗證,編號為7369的員工正是smith

 

對於第五列資料col  4: [ 7]  77 b4 0c 11 01 01 01,該列是date型別,同樣可以透過以上程式包轉換為可顯示的日期

set serveroutput on

declare dt date;

begin

    dbms_stats.convert_raw_value('77b40c11010101', dt);

    dbms_output.put_line(to_char(dt, 'yyyy-mm-dd hh24:mi:ss'));

end;

/

1980-12-17 00:00:00

 

二、dump索引檔案

 

索引資料塊和表資料塊的儲存明顯不同。一個b-tree索引所對應的儲存資料塊有分支節點塊(branch block)和葉節點塊(leaf block)。要匯出一個b-tree索引,需要提供這個索引的object_id,為此先查詢索引物件及其ID資訊

col table_name for a30

col tablespace_name for a20

col index_name for a20

col index_type for a10

select table_name, index_name, index_type, status, tablespace_name from dba_indexes where owner='CMES' and table_name='C_MATERIAL_T';

 

TABLE_NAME                     INDEX_NAME           INDEX_TYPE STATUS   TABLESPACE_NAME

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

C_MATERIAL_T                   IDX_FK_MATERIAL_NO   NORMAL     VALID    CMES

C_MATERIAL_T                   IDX_FK_PART_NO       NORMAL     VALID    CMES

C_MATERIAL_T                   IDX_PK_MATERIAL_ID   NORMAL     VALID    CMES

 

select object_id from dba_objects where object_name = 'IDX_FK_PART_NO';

 

 OBJECT_ID

----------

     77043

 

啟用treedump事件跟蹤來匯出,將索引物件的object_id代入以下命令

alter session set events 'immediate trace name treedump level 77043';

 

檢視匯出檔案

----- begin tree dump

branch: 0x14003b3 20972467 (0: nrow: 2, level: 1)

   leaf: 0x14003b4 20972468 (-1: nrow: 322 rrow: 322)

   leaf: 0x14003b5 20972469 (0: nrow: 23 rrow: 23)

----- end tree dump

 

這個索引樹只有一個分支節點(branch)也就是索引的根節點(root),塊地址為0x14003b3,其十進位制數為20972467,根節點的level1,說明該b-tree索引的高度為2,因為索引樹的level是從0開始計的。該根節點下面沒有再分支了,就是葉節點塊,葉節點的level總是0,因此dump檔案中不需要標出。分支和葉所在的位置標識從最左邊為-1開始而不是0。對於葉節點塊,nrow表示該節點塊中儲存的行指標數,對於分支節點塊,nrow表示指向下一層節點的塊數。在葉節點塊中,還有rrow,它與塊上的事務處理有關(rrow is the number of rows after all current transactions have been committed),rrownrow相等,表示該塊涉及的資料上沒有正在執行的事務處理。

 

分析左邊第一個葉塊leaf: 0x14003b4 20972468 (-1: nrow: 322 rrow: 322),由資料塊地址dba轉換為對應的檔案號、塊號

select dbms_utility.data_block_address_file(to_number('14003b4','xxxxxxxx')) file#, dbms_utility.data_block_address_block(to_number('14003b4','xxxxxxxx')) block# from dual;

 

     FILE#     BLOCK#

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

         5        948

 

dump該資料塊

alter system dump datafile 5 block 948;

 

檢視dump檔案,找到葉塊的描述部分

Leaf block dump

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

header address 532770404=0x1fc16e64

kdxcolev 0

KDXCOLEV Flags = - - -

kdxcolok 0

kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y

kdxconco 2

kdxcosdc 0

kdxconro 322

kdxcofbo 680=0x2a8

kdxcofeo 1502=0x5de

kdxcoavs 822

kdxlespl 0

kdxlende 0

kdxlenxt 20972469=0x14003b5

kdxleprv 0=0x0

kdxledsz 0

kdxlebksz 8036

row#0[8017] flag: ------, lock: 0, len=19

col 0; len 9; (9):  31 36 44 34 30 37 31 38 33

col 1; len 6; (6):  01 40 03 a5 00 0a

row#1[7997] flag: ------, lock: 0, len=20

col 0; len 10; (10):  31 38 30 35 30 30 30 34 31 45

col 1; len 6; (6):  01 40 03 9b 00 0c

 

kdxlenxt:下一個葉節點的塊地址

kdxleprv:前一個葉節點的塊地址

這兩個指標對於SQL最佳化器執行索引的index range scans操作非常重要。隨後就是葉塊的資料內容,這裡只顯示了兩行記錄。

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

相關文章