简单分析dump出来的oracle数据块

手动迁移原创博客,原文发表在http://blog.itpub.net/20777547/viewspace-1352096/


一.dump数据块

oracle的rowid中包含着这条数据对象号,数据文件号,数据文件中的块号以及块中的行号,并且这些都可以通过dbms_rowid这个包转成具体的数字出来

 SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid) as file#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) as block#,dbms_rowid.ROWID_ROW_NUMBER(rowid) as row#,a.* from paololiu.test1 a; 

 

     FILE#     BLOCK#     ROW# AAA   BBB

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

 6   131        0 abc   abc

 6   131        1 111   111

 6   131        2 ab12  ab12 

可以看tset1表中的三条记录都在第6号文件的131号块上,并分别在这个块的第0,1,2行上。

通过dump命令就可以把这整个块都dump出来的:

 SQL> alter system dump datafile 6 block 131;

 

System altered. 

dump 出来的文件在 user_dump_dest 参数设定的目录内,以 _ora_.trc 为格式的名字。其中 spid 指当前 sid 所对应的操作系统的进程号,可以通过以下语句获得:

 SQL> select p.spid from v$session s,v$process p where s.paddr=p.addr and s.sid in (select userenv('sid') from dual);

 

SPID

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

2413 

通过 vi 就可以打开刚才 dump 出来的 trc 文件了,在最下面就可以看到那三条记录了

 block_row_dump:

tab 0, row 0, @0x1f8b

tl: 13 fb: --H-FL-- lb: 0x1  cc: 2

col  0: [ 5]  61 62 63 20 20

col  1: [ 3]  61 62 63

tab 0, row 1, @0x1f7e

tl: 13 fb: --H-FL-- lb: 0x1  cc: 2

col  0: [ 5]  31 31 31 20 20

col  1: [ 3]  31 31 31

tab 0, row 2, @0x1f70

tl: 14 fb: --H-FL-- lb: 0x1  cc: 2

col  0: [ 5]  61 62 31 32 20

col  1: [ 4]  61 62 31 32

end_of_block_dump 

另外同样也可以通过 dump 函数来获得这些二进制文件的值(前面 trc 文件显示的是 16 进制的,这里显示的是 10 进制的):

 SQL> select a.*,dump(aaa) as dump1,dump(bbb) as dump2 from test1 a;

 

AAA   BBB  DUMP1   DUMP2

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

abc   abc  Typ=96 Len=5: 97,98,99,32,32   Typ=1 Len=3: 97,98,99

111   111  Typ=96 Len=5: 49,49,49,32,32   Typ=1 Len=3: 49,49,49

ab12  ab12  Typ=96 Len=5: 97,98,49,50,32   Typ=1 Len=4: 97,98,49,50 

二.分析dump出来的数值

 

刚才那张表的数据结构如下:

 SQL> desc test1;

 Name    Null?    Type

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

 AAA     CHAR(5)

 BBB     VARCHAR2(50) 

这里可以看到typ=96代表char类型,而typ=1代表varchar2类型。后面的数值则对应的是ascii表的值,其中97是a,98是b,99是c,49是1,50是2。还有可以看到char类型后面还有一些32则对应的是空格,填充剩余字符串长度。

 

这里显示的是字符串,而数值型就相对比较复杂了

1.数值:123456

 SQL> select dump(123456) as dump1 from dual;

 

DUMP1

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

Typ=2 Len=4: 195,13,35,57 

195-193=2

193是个常数值,第一位的数字195去减193得到一个指数值2

13-1=12,12*100^2=120000

35-1=34,34*100^1=3400

57-1=56,56*100^0=56

这里-1前面的就是dump出来的后面几位的值,依次分别是13,35,57,用他们减掉一个常数值1以后再依次乘以100的递减指数倍

 

sum=120000+3400+56=123456

再将它们相加就可以得到原来的值了


2.数值:123456.789

 SQL> select dump(123456.789) as dump1 from dual;

 

DUMP1

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

Typ=2 Len=6: 195,13,35,57,79,91 

其实小数的算法和前面的整数一样的:

a.用第一位195减掉193得到指数值

195-194=2

 

b.后面几位分别乘以相对应的100的递减的指数倍

13-1=12;12*100^2=120000

35-1=34;34*100^1=3400

57-1=56;56*100^0=56

79-1=78;78*100^-1=0.78

91-1=90;90*100^-2=0.09

 

c.最后相加

120000+3400+56+0.78+0.9=123456.789


3.数值:-98765.4321

 SQL> select dump(-98765.4321) as dump1 from dual;

 

DUMP1

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

Typ=2 Len=7: 60,92,14,36,58,80,102 

负数的算法和前面的正数差不多,只是几个常数需要换一下

a.指数算法稍有区别:用常数62减去第一位等到指数值

62-60=2

 

b.后面的是减去常数101后再乘以100的递减指数倍

92-101=-9;-9*100^2=-90000

14-101=-87;-87*100^1=-8700

36-101=-65;-65*100^0=-65

58-101=-43;-43*100^-1=-0.43

80-101=-21;-21*100^-2=-0.0021

最后一位102放弃

 

c.相加后得到相应的数值:

-90000-8700-65-0.43-0.0021=-98765.4321


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值