本实验的上半部分请见:http://bfc99.blog.51cto.com/265386/1359373
综上,可以得出以下几个观点:
1、当初始创建表空间后,ORACLE会首先向FILE_ID最大的数据文件中写入。
2、区的大小不是不变的,初始是每区8个块,但随后就增加到每区128个数据块。
3、数据文件中剩余的连续块若不够128个,即不够一个新区的需要的块数量时,空间是浪费的。
疑问:由于这个实验中的数据文件起始大小过小,非自动扩展的数据文件中已不能容纳一个新的区(128个数据块),所以,再新增加的区只能是写到新追加的数据文件或是对可扩展的数据文件进行扩展。那么,如果非自动扩展的数据文件可以容纳下一个新的区,情况会是什么样子呢?
为此,在下面的实验中,我们将初始文件的大小由2M,改为4M。
同时,为了保证实验的一致性,我们将当前的表空间及其内容和数据文件全部删除。
SQL> drop tablespace demo including contents and datafiles;
Tablespace dropped.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
no rows selected
情景2:创建两个自动扩展的的数据文件,创建测试用表,向测试用表中插入数据,观察组成两个数据文件空间的使用情况。然后增加一个同样大小的非自动扩展的数据文件后,继续向测试用表中插入数据,观察这三个数据文件的空间使用情况。再增加一个同样大小的自动扩展的数据文件后,继续向测试用表中插入数据,并观察四个数据文件的空间使用情况。
SQL> create tablespace demo datafile '/oradata/orcl/demo01.dbf' size 4M autoextend on,'/oradata/orcl/demo02.dbf' size 4M autoextend on;
Tablespace created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 4128768 504 6
DEMO 8 9 4128768 504 8
SQL> select * from dba_data_files where tablespace_name='DEMO';
FILE_NAME FILE_ID TABLESPACE BYTES BLOCKS STATUS RELATIVE_FNO AUTMAXBYTES MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf6 DEMO4194304 512 AVAILABLE6 YES 3.4360E+10 4194302 1 4128768 504 ONLINE
/oradata/orcl/demo02.dbf8 DEMO4194304 512 AVAILABLE8 YES 3.4360E+10 4194302 1 4128768 504 ONLINE
查看当前表空间的管理方式为本地自动管理。
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_IDBLOCK_ID BYTES
-------------------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536
DEMO_TABLE DEMO 8 1 17 65536
为加快实验进程,我们不每1000行插入一次,根据前面的经验,我们插入9000行,使当前表拥有1万行记录。
SQL> insert into demo_table select * from dba_objects where rownum<=9000;
9000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 3080192 376 6
DEMO 8 137 3080192 376 8
我们发现已经开始使用6号文件了。
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes,blocks from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 6 16 9 1048576 128
DEMO_TABLE DEMO 8 0 9 65536 8
DEMO_TABLE DEMO 8 1 17 65536 8
DEMO_TABLE DEMO 8 2 25 65536 8
DEMO_TABLE DEMO 8 3 33 65536 8
DEMO_TABLE DEMO 8 4 41 65536 8
DEMO_TABLE DEMO 8 5 49 65536 8
DEMO_TABLE DEMO 8 6 57 65536 8
DEMO_TABLE DEMO 8 7 65 65536 8
DEMO_TABLE DEMO 8 8 73 65536 8
DEMO_TABLE DEMO 8 9 81 65536 8
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 10 89 65536 8
DEMO_TABLE DEMO 8 11 97 65536 8
DEMO_TABLE DEMO 8 12 105 65536 8
DEMO_TABLE DEMO 8 13 113 65536 8
DEMO_TABLE DEMO 8 14 121 65536 8
DEMO_TABLE DEMO 8 15 129 65536 8
17 rows selected.
和前一个实验类似,当分配了16个8个数据块大小的区之后,再新增的区,就变为了128个数据块大小。而且,在这个实验中,因为我们增大了初始数据文件的大小至4M,虽然8号文件剩余的空间还可以容纳下新的区,但ORACLE仍然将新区放在了6号文件上。
现在我们直接再插入数据1万行,这时又会产生一个新区,看看这个新区会分配给哪个文件。
SQL> insert into demo_table select * from dba_objects where rownum<=10000;
10000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 3080192 376 6
DEMO 8 265 2031616 248 8
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes,blocks from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 6 16 9 1048576 128
DEMO_TABLE DEMO 8 0 9 65536 8
DEMO_TABLE DEMO 8 1 17 65536 8
DEMO_TABLE DEMO 8 2 25 65536 8
DEMO_TABLE DEMO 8 3 33 65536 8
DEMO_TABLE DEMO 8 4 41 65536 8
DEMO_TABLE DEMO 8 5 49 65536 8
DEMO_TABLE DEMO 8 6 57 65536 8
DEMO_TABLE DEMO 8 7 65 65536 8
DEMO_TABLE DEMO 8 8 73 65536 8
DEMO_TABLE DEMO 8 9 81 65536 8
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 10 89 65536 8
DEMO_TABLE DEMO 8 11 97 65536 8
DEMO_TABLE DEMO 8 12 105 65536 8
DEMO_TABLE DEMO 8 13 113 65536 8
DEMO_TABLE DEMO 8 14 121 65536 8
DEMO_TABLE DEMO 8 15 129 65536 8
DEMO_TABLE DEMO 8 17 137 1048576 128
18 rows selected.
如上所示,新的区被分配在了8号文件上。似乎ORACLE在分配新区时,会轮流向2个文件中写入。如果这个假设成立,那么如果我们再插入数据1万行,就应该写到6号文件上了。检验一下。
SQL> insert into demo_table select * from dba_objects where rownum<=10000;
10000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 265 2031616 248 6
DEMO 8 265 2031616 248 8
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes,blocks from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 6 16 9 1048576 128
DEMO_TABLE DEMO 6 18 137 1048576 128
DEMO_TABLE DEMO 8 0 9 65536 8
DEMO_TABLE DEMO 8 1 17 65536 8
DEMO_TABLE DEMO 8 2 25 65536 8
DEMO_TABLE DEMO 8 3 33 65536 8
DEMO_TABLE DEMO 8 4 41 65536 8
DEMO_TABLE DEMO 8 5 49 65536 8
DEMO_TABLE DEMO 8 6 57 65536 8
DEMO_TABLE DEMO 8 7 65 65536 8
DEMO_TABLE DEMO 8 8 73 65536 8
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 9 81 65536 8
DEMO_TABLE DEMO 8 10 89 65536 8
DEMO_TABLE DEMO 8 11 97 65536 8
DEMO_TABLE DEMO 8 12 105 65536 8
DEMO_TABLE DEMO 8 13 113 65536 8
DEMO_TABLE DEMO 8 14 121 65536 8
DEMO_TABLE DEMO 8 15 129 65536 8
DEMO_TABLE DEMO 8 17 137 1048576 128
19 rows selected.
果然。
那么我们现在再增加一个非自动扩展的数据文件,看看ORACLE会如何分配。
SQL> alter tablespace demo add datafile '/oradata/orcl/demo03.dbf' size 4M autoextend off;
Tablespace altered.
SQL> select * from dba_data_files where tablespace_name='DEMO';
FILE_NAME FILE_ID TABLESPACE BYTES BLOCKS STATUS RELATIVE_FNO AUTMAXBYTES MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf6 DEMO4194304 512 AVAILABLE6 YES 3.4360E+10 4194302 1 4128768 504 ONLINE
/oradata/orcl/demo02.dbf8 DEMO4194304 512 AVAILABLE8 YES 3.4360E+10 4194302 1 4128768 504 ONLINE
/oradata/orcl/demo03.dbf9 DEMO4194304 512 AVAILABLE9 NO 0 0 0 4128768 504 ONLINE
我们再插入数据1万行。看看ORACLE会如何处理。
SQL> insert into demo_table select * from dba_objects where rownum<=10000;
10000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 265 2031616 248 6
DEMO 8 265 2031616 248 8
DEMO 9 9 4128768 504 9
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes,blocks from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 6 16 9 1048576 128
DEMO_TABLE DEMO 6 18 137 1048576 128
DEMO_TABLE DEMO 8 0 9 65536 8
DEMO_TABLE DEMO 8 1 17 65536 8
DEMO_TABLE DEMO 8 2 25 65536 8
DEMO_TABLE DEMO 8 3 33 65536 8
DEMO_TABLE DEMO 8 4 41 65536 8
DEMO_TABLE DEMO 8 5 49 65536 8
DEMO_TABLE DEMO 8 6 57 65536 8
DEMO_TABLE DEMO 8 7 65 65536 8
DEMO_TABLE DEMO 8 8 73 65536 8
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 9 81 65536 8
DEMO_TABLE DEMO 8 10 89 65536 8
DEMO_TABLE DEMO 8 11 97 65536 8
DEMO_TABLE DEMO 8 12 105 65536 8
DEMO_TABLE DEMO 8 13 113 65536 8
DEMO_TABLE DEMO 8 14 121 65536 8
DEMO_TABLE DEMO 8 15 129 65536 8
DEMO_TABLE DEMO 8 17 137 1048576 128
19 rows selected.
看来上一次分配的区还能容纳下这1万行数据。
我们继续插入数据,因为已临近产生新区的临界点。这次,我们只插入数据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_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 265 2031616 248 6
DEMO 8 393 983040 120 8
DEMO 9 9 4128768 504 9
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes,blocks from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 6 16 9 1048576 128
DEMO_TABLE DEMO 6 18 137 1048576 128
DEMO_TABLE DEMO 8 0 9 65536 8
DEMO_TABLE DEMO 8 1 17 65536 8
DEMO_TABLE DEMO 8 2 25 65536 8
DEMO_TABLE DEMO 8 3 33 65536 8
DEMO_TABLE DEMO 8 4 41 65536 8
DEMO_TABLE DEMO 8 5 49 65536 8
DEMO_TABLE DEMO 8 6 57 65536 8
DEMO_TABLE DEMO 8 7 65 65536 8
DEMO_TABLE DEMO 8 8 73 65536 8
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 9 81 65536 8
DEMO_TABLE DEMO 8 10 89 65536 8
DEMO_TABLE DEMO 8 11 97 65536 8
DEMO_TABLE DEMO 8 12 105 65536 8
DEMO_TABLE DEMO 8 13 113 65536 8
DEMO_TABLE DEMO 8 14 121 65536 8
DEMO_TABLE DEMO 8 15 129 65536 8
DEMO_TABLE DEMO 8 17 137 1048576 128
DEMO_TABLE DEMO 8 19 265 1048576 128
20 rows selected.
ORACLE把新区分配到了8号文件,并没有使用新添加的数据文件。我们再插入1万行数据试试。
SQL> insert into demo_table select * from dba_objects where rownum<=10000;
10000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 265 2031616 248 6
DEMO 8 393 983040 120 8
DEMO 9 137 3080192 376 9
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes,blocks from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 6 16 9 1048576 128
DEMO_TABLE DEMO 6 18 137 1048576 128
DEMO_TABLE DEMO 8 0 9 65536 8
DEMO_TABLE DEMO 8 1 17 65536 8
DEMO_TABLE DEMO 8 2 25 65536 8
DEMO_TABLE DEMO 8 3 33 65536 8
DEMO_TABLE DEMO 8 4 41 65536 8
DEMO_TABLE DEMO 8 5 49 65536 8
DEMO_TABLE DEMO 8 6 57 65536 8
DEMO_TABLE DEMO 8 7 65 65536 8
DEMO_TABLE DEMO 8 8 73 65536 8
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 9 81 65536 8
DEMO_TABLE DEMO 8 10 89 65536 8
DEMO_TABLE DEMO 8 11 97 65536 8
DEMO_TABLE DEMO 8 12 105 65536 8
DEMO_TABLE DEMO 8 13 113 65536 8
DEMO_TABLE DEMO 8 14 121 65536 8
DEMO_TABLE DEMO 8 15 129 65536 8
DEMO_TABLE DEMO 8 17 137 1048576 128
DEMO_TABLE DEMO 8 19 265 1048576 128
DEMO_TABLE DEMO 9 20 9 1048576 128
21 rows selected.
如上所示,这次分配到了9号文件。再插入1万行数据,是会写到9号文件呢,还是6号文件?
SQL> insert into demo_table select * from dba_objects where rownum<=10000;
10000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 393 983040 120 6
DEMO 8 393 983040 120 8
DEMO 9 137 3080192 376 9
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes,blocks from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 6 16 9 1048576 128
DEMO_TABLE DEMO 6 18 137 1048576 128
DEMO_TABLE DEMO 6 21 265 1048576 128
DEMO_TABLE DEMO 8 0 9 65536 8
DEMO_TABLE DEMO 8 1 17 65536 8
DEMO_TABLE DEMO 8 2 25 65536 8
DEMO_TABLE DEMO 8 3 33 65536 8
DEMO_TABLE DEMO 8 4 41 65536 8
DEMO_TABLE DEMO 8 5 49 65536 8
DEMO_TABLE DEMO 8 6 57 65536 8
DEMO_TABLE DEMO 8 7 65 65536 8
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 8 73 65536 8
DEMO_TABLE DEMO 8 9 81 65536 8
DEMO_TABLE DEMO 8 10 89 65536 8
DEMO_TABLE DEMO 8 11 97 65536 8
DEMO_TABLE DEMO 8 12 105 65536 8
DEMO_TABLE DEMO 8 13 113 65536 8
DEMO_TABLE DEMO 8 14 121 65536 8
DEMO_TABLE DEMO 8 15 129 65536 8
DEMO_TABLE DEMO 8 17 137 1048576 128
DEMO_TABLE DEMO 8 19 265 1048576 128
DEMO_TABLE DEMO 9 20 9 1048576 128
22 rows selected.
写到了6号文件。也就是说,到这个时候,ORACLE似乎是向各个数据文件中轮流分配新区。
如果这个假设成立,我们如果再插入1万行数据,应该是写到8号文件了。
SQL> insert into demo_table select * from dba_objects where rownum<=10000;
10000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 393 983040 120 6
DEMO 8 393 983040 120 8
DEMO 9 265 2031616 248 9
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes,blocks from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 6 16 9 1048576 128
DEMO_TABLE DEMO 6 18 137 1048576 128
DEMO_TABLE DEMO 6 21 265 1048576 128
DEMO_TABLE DEMO 8 0 9 65536 8
DEMO_TABLE DEMO 8 1 17 65536 8
DEMO_TABLE DEMO 8 2 25 65536 8
DEMO_TABLE DEMO 8 3 33 65536 8
DEMO_TABLE DEMO 8 4 41 65536 8
DEMO_TABLE DEMO 8 5 49 65536 8
DEMO_TABLE DEMO 8 6 57 65536 8
DEMO_TABLE DEMO 8 7 65 65536 8
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 8 73 65536 8
DEMO_TABLE DEMO 8 9 81 65536 8
DEMO_TABLE DEMO 8 10 89 65536 8
DEMO_TABLE DEMO 8 11 97 65536 8
DEMO_TABLE DEMO 8 12 105 65536 8
DEMO_TABLE DEMO 8 13 113 65536 8
DEMO_TABLE DEMO 8 14 121 65536 8
DEMO_TABLE DEMO 8 15 129 65536 8
DEMO_TABLE DEMO 8 17 137 1048576 128
DEMO_TABLE DEMO 8 19 265 1048576 128
DEMO_TABLE DEMO 9 20 9 1048576 128
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 9 22 137 1048576 128
23 rows selected.
假设失败,实际写到了新增加的9号数据文件上了。并没有写到我们预测的8号文件上。
那如果我们再插入1万行,是会在有较多空闲空间的9号文件上分配,还是轮回到其它文件上呢。
SQL> insert into demo_table select * from dba_objects where rownum<=10000;
10000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 393 983040 120 6
DEMO 8 393 983040 120 8
DEMO 9 393 983040 120 9
仍然写到了9号文件。看来似乎和数据文件的空闲空间相关,哪个文件的空闲空间大,就优先分配给谁。
为了方便查看这种分配的过程,我把查看区块分配情况的SQL语的排序条件改变了一下,首先按区ID来排序。如下所示:
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes,blocks from dba_extents where tablespace_name='DEMO' order by extent_id,file_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536 8
DEMO_TABLE DEMO 8 1 17 65536 8
DEMO_TABLE DEMO 8 2 25 65536 8
DEMO_TABLE DEMO 8 3 33 65536 8
DEMO_TABLE DEMO 8 4 41 65536 8
DEMO_TABLE DEMO 8 5 49 65536 8
DEMO_TABLE DEMO 8 6 57 65536 8
DEMO_TABLE DEMO 8 7 65 65536 8
DEMO_TABLE DEMO 8 8 73 65536 8
DEMO_TABLE DEMO 8 9 81 65536 8
DEMO_TABLE DEMO 8 10 89 65536 8
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 11 97 65536 8
DEMO_TABLE DEMO 8 12 105 65536 8
DEMO_TABLE DEMO 8 13 113 65536 8
DEMO_TABLE DEMO 8 14 121 65536 8
DEMO_TABLE DEMO 8 15 129 65536 8
DEMO_TABLE DEMO 6 16 9 1048576 128
DEMO_TABLE DEMO 8 17 137 1048576 128
DEMO_TABLE DEMO 6 18 137 1048576 128
DEMO_TABLE DEMO 8 19 265 1048576 128
DEMO_TABLE DEMO 9 20 9 1048576 128
DEMO_TABLE DEMO 6 21 265 1048576 128
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 9 22 137 1048576 128
DEMO_TABLE DEMO 9 23 265 1048576 128
24 rows selected.
继续验证,我们再插入1万行数据,现在三个文件的空闲空间已经一样了,这回该轮到哪个文件了呢?
SQL> insert into demo_table select * from dba_objects where rownum<=10000;
10000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 521 983040 120 6
DEMO 8 393 983040 120 8
DEMO 9 393 983040 120 9
三个文件的空闲空间都没有减少。奇怪?看一看区块的分配情况。
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes,blocks from dba_extents where tablespace_name='DEMO' order by extent_id,file_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536 8
DEMO_TABLE DEMO 8 1 17 65536 8
DEMO_TABLE DEMO 8 2 25 65536 8
DEMO_TABLE DEMO 8 3 33 65536 8
DEMO_TABLE DEMO 8 4 41 65536 8
DEMO_TABLE DEMO 8 5 49 65536 8
DEMO_TABLE DEMO 8 6 57 65536 8
DEMO_TABLE DEMO 8 7 65 65536 8
DEMO_TABLE DEMO 8 8 73 65536 8
DEMO_TABLE DEMO 8 9 81 65536 8
DEMO_TABLE DEMO 8 10 89 65536 8
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 11 97 65536 8
DEMO_TABLE DEMO 8 12 105 65536 8
DEMO_TABLE DEMO 8 13 113 65536 8
DEMO_TABLE DEMO 8 14 121 65536 8
DEMO_TABLE DEMO 8 15 129 65536 8
DEMO_TABLE DEMO 6 16 9 1048576 128
DEMO_TABLE DEMO 8 17 137 1048576 128
DEMO_TABLE DEMO 6 18 137 1048576 128
DEMO_TABLE DEMO 8 19 265 1048576 128
DEMO_TABLE DEMO 9 20 9 1048576 128
DEMO_TABLE DEMO 6 21 265 1048576 128
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 9 22 137 1048576 128
DEMO_TABLE DEMO 9 23 265 1048576 128
DEMO_TABLE DEMO 6 24 393 1048576 128
25 rows selected.
分配到了6号文件。6号文件空闲空间并没有减少啊。
想一想,噢,明白了。三个文件任一个文件的剩余空间都已经不够容纳1个区的空间了(128个8K的数据块,共1024K)。那一定在6号文件上发生了空间扩展。
验证一下。
SQL> select * from dba_data_files where tablespace_name='DEMO';
FILE_NAME FILE_ID TABLESPACE BYTES BLOCKS STATUS RELATIVE_FNO AUTMAXBYTES MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf6 DEMO5242880 640 AVAILABLE6 YES 3.4360E+10 4194302 1 5177344 632 ONLINE
/oradata/orcl/demo02.dbf8 DEMO4194304 512 AVAILABLE8 YES 3.4360E+10 4194302 1 4128768 504 ONLINE
/oradata/orcl/demo03.dbf9 DEMO4194304 512 AVAILABLE9 NO 0 0 0 4128768 504 ONLINE
确定,6号文件的大小已经变为5242880了,已经不是初始时的4194304了。扩展的大小正好是1个区的大小。
根据我们前面推测的轮流分配的机制,如果我们再增加1万行,就该轮到用8号文件了,而且8号文件也会发生空间扩展,扩展的大小也应该是目前1个区的大小,即1024K。
验证之。
SQL> insert into demo_table select * from dba_objects where rownum<=10000;
10000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_IDBLOCK_ID BYTESBLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 521 983040 120 6
DEMO 8 521 983040 120 8
DEMO 9 393 983040 120 9
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes,blocks from dba_extents where tablespace_name='DEMO' order by extent_id,file_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536 8
DEMO_TABLE DEMO 8 1 17 65536 8
DEMO_TABLE DEMO 8 2 25 65536 8
DEMO_TABLE DEMO 8 3 33 65536 8
DEMO_TABLE DEMO 8 4 41 65536 8
DEMO_TABLE DEMO 8 5 49 65536 8
DEMO_TABLE DEMO 8 6 57 65536 8
DEMO_TABLE DEMO 8 7 65 65536 8
DEMO_TABLE DEMO 8 8 73 65536 8
DEMO_TABLE DEMO 8 9 81 65536 8
DEMO_TABLE DEMO 8 10 89 65536 8
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 11 97 65536 8
DEMO_TABLE DEMO 8 12 105 65536 8
DEMO_TABLE DEMO 8 13 113 65536 8
DEMO_TABLE DEMO 8 14 121 65536 8
DEMO_TABLE DEMO 8 15 129 65536 8
DEMO_TABLE DEMO 6 16 9 1048576 128
DEMO_TABLE DEMO 8 17 137 1048576 128
DEMO_TABLE DEMO 6 18 137 1048576 128
DEMO_TABLE DEMO 8 19 265 1048576 128
DEMO_TABLE DEMO 9 20 9 1048576 128
DEMO_TABLE DEMO 6 21 265 1048576 128
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_IDBLOCK_ID BYTESBLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 9 22 137 1048576 128
DEMO_TABLE DEMO 9 23 265 1048576 128
DEMO_TABLE DEMO 6 24 393 1048576 128
DEMO_TABLE DEMO 8 25 393 1048576 128
26 rows selected.
SQL> select * from dba_data_files where tablespace_name='DEMO';
FILE_NAME FILE_ID TABLESPACE BYTES BLOCKS STATUS RELATIVE_FNO AUTMAXBYTES MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf6 DEMO5242880 640 AVAILABLE6 YES 3.4360E+10 4194302 1 5177344 632 ONLINE
/oradata/orcl/demo02.dbf8 DEMO5242880 640 AVAILABLE8 YES 3.4360E+10 4194302 1 5177344 632 ONLINE
/oradata/orcl/demo03.dbf9 DEMO4194304 512 AVAILABLE9 NO 0 0 0 4128768 504 ONLINE
确实如此。
到目前为止,我们发现ORACLE在选择数据文件时,是按照轮流分配的方式进行,当被分配到的文件的空闲空间不足时,会在其它空闲空间满足的数据文件间继续轮流分配。数据文件空闲空间的大小顺序并不会影响被选中的次序。
受篇幅限制,后续部分请见:http://bfc99.blog.51cto.com/265386/1359376