All about oracle smallfile and bigfile tablespace(二)
data/orcl/users01.dbf 4 4
/oradata/orcl/undotbs01.dbf 3 3
/oradata/orcl/sysaux01.dbf 2 2
/oradata/orcl/system01.dbf 1 1
/oradata/orcl/bttest.dbf 5 1024
=======================================================================
每个文件都包括两个编号,一个是绝对文件编号file_id,另一个是相对文件编号relative_fno。在文件数量较少,或者创建删除文件比较少情况下的数据库,file_id 和relative_fno 是相同的。Relative_fno 是一个循环周期,以1024为一个循环。当file_id依次递增到1024整数倍之后,file_id会继续增加,而relative_fno会形成一个内部循环。
这种机制让我们联想起了Oracle Small Tablespace 的数据文件上限限制,也是1023个文件。我们设想一种极端的情况,如果一个表空间中的数据文件个数超过了1024,也就是一个表空间内的数据文件中,存在相同的relative_fno。这种情况首先是不被允许的。
设置1024的relative_fno 是进行Oracle 数据寻址的需要。这里我们要关注到Oracle定位数据行的rowid 信息,rowid 是Oracle 内部唯一标注一行记录的地址。Rowid 包括四部分组成,对象号 + 文件号 + 块号 + slot行号。Rowid长度固定,所以四部分的长度都是固定的,这里的文件号fno是相对文件编号。这里的查找顺序是,对象号获取所在表空间的编号,在表空间内部使用相对文件号来定位到文件。如果一个表空间内出现相同的relative_fno 文件,定位就不可能了。所以,small tablepsace 的内部文件上限必然是1023。
但是,Bigfile Tablespace存在一些不同之处。如果一个表空间只有一个数据文件且只能拥有一个数据文件,那么relative_fno就失去了存在的意义。所以在dba_data_files 中的relative_fno 列上,bigfile tablespace 对应的datafile 是直接1024。
==========================================================================================
SYS@ orcl> create table t_big tablespace bttest as select * from dba_tables;
Table created.
SYS@ orcl> select dbms_rowid.rowid_object(t.rowid) obj_id, dbms_rowid.rowid_relative_fno(t.rowid,'BIGFILE') relative_fno,
2 dbms_rowid.rowid_block_number(t.rowid) block_num, dbms_rowid.rowid_row_number(t.rowid) rownums,
3 dbms_rowid.rowid_to_absolute_fno(t.rowid,'SYS','T_BIG') abso_fno
4 from t_BIG t where rownum < 4;
OBJ_ID RELATIVE_FNO BLOCK_NUM ROWNUMS ABSO_FNO
---------- ------------ ---------- ---------- ----------
74519 1024 131 0 5
74519 1024 131 1 5
74519 1024 131 2 5
==========================================================================================
借助dbms_rowid包的相应方法,我们也可以看清bigfile tablespace上rowid行的relative_fno信息。
3、Bigfile Datafile大小探索
一个数据文件最大能有多大,在Oracle中有两个因素控制,一个是Oracle内部寻址能够寻找到的最大范围多少个块,另一个是数据库每个块大小是多大。
我们首先来看看Small Datafile的情况。Rowid是一个用16进制表示的18位长度类字符串。其中,前6位表示object_id,之后3位表示文件编号,之后6位表示块号,最后3位表示row的slot编号。
--语句摘自MOS[ID 1057891.6]
SQL> select substr(rowid,1,6) "object",
substr(rowid,7,3) "file",
substr(rowid,10,6) "block",
substr(rowid,16,3) "row"
from test;
object fil block row
------ --- ------ ---
AAABPW AAF AAAAv1 AAA
在small datafile中,对数据块有6×4=24位二进制表示。Oracle利用中间的22位进行块地址存储。这样,22位二进制可以表示的数据块编号范围为(2^22-1)=4M个数据块。如果按照每个数据块8K的普遍大小计算,这样每个small datafile大小上限就是32G。如果按照每个数据块上限32K计算,这样每个small datafile大小上限就是128G。
在bigfile datafile中,事情有所不同。由于没有relative_fno的问题,这样rowid中就不需要保存relative_fno 的最多1024的数值。这样就节省出10位二进制位给数据块定位,相同长度的rowid 就可以进行32位二进制长度的数据块寻址。每个bigfile datafile 中,最多可以包括到(2^32-1)=4G 个数据块。在数据块大小8K的环境下,最大为32TB数据。如果是数据块大小为32K环境下,文件最大可以到128TB大小。
4、结论和讨论
在本文第一部分中,我们讨论了Bigfile Tablespace 和Small Tablespace 的理论分析,两者理论上最大容量值是一样的。只是Bigfile的单个文件容量上限很大,我们如何看待这种新类型呢?
首先,实际生产环境下,Bigfile Tablespace 在