如何分解rdba地址

puber晶晶的一篇文章http://space.itpub.net/13095417/viewspace-171150
介绍了ASSM寻找free block的过程其中在转储L3块的时候,在文件中有这样一项
L2 Hint for inserts: 0x010002e2
这是寻找L2块的线索,但是这是一个rdba地址,我们如何从这个块地址中知道file_id和block_id呢?进而进一步转储研究呢?

还得先复习一下rowid的知识:
------------------------------------------
我们都知道rowid表示一行的物理地址,一行唯一确定一个rowid,并且在使用中一般不会改变,除非rowid之后在行的物理位置发生改变的情况下才会发生变化。需要注意的是rowid并不会真正存在于表的data block中,但是他会存在于index当中,用来通过rowid来寻找表中的行数据。
oracle8以前一个rowid占用6个字节大小的存储空间(10bit file#+22bit block#+16bit row#),那么oracle 8以后这个rowid的存储空间扩大到了10个字节(32bit object#+10bit rfile#+22bit block#+16bit row#),所以数据库中数据库文件个数的限制从整个数据库最多只能有的2^10-1个数据文件,变为了每个表空间中可以最多有2^10-1个数据文件。(需要注意的是:local index中存储的rowid是6个字节,而global index中存储的rowid是10个字节)
那么增加的32bit object#这个前缀主要就是用来定位表空间的,同时这个object#其实对应的就是data_object_id,由于一个段对象只能属于一个表空间,同时data_object_id就是标识了一个段的物理存储id.因此object#+rfile#就可以唯一定位当前的rowid是在那个数据文件上了。
我们可以通过dbms_rowid这个包来转换我们的rowid成不同组成部分

dbms_rowid.rowid_object(rowid)---> 32bit object#
dbms_rowid.rowid_relative_fno(rowid)---> 10bit rfile#
dbms_rowid.rowid_block_number(rowid)---> 22bit block#
dbms_rowid.rowid_row_number(rowid)---> 16bit row#

那么理解了rowid的组成,我们就很容易的理解rdba的计算了
其实rdba就是rowid中的rfile#+block#

对于0x010002e2这个地址,由于他是一个16进制的数字串,转换为10进制就是16777954

这个时候我们就可以通过dbms_utility这个包来进而分解我们的rdba地址
SQL>select dbms_utility.data_block_address_file(16777954) "file",dbms_utility.data_block_address_block(16777954) "block"
2 from dual;

file block
---------- ----------
4 738

这样我们在根据这条记录的内容来转储L2块信息:

alter system dump datafile 4 block 738

基本上就是这样。


附:
rdba: 0x004062ba (1/25274)
我们通过这个例子介绍一下.
rdba从Oracle6->Oracle7->Oracle8发生了三次改变:
在Oracle6中,rdba由6位2进制数表示,也就是说数据块最多只能有2^6=64个数据文件(去掉全0和全1, 实际上最多只能代表62个文件),在Oracle7中,rdba中的文件号增加为10位,为了向后兼容,从Block号的高位拿出4位作为文件号的高位.这样从6->7的Rowid无需发生变化.
而数据文件的个数理论上则扩展到了1022个(去掉全0和全1),在Oracle7中,rowid格式为:BBBBBBBB.RRRR.FFFF 在Oracle8中,文件号仍然用10位表示,只是不再需要置换,为了向后兼容,同时引入了相对文件号(rfile#),所以从Oracle7到Oracle8,Rowid仍然无需发生变化.
在Oracle8i中,Oracle引入了dataobj#,rowid的格式为:OOOOOOFFFBBBBBBSSS,Oracle通过dataobj#进一步向上定为表空间等,从而使每个表空间的数据文件数量理论上可以达到1022个

举例说明如下:
在Oracle6中:
比如: file 8, block 56892
26位block号==56892
vv vvvvvvvv vvvvvvvv vvvvvvvv
00100000 00000000 11011110 00111100
^^^^^^
6位文件号==8
在Oracle7中:
比如:File 255, block 56892
11111100 11000000 11011110 00111100
F C C 0 D E 3 C
\_____/\___/\_______________________/
| | |
| | Block = 0xDE3C = 56892
\_____________
| \
V V
0011 111111 = 0xFF = 255 --注意这里高位和低位要置换才能得出正确的file#
在Oracle8中:
比如:File 255, block 56892
11111100 11000000 11011110 00111100
F C C 0 D E 3 C
\_____/\___/\_______________________/
| | |
| | Block = 0xDE3C = 56892
\_____________
| \
V V
0011 1111 0011 = 03F3 = 1011 --这就是相对文件号
对于我们测试中的例子:
rdba: 0x004062ba (1/25274)
也就是:0000 0000 0100 0000 0110 0010 1011 1010
前10位为rfile#: 0000 0000 01 = 1
后22位为Block#:00 0000 0110 0010 1011 1010 = 25274
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值