当一个表空间中有多个数据文件,新增数据时,会写到哪个数据文件上呢?有人说是由ORACLE随机控制,即是根据一个分配算法计算后,将新增的数据写入到指定的一个或多个数据文件上。但这个算法是什么,一直也没有找到相关的说明。下面的这个实验,算是对这个算法的一个初步探寻吧,供大家参考。
实验设想:
所有实验在ORACLE DATABASE 10.2.0.5上完成,操作系统为Linux localhost.localdomain 2.6.18-194.el5 。创建的表空间均为本地自动管理。
情景1:创建两个非自动扩展的的数据文件,创建测试用表,向测试用表中插入数据,观察这两个数据文件的空间使用情况。然后增加一个同样大小的自动扩展的数据文件后,继续向测试用表中插入数据,观察这三个数据文件的空间使用情况。再增加一个同样大小的非自动扩展的数据文件后,继续向测试用表中插入数据,并观察四个数据文件的空间使用情况。
SQL> create tablespace demo datafile '/oradata/orcl/demo01.dbf' size 2M autoextend off,'/oradata/orcl/demo02.dbf' size 2M autoextend off;
Tablespace created.
SQL> select * from dba_data_files where tablespace_name='DEMO';
FILE_NAME FILE_ID TABLESPACE BYTES BLOCKS STATUS RELATIVE_FNO AUT MAXBYTES MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 2097152 256 AVAILABLE 6 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 2097152 256 AVAILABLE 8 NO 0 0 0 2031616 248 ONLINE
检查DEMO表空间的管理方式,确认为本地自动管理。
SQL> select tablespace_name,block_size,initial_extent,next_extent,min_extents,max_extents,extent_management,allocation_type from dba_tablespaces where tablespace_name='DEMO';
TABLESPACE BLOCK_SIZE INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS EXTENT_MAN ALLOCATIO
---------- ---------- -------------- ----------- ----------- ----------- ---------- ---------
DEMO 8192 65536 1 2147483645 LOCAL SYSTEM
创建测试用表,并插入1000行记录
SQL> create table demo_table tablespace demo as select * from dba_objects where 1=2;
Table created.
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
查看当前空间使用情况
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_ID BLOCK_ID BYTES
-------------------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536
DEMO_TABLE DEMO 8 1 17 65536
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 25 1900544 232 8
如上所示,1000行记当占用了两个区,共16个数据块,每个区由8个数据块组成,共占用了16个数据块。每个数据块8K,共占用了128K的空间。但这128K的空间全部来自于FILE_ID为8的数据文件。
我们继续插入1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_ID BLOCK_ID BYTES
-------------------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536
DEMO_TABLE DEMO 8 1 17 65536
DEMO_TABLE DEMO 8 2 25 65536
DEMO_TABLE DEMO 8 3 33 65536
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 41 1769472 216 8
仍然是使用8号文件。继续插入数据。
SQL> select count(1) from demo_table;
COUNT(1)
----------
8000
已经插入了8000行(前面插入数据的过程略去)
再插入数据1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 129 1048576 128 8
可以看到,这时仍只是使用8号文件,6号文件一直未使用。
再插入数据1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
实验设想:
所有实验在ORACLE DATABASE 10.2.0.5上完成,操作系统为Linux localhost.localdomain 2.6.18-194.el5 。创建的表空间均为本地自动管理。
情景1:创建两个非自动扩展的的数据文件,创建测试用表,向测试用表中插入数据,观察这两个数据文件的空间使用情况。然后增加一个同样大小的自动扩展的数据文件后,继续向测试用表中插入数据,观察这三个数据文件的空间使用情况。再增加一个同样大小的非自动扩展的数据文件后,继续向测试用表中插入数据,并观察四个数据文件的空间使用情况。
SQL> create tablespace demo datafile '/oradata/orcl/demo01.dbf' size 2M autoextend off,'/oradata/orcl/demo02.dbf' size 2M autoextend off;
Tablespace created.
SQL> select * from dba_data_files where tablespace_name='DEMO';
FILE_NAME FILE_ID TABLESPACE BYTES BLOCKS STATUS RELATIVE_FNO AUT MAXBYTES MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 2097152 256 AVAILABLE 6 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 2097152 256 AVAILABLE 8 NO 0 0 0 2031616 248 ONLINE
检查DEMO表空间的管理方式,确认为本地自动管理。
SQL> select tablespace_name,block_size,initial_extent,next_extent,min_extents,max_extents,extent_management,allocation_type from dba_tablespaces where tablespace_name='DEMO';
TABLESPACE BLOCK_SIZE INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS EXTENT_MAN ALLOCATIO
---------- ---------- -------------- ----------- ----------- ----------- ---------- ---------
DEMO 8192 65536 1 2147483645 LOCAL SYSTEM
创建测试用表,并插入1000行记录
SQL> create table demo_table tablespace demo as select * from dba_objects where 1=2;
Table created.
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
查看当前空间使用情况
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_ID BLOCK_ID BYTES
-------------------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536
DEMO_TABLE DEMO 8 1 17 65536
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 25 1900544 232 8
如上所示,1000行记当占用了两个区,共16个数据块,每个区由8个数据块组成,共占用了16个数据块。每个数据块8K,共占用了128K的空间。但这128K的空间全部来自于FILE_ID为8的数据文件。
我们继续插入1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_ID BLOCK_ID BYTES
-------------------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536
DEMO_TABLE DEMO 8 1 17 65536
DEMO_TABLE DEMO 8 2 25 65536
DEMO_TABLE DEMO 8 3 33 65536
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 41 1769472 216 8
仍然是使用8号文件。继续插入数据。
SQL> select count(1) from demo_table;
COUNT(1)
----------
8000
已经插入了8000行(前面插入数据的过程略去)
再插入数据1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 129 1048576 128 8
可以看到,这时仍只是使用8号文件,6号文件一直未使用。
再插入数据1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8