分类: Oracle
2010-12-30 17:15:53
Oracle 从8I开始就对文件数量控制就引进了relative的概念,这个概念很好理解,但是查询v$datafile,dba_data_files等视图,这个概念又变的不太好理解了。
SQL> select FILE_ID,FILE_NAME,TABLESPACE_NAME,RELATIVE_FNO from dba_data_files;
FILE_ID FILE_NAME TABLESPACE_NAME RELATIVE_FNO
---------- ---------------------------------------------------------------------- -------------------- ------------
1 /ORA10G/data01/NERO/SYSTEM01.DBF SYSTEM 1
2 /ORA10G/data01/NERO/UNDOTBS01.DBF UNDOTBS1 2
3 /ORA10G/data01/NERO/SYSAUX01.DBF SYSAUX 3
4 /ORA10G/data01/NERO/USERS01.DBF USERS 4
按照一般的思维,每个TABLESPACE的第一个文件的RELATIVE_FNO应该为1才是,而这里FILE_ID跟RELATIVE_FNO却是相同的递增。
进一步实验:
首先给USERS表空间增加1022个数据文件(不存在0号文件,单个表空间数据文件上限是1023。这是ORACLE设计的时候就决定了,比如DATA BLOCK中RDBA的前10位是作为R_FNO,1023也就是上限了)。
SQL> create or replace procedure insert_datafile_full
2 as
3 str varchar2(200);
4 begin
5 for i in 2..1022 loop
6 str:='alter tablespace users add datafile ''/ORA10G/data01/NERO/USERS0'||i||'.DBF'' size 1m reuse';
7 execute immediate str;
8 end loop;
9 end;
10 /
Procedure created.
SQL> exec insert_datafile_full;
PL/SQL procedure successfully completed.
SQL> alter tablespace users add datafile '/ORA10G/data01/NERO/USERS01023.DBF' size 1m reuse;
Tablespace altered.
SQL> alter tablespace users add datafile '/ORA10G/data01/NERO/USERS01024.DBF' size 1m reuse;
alter tablespace users add datafile '/ORA10G/data01/NERO/USERS01024.DBF' size 1m reuse
*
ERROR at line 1:
ORA-01686: max # files (1023) reached for the tablespace USERS
SQL> select FILE_ID,FILE_NAME,TABLESPACE_NAME,RELATIVE_FNO from dba_data_files where file_id<>relative_fno;
FILE_ID FILE_NAME TABLESPACE_NAME RELATIVE_FNO
---------- ---------------------------------------------------------------------- -------------------- ------------
1024 /ORA10G/data01/NERO/USERS01021.DBF USERS 1
1025 /ORA10G/data01/NERO/USERS01022.DBF USERS 2
1026 /ORA10G/data01/NERO/USERS01023.DBF USERS 3
SQL> select FILE_ID,FILE_NAME,TABLESPACE_NAME,RELATIVE_FNO from dba_data_files where file_id>1020;
FILE_ID FILE_NAME TABLESPACE_NAME RELATIVE_FNO
---------- ---------------------------------------------------------------------- -------------------- ------------
1021 /ORA10G/data01/NERO/USERS01018.DBF USERS 1021
1022 /ORA10G/data01/NERO/USERS01019.DBF USERS 1022
1023 /ORA10G/data01/NERO/USERS01020.DBF USERS 1023
1024 /ORA10G/data01/NERO/USERS01021.DBF USERS 1
1025 /ORA10G/data01/NERO/USERS01022.DBF USERS 2
1026 /ORA10G/data01/NERO/USERS01023.DBF USERS 3
6 rows selected.
初见眉目了,R_FNO似乎是1-1023的一个带cycle的sequence。
SQL> select count(distinct RELATIVE_FNO) from dba_data_files where TABLESPACE_NAME='USERS';
COUNT(DISTINCTRELATIVE_FNO)
---------------------------
1023
SQL> create tablespace ss datafile '/ORA10G/data01/NERO/SS01.DBF' size 1m reuse;
Tablespace created.
SQL> select FILE_ID,FILE_NAME,TABLESPACE_NAME,RELATIVE_FNO from dba_data_files where TABLESPACE_NAME='SS';
FILE_ID FILE_NAME TABLESPACE_NAME RELATIVE_FNO
---------- ---------------------------------------------------------------------- -------------------- ------------
1027 /ORA10G/data01/NERO/SS01.DBF SS 4
SQL> create tablespace tt datafile '/ORA10G/data01/NERO/TT01.DBF' size 1m reuse;
Tablespace created.
SQL> select FILE_ID,FILE_NAME,TABLESPACE_NAME,RELATIVE_FNO from dba_data_files where TABLESPACE_NAME in ('SS','TT');
FILE_ID FILE_NAME TABLESPACE_NAME RELATIVE_FNO
---------- ---------------------------------------------------------------------- -------------------- ------------
1027 /ORA10G/data01/NERO/SS01.DBF SS 4
1028 /ORA10G/data01/NERO/TT01.DBF TT 5
SQL> alter tablespace ss add datafile '/ORA10G/data01/NERO/SS02.DBF' size 1m reuse;
Tablespace altered.
SQL> select FILE_ID,FILE_NAME,TABLESPACE_NAME,RELATIVE_FNO from dba_data_files where TABLESPACE_NAME in ('SS','TT');
FILE_ID FILE_NAME TABLESPACE_NAME RELATIVE_FNO
---------- ---------------------------------------------------------------------- -------------------- ------------
1027 /ORA10G/data01/NERO/SS01.DBF SS 4
1028 /ORA10G/data01/NERO/TT01.DBF TT 5
1029 /ORA10G/data01/NERO/SS02.DBF SS 6
SQL> alter tablespace users drop datafile '/ORA10G/data01/NERO/USERS01020.DBF';
Tablespace altered.
SQL> alter tablespace users add datafile '/ORA10G/data01/NERO/USERS01020.DBF' size 1m reuse;
Tablespace altered.
SQL> select FILE_ID,FILE_NAME,TABLESPACE_NAME,RELATIVE_FNO from dba_data_files where file_id>1020 order by file_id;
FILE_ID FILE_NAME TABLESPACE_NAME RELATIVE_FNO
---------- ---------------------------------------------------------------------- -------------------- ------------
1021 /ORA10G/data01/NERO/USERS01018.DBF USERS 1021
1022 /ORA10G/data01/NERO/USERS01019.DBF USERS 1022
1023 /ORA10G/data01/NERO/USERS01020.DBF USERS 1023
1024 /ORA10G/data01/NERO/USERS01021.DBF USERS 1
1025 /ORA10G/data01/NERO/USERS01022.DBF USERS 2
1026 /ORA10G/data01/NERO/USERS01023.DBF USERS 3
1027 /ORA10G/data01/NERO/SS01.DBF SS 4
1028 /ORA10G/data01/NERO/TT01.DBF TT 5
1029 /ORA10G/data01/NERO/SS02.DBF SS 6
9 rows selected.
SQL> alter tablespace users drop datafile '/ORA10G/data01/NERO/USERS01020.DBF';
Tablespace altered.
SQL> select FILE_ID,FILE_NAME,TABLESPACE_NAME,RELATIVE_FNO from dba_data_files where file_id>1020 order by file_id;
FILE_ID FILE_NAME TABLESPACE_NAME RELATIVE_FNO
---------- ---------------------------------------------------------------------- -------------------- ------------
1021 /ORA10G/data01/NERO/USERS01018.DBF USERS 1021
1022 /ORA10G/data01/NERO/USERS01019.DBF USERS 1022
1024 /ORA10G/data01/NERO/USERS01021.DBF USERS 1
1025 /ORA10G/data01/NERO/USERS01022.DBF USERS 2
1026 /ORA10G/data01/NERO/USERS01023.DBF USERS 3
1027 /ORA10G/data01/NERO/SS01.DBF SS 4
1028 /ORA10G/data01/NERO/TT01.DBF TT 5
1029 /ORA10G/data01/NERO/SS02.DBF SS 6
8 rows selected.
SQL> alter tablespace ss add datafile '/ORA10G/data01/NERO/SS03.DBF' size 1m reuse;
Tablespace altered.
SQL> select FILE_ID,FILE_NAME,TABLESPACE_NAME,RELATIVE_FNO from dba_data_files where file_id>1020 order by file_id;
FILE_ID FILE_NAME TABLESPACE_NAME RELATIVE_FNO
---------- ---------------------------------------------------------------------- -------------------- ------------
1021 /ORA10G/data01/NERO/USERS01018.DBF USERS 1021
1022 /ORA10G/data01/NERO/USERS01019.DBF USERS 1022
1023 /ORA10G/data01/NERO/SS03.DBF SS 1023
1024 /ORA10G/data01/NERO/USERS01021.DBF USERS 1
1025 /ORA10G/data01/NERO/USERS01022.DBF USERS 2
1026 /ORA10G/data01/NERO/USERS01023.DBF USERS 3
1027 /ORA10G/data01/NERO/SS01.DBF SS 4
1028 /ORA10G/data01/NERO/TT01.DBF TT 5
1029 /ORA10G/data01/NERO/SS02.DBF SS 6
9 rows selected.
SQL> alter tablespace users add datafile '/ORA10G/data01/NERO/USERS01020.DBF' size 1m reuse;
Tablespace altered.
SQL> select FILE_ID,FILE_NAME,TABLESPACE_NAME,RELATIVE_FNO from dba_data_files where file_id>1020 order by file_id;
FILE_ID FILE_NAME TABLESPACE_NAME RELATIVE_FNO
---------- ---------------------------------------------------------------------- -------------------- ------------
1021 /ORA10G/data01/NERO/USERS01018.DBF USERS 1021
1022 /ORA10G/data01/NERO/USERS01019.DBF USERS 1022
1023 /ORA10G/data01/NERO/SS03.DBF SS 1023
1024 /ORA10G/data01/NERO/USERS01021.DBF USERS 1
1025 /ORA10G/data01/NERO/USERS01022.DBF USERS 2
1026 /ORA10G/data01/NERO/USERS01023.DBF USERS 3
1027 /ORA10G/data01/NERO/SS01.DBF SS 4
1028 /ORA10G/data01/NERO/TT01.DBF TT 5
1029 /ORA10G/data01/NERO/SS02.DBF SS 6
1030 /ORA10G/data01/NERO/USERS01020.DBF USERS 1023
10 rows selected.
到这里可以猜测,relative file_no 应该是类似于一个1-1023的全局的带CYCLE的循环 递增的’SEQUENCE’,我们增加DATAFILE的时候会用’SEQ’.NEXTVAL来填充该R_FNO,如果NEXTVAL与该 TABLESPACE的数据文件的RELATIVE FILE_NO冲突,就会尝试下个NEXTVAL,以此循环,如果发现1-1023都冲突,说明该表空间数据文件数量达到上限了。
Ref: http://hi.baidu.com/kywinder/blog/item/4d2bd3d13d97890e3bf3cfc1.html