ROWID的含義與塊地址rdba深入分析

路途中的人2012發表於2016-05-20

Oracle 8以下ROWID組成(也叫受限Rowid)為:FFFF.BBBBBBBB.RRRR,佔用6個位元組(10bit file#+22bit+16bit),但是,為了擴充的需要,如資料檔案的擴充,現在的Rowid改為:OOOOOOFFFBBBBBBRRR,佔用 10個位元組(32bit+10bit rfile#+22bit+16bit)。其中,O是物件ID,F是檔案ID,B是塊ID,R是行ID。由於rowid的組成從file#變成了 rfile#,所以資料檔案數的限制也從整個庫不能超過1023個變成了每個表空間不能超過1023個資料檔案。

 

注意:這裡的O,代表的是data_object_id,是與段物理儲存位置相關的一個資訊,因為一個段物件只可能在一個表空間 上,data_object_id能唯一確認ts#,而data_object_id + rfile#就能最終定位到該rowid在那個確定的物理資料檔案。

 

如果我們查詢一個表的ROWID,就可以獲得object的資訊,檔案資訊,塊資訊與行資訊等等,如根據其中塊的資訊,可以知道該表確切佔用了多少個塊,每行在哪個塊上,哪個資料檔案上。

用例子說明一下Rowid的組成:

  1. SQL> select rowid from emp where rownum = 1; 
  2.      AAAAeNAADAAAAWZAAA

分解一下,可以看到

				
				

Data Object number = AAAAeN

File = AAD

Block = AAAAWZ

ROW = AAA

另外,我們需要注意的是,ROWID是64進位制的,分佈關係如下

				
				

A-Z <==> 0 - 25 (26)

a-z <==> 26 - 51 (26)

0-9 <==> 52 - 61 (10)

+/ <==> 62 - 63 (2)

拿其中的Data Object number= AAAAeN為例子,

N是64進位制中的13,位置為0

13 * (64 ^ 0) = 13

E是64進位制中的30,位置為1

30 * (64 ^ 1) = 1920

A是64進位制中的 0

所以

				
				

A * (64 ^ 2) = 0

A * (64 ^ 3) = 0

A * (64 ^ 4) = 0

A * (64 ^ 5) = 0

則有AAAAeN = 0 + 0 + 0 + 0 + 1920 + 13 = 1933,表示該行存在的物件,對應的物件號為1933。

而且,我們也可以利用oracle提供的包,dbms_rowid來做到這一點:

  1. select dbms_rowid.rowid_object('AAAAeNAADAAAAWZAAA') data_object_id#,
  2.        dbms_rowid.rowid_relative_fno('AAAAeNAADAAAAWZAAA') rfile#,
  3.        dbms_rowid.rowid_block_number('AAAAeNAADAAAAWZAAA') block#,
  4.        dbms_rowid.rowid_row_number('AAAAeNAADAAAAWZAAA') row# from dual;
  5.  
  6.        DATA_OBJECT_ID#     RFILE#     BLOCK#       ROW#
  7.        --------------- ---------- ---------- ----------
  8.                   1933          3       1433          0

關於更多dbms_rowid的用法,可以參考包的說明或者是oracle手冊。

 

如果明白了以上ROWID的含義,那麼我們就很容易理解塊的地址了rdba了,也就是ROWID中的FFFBBBBBB部分,10bit rfile#+22bit,如我們分析一個塊地址:

DBA: 0×2fc0100a

那麼,把0×2fc0100a轉換成2進製為

							
							

2 f c 0 1 0 0 a

0010 1111 1100 0000 0001 0000 0000 1010

再次轉換

0010 1111 11 00 0000 0001 0000 0000 1010

=—————— —————————

資料檔案id 塊ID

=191(十進位制) =4106(十進位制)

或者0×2fc0100a=十進位制的801116170

  1. SQL> select dbms_utility.data_block_address_file(801116170) "file",
  2.   2         dbms_utility.data_block_address_block(801116170) "block" 
  3.   3         from dual;
  4.  
  5.       file      block
  6. ---------- ----------
  7.        191       4106

注意,這裡得到的191是rfile#,相對檔案號,而相對檔案號是不能超過1023,所以,如果你想根據這個地址來dump資料檔案塊的話,最好還是核對一下v$datafile:

select file# from v$datafile where rfile# = 191 and ts# = <:dbfile_in_ts>

  1. SQL> select file# from v$datafile where rfile# = 191 and ts# = 9;
  2.  
  3.      FILE#
  4. ----------
  5.       1214

這裡的9代表該資料檔案所在的表空間的編號,你是不是驚奇的發現,這個塊地址真正的資料檔案編號應當是1214。而不是我們轉換得到的191。

不過一般的情況下,資料庫的資料檔案都沒有1023個,所以這個時候的資料檔案編號file#與rfile#基本是對應的,這個時候,如果我們要dump這個資料塊,就可以採用如下的方式來dump

  1. alter system dump datafile 1214 block 4106;

原文連結:http://www.cnblogs.com/rootq/archive/2009/02/13/1389795.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29067253/viewspace-2103928/,如需轉載,請註明出處,否則將追究法律責任。

相關文章