一. DUMP DatafileBlock 樣本
Oracle的一個資料區塊裡的SCN有三種,分別是塊頭的SCN, CSC (cleanout SCN)和ITL中記錄的commit SCN。 如果我們想查看某個或者某些block 裡的內容,可以把這些block dump出來查看。
關於這個dump 方法,在之前的blog裡有說明:
Oracle rdba和 dba 說明
OraceITL(Interested Transaction List) 說明
根據Rowid 查詢對應的block number 和datafile number:
SQL> SELECT
2dbms_rowid.rowid_relative_fno(rowid) REL_FNO,
3dbms_rowid.rowid_block_number(rowid) BLOCKNO,
4dbms_rowid.rowid_row_number(rowid) ROWNO,
5 empno, ename
6 FROM emp WHERE empno = 7369;
REL_FNO BLOCKNO ROWNO EMPNOENAME
---------- -------------------- ---------- ----------
4 20 0 7369 SMITH
然後根據block id執行dump 命令:
SQL> alter system dump datafile 4 block 20;
如果要dump 多個block,命令如下:
SQL>ALTER SYSTEM dump datafile <file_id> block min<block_id> block max <block_id+blocks-1>;
SYS@anqing2(rac2)> oradebug setmypid
Statement processed.
SYS@anqing2(rac2)> alter system dump datafile 1 block 292689;
System altered.
SYS@anqing2(rac2)> oradebug tracefile_name
/u01/app/oracle/admin/anqing/udump/anqing2_ora_32276.trc
[oracle@rac2 ~]$ cat /u01/app/oracle/admin/anqing/udump/anqing2_ora_32276.trc
*** 2011-08-01 17:51:31.366
Start dump data blocks tsn: 0file#: 1 minblk 292689 maxblk 292689
buffer tsn: 0 rdba: 0x00447751(1/292689)
-- buffertsn: 資料檔案對應的tablespace 的 number ,這隻是dump檔案中記錄的資料而已,block 中是沒有記錄tablespace 的 number 的
scn: 0x0000.005bdee1 seq: 0x01flg: 0x06 tail: 0xdee10601
frmt: 0x02 chkval: 0xaf6f type:0x06=trans data
Hex dump of block: st=0,typ_found=1
Dump of memory from 0x0DC34400to 0x0DC36400
DC34400 0000A206 00447751005BDEE1 06010000 [....QwD...[.....]
......
DC363F0 C3040203 04261C0B65766164 DEE10601 [......&.dave....]
Block header dump: 0x00447751
Object id on Block? Y
seg/obj: 0xd5ec csc: 0x00.5bcbe0 itc: 3 flg: - typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000e.007.00000236 0x00000000.0000.00 C-U- 0 scn 0x0000.005b1f7f
0x02 0x000c.005.000003b4 0x01401727.0144.13 C--- 0 scn 0x0000.005bbf0b
0x03 0x0011.007.00000406 0x0140015b.00c7.57 --U- 483 fsc 0x0000.005bdee1
data_block_dump,data header at0xdc34474
-- 其實這個block不是直接從data buffer 中 dump 出來的,這個表示真正dump時 block 的資料區的起始位置,也就是下面這部分開始的位置
===============
tsiz: 0x1f88
-- tsiz: hsiz: pbl: bdba: 在資料檔案都是沒有儲存的
--Total data area size
--8k的block: 8192-20(blockhead)-24(Transaction Header)-24*3(一個事務條)-4(block tail)=8072(0x1f88)
--將十六進位轉換為10進位
SYS@anqing2(rac2)> selectto_number('1f88','xxxx') from dual;
TO_NUMBER('1F88','XXXX')
------------------------
8072
hsiz: 0x3d8
--Data headersize
pbl: 0x0dc34474
-- Pointer tobuffer holding the block
bdba: 0x00447751
76543210
flag=--------
ntab=1
nrow=483
frre=-1
fsbo=0x3d8
fseo=0x706
avsp=0x32e
tosp=0x32e
0xe:pti[0] nrow=483 offs=0
0x12:pri[0] offs=0x1f7b
0x14:pri[1] offs=0x1f6e
......
0x3d4:pri[481] offs=0x713
0x3d6:pri[482] offs=0x706
block_row_dump:
tab 0, row 0, @0x1f7b
tl: 13 fb: --H-FL-- lb:0x3 cc: 2
col 0: [ 4] c3 0b 1c 26
col 1: [ 4] 64 61 76 65
tab 0, row 1, @0x1f6e
tl: 13 fb: --H-FL-- lb:0x3 cc: 2
col 0: [ 4] c3 0b 1c 27
col 1: [ 4] 64 61 76 65
tab 0, row 2, @0x1f61
tl: 13 fb: --H-FL-- lb:0x3 cc: 2
col 0: [ 4] c3 0b 1c 28
col 1: [ 4] 64 61 76 65
......
tab 0, row 481, @0x713
tl: 13 fb: --H-FL-- lb:0x3 cc: 2
col 0: [ 4] c3 0b 21 13
col 1: [ 4] 64 61 76 65
tab 0, row 482, @0x706
tl: 13 fb: --H-FL-- lb:0x3 cc: 2
col 0: [ 4] c3 0b 21 14
col 1: [ 4] 64 61 76 65
--這裡的row482 之類的都是每一條記錄裡的具體值。我dump 這個block 儲存的記錄比較簡單,只有2列值。 可以將這個值轉換成具體的字串。 方法如下:
SYS@anqing2(rac2)> setserveroutput on
SYS@anqing2(rac2)> declare nnumber;
2 begin
3 dbms_stats.convert_raw_value('c30b2114',n);
4 dbms_output.put_line(n);
5 end;
6 /
103219
PL/SQL procedure successfullycompleted.
SYS@anqing2(rac2)> declarestr varchar2(100);
2 begin
3 dbms_stats.convert_raw_value('64617665',str);
4 dbms_output.put_line(str);
5 end;
6 /
dave --這個就是 col 1: [ 4] 64 61 76 65 對應的值
PL/SQL procedure successfullycompleted.
end_of_block_dump
End dump data blocks tsn: 0file#: 1 minblk 292689 maxblk 292689
[oracle@rac2 ~]$