理论上的 BFT 可以达到下面所列的值:
数据块大小(单位:K) BFT 最大值(单位:T) 2k 8T 4k 16T 8k 32T 16k 64T 32k 128T
DATAFILE '/u01/app/oracle/oradata/DEMO/bftbs02.dbf' SIZE 20T reuse;
10bit的file number,每个对象最多有1022个文件(2个文件预留)
22bit的block number,每个文件最多有4M个BLOCK
16bit的row number,每个BLOCK最多有64K个ROWS
select rowid ,
substr(rowid,1,6) "OBJECT",
substr(rowid,7,3) "FILE",
substr(rowid,10,6) "BLOCK",
substr(rowid,16,3) "ROW"
from TableName;
OWID OBJECT FILE BLOCK ROW
------------------ ------------ ------ ------------ ------
AAABc4AADAAAGLUAAA AAABc4 AAD AAAGLU AAA
AAABc4AADAAAGLUAAB AAABc4 AAD AAAGLU AAB
AAABc4AADAAAGLUAAC AAABc4 AAD AAAGLU AAC
AAABc4AADAAAGLUAAD AAABc4 AAD AAAGLU AAD
AAABc4AADAAAGLUAAE AAABc4 AAD AAAGLU AAE
通过dbms_rowid这个包,可以直接的得到具体的rowid包含的信息:
select dbms_rowid.rowid_object(rowid) object_id,
dbms_rowid.rowid_block_number(rowid) block_id ,
OBJECT_ID FILE_ID BLOCK_ID NUM
---------- ---------- ---------- ----------
5944 3 25300 0
5944 3 25300 1
5944 3 25300 2
5944 3 25300 3
一些使用ROWID的函数
ROWIDTOCHAR(rowid) :将ROWID转换成STRING
CHARTOROWID('rowid_string') :将STRING转换成ROWID
另外,就是自己写的一些函数:(下面的函数是网友eygle提供)
create or replace function get_rowid
(l_rowid in varchar2)
return varchar2
is
ls_my_rowid varchar2(200);
rowid_type number;
object_number number;
relative_fno number;
block_number number;
row_number number;
begin
dbms_rowid.rowid_info(l_rowid,rowid_type,object_number,relative_fno, block_number, row_number);
ls_my_rowid := 'Object# is :'||to_char(object_number)||chr(10)||
'Relative_fno is :'||to_char(relative_fno)||chr(10)||
'Block number is :'||to_char(block_number)||chr(10)||
'Row number is :'||to_char(row_number);
return ls_my_rowid ;
end;
/
应用上面的函数如下:
SQL> select get_rowid(rowid), name from bruce_t;
GET_ROWID(ROWID) NAME
-------------------------------------------------------------------------------- --------------------------------
Object# is :5944 BruceLau
Relative_fno is :3
Block number is :25300
Row number is :0
Object# is :5944 MabelTang
Relative_fno is :3
Block number is :25300
Row number is :1
大家都知道从Oracle8开始,Oracle开始使用“相对文件号”,使原来一个数据库最多只能有1023个文件,扩展为一个表空间最多可以有1023个文件,每个库最多可以有65534个文件。
我们来作一个测试:
SQL> create tablespace test_mf datafile 'F:\Works\oracle\product\10.2.0\oradata\
xj\many\m1.dbf' size 100k reuse;
表空间已创建。
SQL> alter tablespace test_mf add datafile 'F:\Works\oracle\product\10.2.0\orada
ta\xj\many\m2.dbf' size 88k;
表空间已更改。
SQL> show parameter db_files
NAME TYPE VALUE
--------------------------- ----------- ---------------
db_files integer 2000
SQL> begin
2 for i in 193..1025 loop
3 execute immediate'alter tablespace test_mf add datafile ''F:\Works\ora
cle\product\10.2.0\oradata\xj\many\m_' || i ||''' size 88k';
4 end loop;
5 end;
6 /
begin
*
第 1 行出现错误:
ORA-01686: 最大文件数 (1023) 对于表空间 TEST_MF 已达到
ORA-06512: 在 line 3
SQL> select count(*) from dba_data_files where tablespace_name='TEST_MF';
COUNT(*)
----------
1023
可以看到表空间TEST_MF的文件数为1023个,最多也只能为1023个。
SQL> select ts# from v$tablespace where name='TEST_MF';
TS#
----------
8
SQL> select file#,rfile#,name from v$datafile where ts#=8;
FILE# RFILE# NAME
---------- ---------- ------------------------------------------------------------
7 7 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M1.DBF
8 8 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M2.DBF
9 9 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1
10 10 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_2
11 11 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_3
..................................................................................
1019 1019 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1011
1020 1020 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1012
1021 1021 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1013
1022 1022 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1014
1023 1023 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1015
1024 1 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1016
1025 2 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1017
1026 3 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1018
1027 4 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1019
1028 5 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1020
1029 6 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\M_1021
从上面的数据可以看出,当绝对文件号小于等于1023,相对文件号与绝对文件号一样。相对文件号大于1023之后,又从1开始循环。
我们DUMP最后一个文件的文件头块看看:
Block Header:
block type=0x0b (file header)
block format=0xa2 (oracle 10)
block rdba=0x01800001 (file#=6, block#=1)
scn=0x0000.00000000, seq=1, tail=0x00000b01
block checksum value=0xe7f3=59379, flag=4
File Header:
Db Id=0xb004e979=2953111929, Db Name=XJ, Root Dba=0x0
Software vsn=0x0, Compatibility Vsn=0xa200100, File Size=0xb=11 Blocks
File Type=0x3 (data file), File Number=1029, Block Size=8192
Tablespace #8 - TEST_MF rel_fn:6
文件头里面有两部分内容,第一部分为块头,块头记录了该块的RDBA:block rdba=0x01800001 (file#=6, block#=1),因此块头记录的是相对文件号。第二部分为文件头,文件头里面有如下的记录:
File Type=0x3 (data file), File Number=1029, Block Size=8192
Tablespace #8 - TEST_MF rel_fn:6
因此文件头里同时记录了文件绝对号,表空间号和相对文件号。
下面我们再做另一个实验,看看段是怎么跟文件号关联的。
SQL> create tablespace test_lf datafile 'F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\
XJ\MANY\TEST_LF.dbf' size 1m;
表空间已创建。
SQL> select ts# from v$tablespace where name='TEST_LF';
TS#
----------
9
SQL> select file#,rfile#,name from v$datafile where ts#=9;
FILE# RFILE# NAME
---------- ---------- ------------------------------------------------------------
1030 7 F:\WORKS\ORACLE\PRODUCT\10.2.0\ORADATA\XJ\MANY\TEST_LF.DBF
从上面的数据可以看出,一个表空间的数据文件,其相对文件号并不是从1开始的,而依然是从上一个用过的最后一个相对文件号继续。
SQL> select obj# from obj$ where owner#=0 and name='T1';
OBJ#
----------
47686
SQL> select obj#,dataobj#,ts#,file# from tab$ where obj#=47686;
OBJ# DATAOBJ# TS# FILE#
---------- ---------- ---------- ----------
47686 47686 9 7
在数据字典里面记录了表的段头表空间号和相对文件号。
SQL> select header_file,header_block,relative_fno from dba_segments where segmen
t_name='T1' and wner='SYS';
HEADER_FILE HEADER_BLOCK RELATIVE_FNO
----------- ------------ ------------
1030 11 7
在DBA_SEGMENTS视图里面,可以查到段头的相对文件号和绝对文件号。(这个视图最终是从file$、seg$等字典表里面取得数据)
三、临时文件的绝对文件号
转载:http://www.eygle.com/archives/2006/03/tempfile_and_sort_usage.html
V$TEMPSEG_USAGE和V$SORT_USAGE同源,其中的SEGFILE#代表的是绝对文件号(AFN).
那么对于临时表空间的临时文件来说,这个字段可以和什么字段进行关联呢?
我们再来看一下V$TEMPFILE的来源,V$TEMPFILE由如下语句创建:
SELECT tf.inst_id, tf.tfnum, TO_NUMBER (tf.tfcrc_scn), |
考察x$kcctf底层表,我们注意到TFAFN(temp file absolute file number)在这里存在:
SQL> desc x$kcctf |
而这个字段在构建v$tempfile时并未出现,所以我们不能通过v$sort_usage和v$tempfile直接关联绝对文件号.
通过LOB对象与临时段一文中方法我们可以简单构建一个排序段使用,然后来研究一下:
SQL> select username,segtype,segfile#,segblk#,extents,segrfno# USERNAME SEGTYPE SEGFILE# SEGBLK# EXTENTS SEGRFNO# |
我们看到这里的SEGFILE#=9,而在v$tempfile是找不到这个信息的:
SQL> select file#,rfile#,ts#,status,blocks FILE# RFILE# TS# STATUS BLOCKS |
我们可以从x$kcctf中获得这些信息,我们可以看到v$tempfile.file#实际上来自x$kcctf.tfnum,实际上是临时文件的顺序号,而绝对文件号是x$kcctf.tfafn,这个才可以和v$sort_usage.segfile#关联:
SQL> select indx,tfnum,tfafn,tfcsz INDX TFNUM TFAFN TFCSZ |
临时表空间的绝对文件号可以通过如下查询获得:
SQL> select tm.file# Fnum ,tf.tfafn AFN,tm.name FName FNUM AFN FNAME |
转载:http://www.eygle.com/archives/2006/03/file_id_and_db_files.html
我们注意到对于临时文件的绝对文件号(AFN),Oracle的分配规则和常规数据文件并不相同.
实际上,临时文件的绝对文件号应该等于db_files + file#.
我们看一下实例:
SQL> select indx,tfnum,tfafn,tfcsz 2 from x$kcctf; INDX TFNUM TFAFN TFCSZ ---------- ---------- ---------- ---------- 0 1 201 2560 SQL> show parameter db_files NAME TYPE VALUE ------------------------------------ ----------- -------------- db_files integer 200 SQL> select file#,name from v$tempfile; FILE# NAME ---------- ----------------------------------------- 1 +ORADG/danaly/tempfile/temp.267.600173887 SQL> |
所以在 Oracle文档中v$tempfile.file#被定义为 The absolute file number是不确切的.
经常的,我们可能会在警报日志文件中看到类似如下的错误:
*** Corrupt block relative dba: 0x00c0008a (file 202, block 138) Bad header found during buffer read Data in bad block - type: 8 format: 2 rdba: 0x0140008a last change scn: 0x0000.431f8beb seq: 0x1 flg: 0x08 consistency value in tail: 0x8beb0801 check value in block header: 0x0, block checksum disabled spare1: 0x0, spare2: 0x0, spare3: 0x0 *** |
这里的file 202其实指的就是临时文件.
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/95233/viewspace-586801/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/95233/viewspace-586801/