续前:http://bfc99.blog.51cto.com/265386/1359374
按实验计划,我们此时还要再增加一个自动扩展的数据文件,看看ORACLE是如何处理的。
SQL> alter tablespace demo add datafile '/oradata/orcl/demo04.dbf' size 4M autoextend on;
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 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
/oradata/orcl/demo04.dbf 10 DEMO4194304 512 AVAILABLE 10 YES 3.4360E+10 4194302 1 4128768 504 ONLINE
我们继续插入1万行数据,来观察ORACLE的处理。在观察前,我们可以先猜一下。而猜之前,我们先看一下各数据文件的空闲空间。
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
DEMO 10 9 4128768 504 10
如下所示,前3个数据文件的空闲空间均不足以容纳1个新的区(extent),所以,我们猜测会是在新创建的10号文件上分配。
实验一下。
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
DEMO 10 9 4128768 504 10
哎,10号文件的空闲空间并没有减少。再看看区块的分配情况。
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.
噢,和插入数据前一样,并没有新的区被分配,说明上一步分配的区的空间还能容纳下这1万行数据。为保险起见,我们再看一下各个数据文件的大小是否有变化。
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
/oradata/orcl/demo04.dbf 10 DEMO4194304 512 AVAILABLE 10 YES 3.4360E+10 4194302 1 4128768 504 ONLINE
嗯,没有。和插入数据前的状况是一样的。
继续插入数据。
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
DEMO 10 137 3080192 376 10
看,10号文件的空闲空间减少了约1M(正好是1个extent的大小)
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
DEMO_TABLE DEMO10 26 9 1048576 128
27 rows selected.
如上所示,可以进一步确定10号文件上被分配了一个区。
如果我们继续插入数据,由于另三个文件的空闲不足,所以,应该还是会在10号文件上分配。
试试。
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
DEMO 10 265 2031616 248 10
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
DEMO_TABLE DEMO10 26 9 1048576 128
DEMO_TABLE DEMO10 27 137 1048576 128
28 rows selected.
确实如此。再插入还是会在10号文件上分配。
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
DEMO 10 393 983040 120 10
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
DEMO_TABLE DEMO10 26 9 1048576 128
DEMO_TABLE DEMO10 27 137 1048576 128
DEMO_TABLE DEMO10 28 265 1048576 128
29 rows selected.
没错,就是这样。现在我们又得猜测一下了。因为4个文件的空闲空间都不够了,那么再插入数据,是会在6、8、10号三个可扩展的数据文件中的哪一个上面呢?
我猜应该是6号,因为哪果轮流分配的话,从上面的轮换次序看,也该轮到它了。
试试。
SQL> insert into demo_table select * from dba_objects where rownum<=10000;
10000 rows created.
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
DEMO_TABLE DEMO10 26 9 1048576 128
DEMO_TABLE DEMO10 27 137 1048576 128
DEMO_TABLE DEMO10 28 265 1048576 128
DEMO_TABLE DEMO 6 29 521 1048576 128
30 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 DEMO6291456 768 AVAILABLE6 YES 3.4360E+10 4194302 1 6225920 760 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
/oradata/orcl/demo04.dbf 10 DEMO4194304 512 AVAILABLE 10 YES 3.4360E+10 4194302 1 4128768 504 ONLINE
哈哈,我猜对了。就是6号文件。下一次一定是8号文件了。
SQL> insert into demo_table select * from dba_objects where rownum<=10000;
10000 rows created.
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
DEMO_TABLE DEMO10 26 9 1048576 128
DEMO_TABLE DEMO10 27 137 1048576 128
DEMO_TABLE DEMO10 28 265 1048576 128
DEMO_TABLE DEMO 6 29 521 1048576 128
DEMO_TABLE DEMO 8 30 521 1048576 128
31 rows selected.
不用说了,再下一次就是10号文件了。经验证也确实如此。为节省篇幅,这里就不贴实验过程了。
实验全部结束,我们该总结一下了。
我们先把在情景1的实验结论回顾一下;
1、当初始创建表空间后,ORACLE会首先向FILE_ID最大的数据文件中写入。
2、区的大小不是不变的,初始是每区8个块,但随后就增加到每区128个数据块。
3、数据文件中剩余的连续块若不够128个,即不够一个新区的需要的块数量时,空间是浪费的。
疑问:由于这个实验中的数据文件起始大小过小,非自动扩展的数据文件中已不能容纳一个新的区(128个数据块),所以,再新增加的区只能是写到新追加的数据文件或是对可扩展的数据文件进行扩展。那么,如果非自动扩展的数据文件可以容纳下一个新的区,情况会是什么样子呢?
为此,在下面的实验中,我们将初始文件的大小由2M,改为4M。
通过情景2的实验,不仅进一步验证了情景1实验的结论,而且,我们也解决了在上一实验中的疑问。所以,我们又得出了以下结论:
4、ORACLE会在空闲空间可以容纳下新的extent的数据文件中按次序轮流使用。
5、数据文件空闲空间的大小不影响分配的次序。
6、当所有数据文件的空闲空间均不足时,会对可扩展的数据文件进行扩展。