承接解析Oracle rowid系列一、系列二。今天,我们来探讨特定场景下的Oracle rowid,大文件表空间下的Oracle rowid。大文件的表空间是Oracle 10g的新特性,关于该特性暂且不作过多表述,简单一句话来说,同小文件类型的表空间(数据库默认的表空间类型)相比,该类型的表空间只能包含一个而且最多只能有一个数据文件。正是因为如此,所以位于大文件类型表空间下的表的rowid显得有些特殊,接下来我们探讨究竟特殊在哪儿?
首先,准备场景,建立大文件表空间,并在该表空间下建立一张普通的Heap表。
SQL> conn / as sysdba; Connected. SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production PL/SQL Release 11.2.0.1.0 - Production CORE 11.2.0.1.0 Production TNS for Linux: Version 11.2.0.1.0 - Production NLSRTL Version 11.2.0.1.0 - Production SQL> create bigfile tablespace big_tbs datafile size 10m autoextend on; Tablespace created. SQL> select d.file_id,d.tablespace_name,t.bigfile 2 from dba_data_files d,dba_tablespaces t 3 where d.tablespace_name=t.tablespace_name 4 order by 1 5 ; FILE_ID TABLESPACE_NAME BIG ---------- ----------------- --- 1 SYSTEM NO 2 SYSAUX NO 3 UNDOTBS1 NO 4 USERS NO 5 EXAMPLE NO 6 UNDOTBS2 NO 7 TEST_TBS NO 8 TEST_TBS NO 9 BIG_TBS YES 9 rows selected. SQL> alter user hr quota unlimited on big_tbs; User altered. SQL> conn hr/hr Connected. SQL> create table bigfile_tab(id number,name varchar2(10)) 2 tablespace big_tbs 3 ; Table created. SQL> insert into bigfile_tab values(1,'oracle'); 1 row created. SQL> insert into bigfile_tab values(2,'oracle'); 1 row created. SQL> commit; Commit complete. SQL>
然后,我们来查询bigfile_tab表中的rowid:
SQL> select id,rowid from bigfile_tab; ID ROWID ---------- ------------------ 1 AAAUHfAAAAAAACGAAA 2 AAAUHfAAAAAAACGAAB SQL> select rowid, 2 dbms_rowid.rowid_object(rowid) object_id, 3 dbms_rowid.rowid_relative_fno(rowid) file_id, 4 dbms_rowid.rowid_block_number(rowid) block_id , 5 dbms_rowid.rowid_row_number(rowid) num 6 from bigfile_tab 7 ; ROWID OBJECT_ID FILE_ID BLOCK_ID NUM ------------------ ---------- ---------- ---------- ---------- AAAUHfAAAAAAACGAAA 82399 0 134 0 AAAUHfAAAAAAACGAAB 82399 0 134 1 SQL>
这时,我们发到貌似诡异的相对文件号竟然为0,本来我们的这张测试表位于bigfile_tbs表空间下,而bigfile_tbs表空间的file_id为9,我们从上述的第一次查询结果可以验证。可是为什么从rowid中查询的相对文件号为什么为0呢?
原来,对于大文件表空间下的rowid有如下特定的格式,这有别于小文件表空间下的rowid格式:
OOOOOOBBBBBBBBBRRR
即,6位的数据库对象号+9位的数据块号+3位的行号,同样也是以18位的64进制值来表示80位的二进制数。只不过,在这里少了相对文件号,其中6位的数据库对象号用32位的二进制数来存放(即一个数据库最多可以拥有232=4G个数据块对象),9位的数据块号同样用32位的二进制数来存放(即一个大文件表空间可以拥有232个数据块儿),最后3位的行号占用剩余的16位的二进制数,正好占满80位。
最后,我们就可以很容易理解为什么本实验中bigfile_tab表的相对文件号为0了?因为该表的rowid格式中根本就不存在相对文件号的信息,最本质的原因是大文件表空间下永远只能有且仅有1个数据文件,也就没有相对文件号的概念了。
同时,我们也可以推算出为什么官方文档中说,对于大文件的表空间,如果数据块大小为32K的话,那么这个表空间的上限是128Tb?因为大文件表空间下最多可以有232个数据块,那么该表空间大小=232*32K=237K=227M=217G=27T=128T,答案也就在于此。
至此,关于Oracle rowid的探讨一、二、三系列结束。如果,大家对该系列有不同的理解,或认为本人理解有误的地方,还请不吝指正!!!
评论 (1)
anonymous| 2011年11月13日
这个系列很不错!