Oracle的rowid和rdba庖丁解牛(一)

2014-11-24 17:52:30 · 作者: · 浏览: 3

注意:这里的O,代表的是data_object_id,是与段物理存储位置相关的一个信息,因为一个段对象只可能在一个表空间上,data_object_id能唯一确认ts#,而data_object_id + rfile#就能最终定位到该rowid在那个确定的物理数据文件。


如果我们查询一个表的ROWID,就可以获得object的信息,文件信息,块信息与行信息等等,如根据其中块的信息,可以知道该表确切占用了多少个块,每行在哪个块上,哪个数据文件上。


我们在select数据时候,在不指定排序字段时, oracle是按rowid升序取数据的。如


SQL> select t.id,rowid from skate.tab2 t;


ID ROWID


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


1067511 AAAO1lAAEAAAHKkAAA


1067513 AAAO1lAAEAAAHKkAAB


1067515 AAAO1lAAEAAAHKkAAC


1067517 AAAO1lAAEAAAHKkAAD


1067519 AAAO1lAAEAAAHKkAAE


1067523 AAAO1lAAEAAAHKkAAG


1067525 AAAO1lAAEAAAHKkAAH


1067527 AAAO1lAAEAAAHKkAAI


8 rows selected


SQL>


可以从上面的显示数据看到,是按rowid降序排列。我们拿rowid “AAAO1lAAEAAAHKkAAA”来说明


Data Object number =AAAO1l


File id =AAE


Block id =AAAHKk


Row =AAA


Rowid是64进制的,可以通过进制转化工具来查看(http://www.2u3.cn/Conversion/jinzhi/



A-Z <==> 0 - 25 (26)
a-z <==> 26 - 51 (26)
0-9 <==> 52 - 61 (10)
+/ <==> 62 - 63 (2)



拿其中的Data Object number= AAAO1l为例子,



l是64进制中的37,位置为0


37 * (64 ^ 0) = 37


1是64进制中的53,位置为1


53 * (64 ^ 1) = 3392


O是64进制中的 14,位置为2


14*(64^2)=57344


A是64进制中的 0


所以


A * (64 ^ 3) = 0


A * (64 ^ 4) = 0


A * (64 ^ 5) = 0


则有AAAO1l= 0 + 0 + 0 + 57344+ 3392 + 37 = 60773,表示该行存在的对象,对应的对象号为60773。



手工算还是比较麻烦的,oracle为此提供相应的函数dbms_rowid来实现


SQL> select dbms_rowid.rowid_object('AAAO1lAAEAAAHKkAAA') data_object_id#,


2 dbms_rowid.rowid_relative_fno('AAAO1lAAEAAAHKkAAA') rfile#,


3 dbms_rowid.rowid_block_number('AAAO1lAAEAAAHKkAAA') block#,


4 dbms_rowid.rowid_row_number('AAAO1lAAEAAAHKkAAA') row# from dual;


DATA_OBJECT_ID# RFILE# BLOCK# ROW#


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


60773 4 29348 0



可以通过包的说明或者oracle官方手册了解更多,例如:


SQL> desc dbms_rowid


Element Type


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


ROWID_TYPE_RESTRICTED CONSTANT


ROWID_TYPE_EXTENDED CONSTANT


ROWID_IS_VALID CONSTANT


ROWID_IS_INVALID CONSTANT


ROWID_OBJECT_UNDEFINED CONSTANT


ROWID_CONVERT_INTERNAL CONSTANT


ROWID_CONVERT_EXTERNAL CONSTANT


ROWID_INVALID EXCEPTION


ROWID_BAD_BLOCK EXCEPTION


ROWID_CREATE FUNCTION


ROWID_INFO PROCEDURE


ROWID_TYPE FUNCTION


ROWID_OBJECT FUNCTION


ROWID_RELATIVE_FNO FUNCTION


ROWID_BLOCK_NUMBER FUNCTION


ROWID_ROW_NUMBER FUNCTION


ROWID_TO_ABSOLUTE_FNO FUNCTION


ROWID_TO_EXTENDED FUNCTION


ROWID_TO_RESTRICTED FUNCTION


ROWID_VERIFY FUNCTION



SQL> desc dbms_rowid.rowid_info


Parameter Type Mode Default


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


ROWID_IN ROWID IN


ROWID_TYPE NUMBER OUT


OBJECT_NUMBER NUMBER OUT


RELATIVE_FNO NUMBER OUT


BLOCK_NUMBER NUMBER OUT


ROW_NUMBER NUMBER OUT


TS_TYPE_IN VARCHAR2 IN Y


如果明白了以上ROWID的含义,那么就很容易理解块的地址rdba了,也就是ROWID中的FFFBBBBBB部分,10bit rfile#+22bit,如我们分析一个块地址:


rdba: 0x010072a4


把0x010072a4转化为10进制16806564


SQL> select dbms_utility.data_block_address_file(16806564) "file",


2 dbms_utility.data_block_address_block(16806564) "block"


3 from dual;



file block


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


4 29348



SQL>


现在通过块的dba知道了file和block,那怎样确认我们推到的正确呢? 这个块地址是dump文件的内容,我们可以去dump文件核对下


Start dump data blocks tsn: 4