表FILE$是SYS用户下面的一张字典表,这个表大家很少会接触到。但是由他生成其他字典表大家应该会很熟悉的。比如说是dba_file_data:
[@more@]
表FILE$是SYS用户下面的一张字典表,这个表大家很少会接触到。但是由他生成其他字典表大家应该会很熟悉的。比如说是dba_file_data:
create view dba_data_files as
select
a.name tablespace,a.dflminext min_extents, a.dflmaxext max_extents,
a.dflinit init,a.dflincr next,a.dflextpct pct_increase, d.name datafile,
b.blocks datafile_size, c.maxextend max_extend, c.inc ext_incr
from ts$ a, file$ b, filext$ c, v$dbfile d
where a.ts#=b.ts# and b.file#=c.file# and b.file#=d.file#
从上面的这个SQL可以看出来,FILE$表里面存储的内容和数据文件是关系的,我们来看一下FILE$的定义:
Name Type Nullable Default Comments
------------- -------------- -------- ------- --------
FILE# NUMBER
STATUS$ NUMBER
BLOCKS NUMBER
TS# NUMBER Y
RELFILE# NUMBER Y
MAXEXTEND NUMBER Y
INC NUMBER Y
CRSCNWRP NUMBER Y
CRSCNBAS NUMBER Y
OWNERINSTANCE VARCHAR2(30) Y
SPARE1 NUMBER Y
SPARE2 NUMBER Y
SPARE3 VARCHAR2(1000) Y
SPARE4 DATE Y
字段说明:
FILE# —— 数据文件的编号
STATUS$ —— 数据文件的状态,2为正常,1为删除
BLOCKS —— 数据文件中的块数
TS# —— 数据文件所属表空间的编号
RELFILE# —— 数据文件的相关文件号,一般和FILE#相同
MAXEXTEND —— 数据文件最大盘区数
INC —— 数据文件自动扩展大小
CRSCNWRP —— 不详
CRSCNBAS —— 数据文件创建时的SCN
OWNERINSTANCE —— 数据文件所属INSTANCE,RAC环境
SPARE1 —— 表参数1
SPARE2 —— 表参数2
SPARE3 —— 表参数3
SPARE4 —— 表参数4
当你为数据库增加一个新的数据文件的时候,表FILE$中会相应的增加一条记录,而在数据库中删除一个数据文件的时候,表FILE$中并不会立即的删掉相关的记录,而是在字段STATUS$上标识为1(删除)。即使重启数据库后那些标识为1的记录也不会被删掉,但是在有新的数据文件增加后,该条记录有可能被重用。
我下面想要重点说明的是表FILE$中字段SPARE1的含义。不知道大家注意过没有,大部分基本表(就是名字里面带有$的数据字典基表)中都会有相似的字段,不同的基表中参数字段的个数也不一样,当然含义也是不一样的。这些含义在ORACLE的文档中是没有说明的。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 – Production
SQL> select file#,blocks,ts#,spare1 from file$;
FILE# BLOCKS TS# SPARE1
---------- ---------- ---------- ----------
1 38400 0 4194306
2 3200 1 8388610
3 15360 2 12582914
4 640 4 16777218
5 12800 6 20971522
6 12800 7 25165826
7 64000 7 29360130
8 1280 8 33554434
9 128 10 37748738
10 64000 11 41943042
10 rows selected
可以看出来SPARE1是随着数据文件标号递增的,细心的同学可以发现相邻数据文件的SPARE1的差值是相同的。在我的数据库环境下都是4194304(2的22次方)。普通数据文件中数据块的个数是有限制的,而这个限制正是4194304 - 1。因为数据文件中块的个数有限制,那么数据文件的总大小也是有限制的。2K的数据文件最大为2K*4194304,大概是8G,类似的8 K的数据文件最大是32G,16K的数据文件最大是64G。这个限制其实也就是ROWID的表达方式上的限制,小文件中的ROWID是用22位来表示BLOCK ID的,所以存在2的22次方的限制。
在10G中引入了大文件表空间,在这种大文件的表空间中是用32位来表示BLOCK ID的。多余的10位是表空间的file#,所以在大文件的表空间中只能有一个数据文件,这也是为了获得更大的BLOCK ID所做的必要的牺牲。
创建大文件表空间的语法如下:
SQL> create bigfile tablespace test05 datafile 'c:/1.dbf' size 1m;
Tablespace created
如果想在大文件的表空间中增加数据文件会出现以下错误
SQL> alter tablespace test05 add datafile 'c:/2.dbf' size 1m;
alter tablespace test05 add datafile 'c:/2.dbf' size 1m
ORA-32771: 无法在大文件表空间中添加文件
说的有些远了,接着说FILE$。大文件的数据文件在FILE$上表现与普通的数据文件会有几个差异。首先,大文件的数据文件的RELFILE#并不和FILE#相同,而是等于1024,可能和占用ROWID中的10位有关系吧。其次,大文件的数据文件的SPARE1字段全部为2,无论这个大文件的数据文件的大小有多大。
create or replace procedure get_fileid_blockid(rdba in varchar2) is
n_rowid number;
n_fileid number;
n_blockid number;
begin
select to_number(rdba,'xxxxxxxxxxxxx')
into n_rowid
from dual;
select round((n_rowid - 4194306)/power(2,22))+1,mod((n_rowid - 4194306 + 2),power(2,22))
into n_fileid,n_blockid
from dual;
dbms_output.put_line('file id is '||to_char(n_fileid));
dbms_output.put_line('block id is '||to_char(n_blockid));
end get_fileid_blockid;
上面的过程是根据RDBA来计算文件号和块号的例子,在普通数据文件的情况下没有问题,在大文件中可能会有些问题。贴上来只是给大家做个参考。
SQL> alter system dump datafile 7 block 151;
System altered
SQL> exec get_fileid_blockid('01c00097');
file id is 7
block id is 151
PL/SQL procedure successfully completed
外部的表现都是由内部的结构决定的。ORACLE是这样的,其他事情也是一样的.
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8394333/viewspace-987130/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/8394333/viewspace-987130/