ITPub博客

首页 > 数据库 > Oracle > 一个表空间有多个数据文件,新增数据时的写入顺序和分配算法初探实验(下)

一个表空间有多个数据文件,新增数据时的写入顺序和分配算法初探实验(下)

Oracle 作者:lilingfeng1 时间:2016-12-15 17:13:21 0 删除 编辑
本实验的上半部分请见:http://blog.itpub.net/22207394/viewspace-1081775/

综上,可以得出以下几个观点:
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_ID BLOCK_ID      BYTES BLOCKS 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 AUT MAXBYTES  MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 4194304        512 AVAILABLE 6 YES 3.4360E+10    4194302       1    4128768    504 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 4194304        512 AVAILABLE 8 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_ID BLOCK_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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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 AUT MAXBYTES  MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 4194304        512 AVAILABLE 6 YES 3.4360E+10    4194302       1    4128768    504 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 4194304        512 AVAILABLE 8 YES 3.4360E+10    4194302       1    4128768    504 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 4194304        512 AVAILABLE 9 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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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 AUT MAXBYTES  MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 5242880        640 AVAILABLE 6 YES 3.4360E+10    4194302       1    5177344    632 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 4194304        512 AVAILABLE 8 YES 3.4360E+10    4194302       1    4128768    504 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 4194304        512 AVAILABLE 9 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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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 AUT MAXBYTES  MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 5242880        640 AVAILABLE 6 YES 3.4360E+10    4194302       1    5177344    632 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 5242880        640 AVAILABLE 8 YES 3.4360E+10    4194302       1    5177344    632 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 4194304        512 AVAILABLE 9 NO       0  0       0    4128768    504 ONLINE


确实如此。
到目前为止,我们发现ORACLE在选择数据文件时,是按照轮流分配的方式进行,当被分配到的文件的空闲空间不足时,会在其它空闲空间满足的数据文件间继续轮流分配。数据文件空闲空间的大小顺序并不会影响被选中的次序。


按实验计划,我们此时还要再增加一个自动扩展的数据文件,看看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 AUT MAXBYTES  MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 5242880        640 AVAILABLE 6 YES 3.4360E+10    4194302       1    5177344    632 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 5242880        640 AVAILABLE 8 YES 3.4360E+10    4194302       1    5177344    632 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 4194304        512 AVAILABLE 9 NO       0  0       0    4128768    504 ONLINE
/oradata/orcl/demo04.dbf       10 DEMO 4194304        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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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 AUT MAXBYTES  MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 5242880        640 AVAILABLE 6 YES 3.4360E+10    4194302       1    5177344    632 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 5242880        640 AVAILABLE 8 YES 3.4360E+10    4194302       1    5177344    632 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 4194304        512 AVAILABLE 9 NO       0  0       0    4128768    504 ONLINE
/oradata/orcl/demo04.dbf       10 DEMO 4194304        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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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     DEMO 10   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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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     DEMO 10   26       9    1048576   128
DEMO_TABLE     DEMO 10   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_ID BLOCK_ID      BYTES BLOCKS 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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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     DEMO 10   26       9    1048576   128
DEMO_TABLE     DEMO 10   27     137    1048576   128
DEMO_TABLE     DEMO 10   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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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     DEMO 10   26       9    1048576   128
DEMO_TABLE     DEMO 10   27     137    1048576   128
DEMO_TABLE     DEMO 10   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 AUT MAXBYTES  MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 6291456        768 AVAILABLE 6 YES 3.4360E+10    4194302       1    6225920    760 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 5242880        640 AVAILABLE 8 YES 3.4360E+10    4194302       1    5177344    632 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 4194304        512 AVAILABLE 9 NO       0  0       0    4128768    504 ONLINE
/oradata/orcl/demo04.dbf       10 DEMO 4194304        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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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_ID BLOCK_ID      BYTES BLOCKS
-------------------- ---------- ---------- ---------- ---------- ---------- ----------
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     DEMO 10   26       9    1048576   128
DEMO_TABLE     DEMO 10   27     137    1048576   128
DEMO_TABLE     DEMO 10   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、当所有数据文件的空闲空间均不足时,会对可扩展的数据文件进行扩展。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30192548/viewspace-2130714/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2015-04-05

  • 博文量
    51
  • 访问量
    38493