温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何理解dump数据块

发布时间:2021-11-12 14:03:33 来源:亿速云 阅读:115 作者:柒染 栏目:关系型数据库

今天就跟大家聊聊有关如何理解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的有效取值有以下几种:

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 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,根节点的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操作非常重要。随后就是叶块的数据内容,这里只显示了两行记录。

看完上述内容,你们对如何理解dump数据块有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI