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

本实验的上半部分请见: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


你可能感兴趣的:(数据文件,分配,写入顺序)