如何理解dump数据块

今天就跟大家聊聊有关如何理解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数据块有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。

原创文章,作者:3628473679,如若转载,请注明出处:https://blog.ytso.com/203741.html

(0)
上一篇 2021年11月28日
下一篇 2021年11月28日

相关推荐

发表回复

登录后才能评论