您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關如何理解dump數據塊,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
一、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的有效取值有以下幾種:
0x02:undo block
0x06:trans data
0x0e:undo segment header
0x10:data segment header block
0x17:bitmapped data segment header
0x20:first level bitmap block
0x21:second level bitmap block
0x23:pagetable 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:塊清理時的SCN(cleanout 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。
ntab:number of tables,如果該值大于1,說明該數據塊屬于cluster的存儲塊。
nrow:number of rows,數據塊中存儲的記錄數量。
fsbo、fseo:free space begin offset和free space end offset,兩者給出了塊中自由空間的起始位置。
avsp:available space in the block
tosp:total 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 row,F和L分別表示行的first piece和last piece,說明此行涉及導出的數據塊,不存在行鏈接,又由于塊中存在行頭,說明也存在行遷移。
lb:ITL事務槽編號
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 hh34: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,根節點的level為1,說明該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),rrow和nrow相等,表示該塊涉及的數據上沒有正在執行的事務處理。
分析左邊第一個葉塊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操作非常重要。隨后就是葉塊的數據內容,這里只顯示了兩行記錄。
看完上述內容,你們對如何理解dump數據塊有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。