一個表空間有多個資料檔案,新增資料時的寫入順序和分配演算法初探實驗(上)
當一個表空間中有多個資料檔案,新增資料時,會寫到哪個資料檔案上呢?有人說是由ORACLE隨機控制,即是根據一個分配演算法計算後,將新增的資料寫入到指定的一個或多個資料檔案上。但這個演算法是什麼,一直也沒有找到相關的說明。下面的這個實驗,算是對這個演算法的一個初步探尋吧,供大家參考。
實驗設想:
所有實驗在ORACLE DATABASE 10.2.0.5上完成,作業系統為Linux localhost.localdomain 2.6.18-194.el5 。建立的表空間均為本地自動管理。
情景1:建立兩個非自動擴充套件的的資料檔案,建立測試用表,向測試用表中插入資料,觀察這兩個資料檔案的空間使用情況。然後增加一個同樣大小的自動擴充套件的資料檔案後,繼續向測試用表中插入資料,觀察這三個資料檔案的空間使用情況。再增加一個同樣大小的非自動擴充套件的資料檔案後,繼續向測試用表中插入資料,並觀察四個資料檔案的空間使用情況。
SQL> create tablespace demo datafile '/oradata/orcl/demo01.dbf' size 2M autoextend off,'/oradata/orcl/demo02.dbf' size 2M autoextend off;
Tablespace created.
SQL> select * from dba_data_files where tablespace_name='DEMO';
FILE_NAME FILE_ID TABLESPACE BYTES BLOCKS STATUS RELATIVE_FNO AUT MAXBYTES MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 2097152 256 AVAILABLE 6 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 2097152 256 AVAILABLE 8 NO 0 0 0 2031616 248 ONLINE
檢查DEMO表空間的管理方式,確認為本地自動管理。
SQL> select tablespace_name,block_size,initial_extent,next_extent,min_extents,max_extents,extent_management,allocation_type from dba_tablespaces where tablespace_name='DEMO';
TABLESPACE BLOCK_SIZE INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS EXTENT_MAN ALLOCATIO
---------- ---------- -------------- ----------- ----------- ----------- ---------- ---------
DEMO 8192 65536 1 2147483645 LOCAL SYSTEM
建立測試用表,並插入1000行記錄
SQL> create table demo_table tablespace demo as select * from dba_objects where 1=2;
Table created.
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
檢視當前空間使用情況
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_ID BLOCK_ID BYTES
-------------------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536
DEMO_TABLE DEMO 8 1 17 65536
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 25 1900544 232 8
如上所示,1000行記當佔用了兩個區,共16個資料塊,每個區由8個資料塊組成,共佔用了16個資料塊。每個資料塊8K,共佔用了128K的空間。但這128K的空間全部來自於FILE_ID為8的資料檔案。
我們繼續插入1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_ID BLOCK_ID BYTES
-------------------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536
DEMO_TABLE DEMO 8 1 17 65536
DEMO_TABLE DEMO 8 2 25 65536
DEMO_TABLE DEMO 8 3 33 65536
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 41 1769472 216 8
仍然是使用8號檔案。繼續插入資料。
SQL> select count(1) from demo_table;
COUNT(1)
----------
8000
已經插入了8000行(前面插入資料的過程略去)
再插入資料1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 129 1048576 128 8
可以看到,這時仍只是使用8號檔案,6號檔案一直未使用。
再插入資料1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
變化了,開始使用6號檔案了,而且一下子就用了128個資料塊,並且,兩個資料檔案目前的可用資料塊數量是相等的。或者說,兩個檔案的可用空間是相同的。
那我們看一下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.
如上所示,6號檔案上只使用了一個extent(區ID為16),但這個區總共佔用了128個資料塊。
我們再插入資料1000行看看。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
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.
資料檔案上的可用空間沒有變化,區和塊的使用上,也和插入前是一樣的。說明新插入的資料仍然是在向6號檔案中寫入(寫入到上次分配的128個資料塊中的空閒塊中)。
我們繼續插入資料,看看6號檔案分配的這128個資料塊用滿後會是什麼情況。
SQL> select count(1) from demo_table;
COUNT(1)
----------
19000
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
insert into demo_table select * from dba_objects where rownum<=1000
*
ERROR at line 1:
ORA-01653: unable to extend table SYS.DEMO_TABLE by 128 in tablespace DEMO
報錯了,提示不能為表DEMO_TABLE以128個資料塊來擴充套件表空間DEMO了。
但實際上,兩個資料檔案中空閒的資料塊合計有240(120+120)個。
我們再看看此時區和塊的使用情況。
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.
和前面沒有區別和變化。
現在追加一個可自動擴充套件的資料檔案到DEMO表空間。
SQL> alter tablespace demo add datafile '/oradata/orcl/demo03.dbf' size 2M 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 2097152 256 AVAILABLE 6 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 2097152 256 AVAILABLE 8 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 2097152 256 AVAILABLE 9 YES 3.4360E+10 4194302 1 2031616 248 ONLINE
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 9 2031616 248 9
繼續向DEMO_TABLE中插入資料1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 137 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 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 9 17 9 1048576 128
18 rows selected.
如上所示,ORACLE直接在新增加的檔案上佔用了128個資料塊。
下面我們試試插入1萬行,把這128個資料塊佔滿,需要再分配新的區時,情況是什麼樣子。
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 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 265 983040 120 9
SQL> select * from dba_data_files where tablespace_name='DEMO';
FILE_NAME FILE_ID TABLESPACE BYTES BLOCKS STATUS RELATIVE_FNO AUT MAXBYTES MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 2097152 256 AVAILABLE 6 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 2097152 256 AVAILABLE 8 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 3145728 384 AVAILABLE 9 YES 3.4360E+10 4194302 1 3080192 376 ONLINE
如上,可自動擴充套件的資料檔案產生了空間擴充套件。
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 9 17 9 1048576 128
DEMO_TABLE DEMO 9 18 137 1048576 128
19 rows selected.
新分配的區被寫在了檔案9上。
我們現在按計劃,再新增一個非自動擴充套件的資料檔案,看看新分配的區會寫到可擴充套件的檔案上,還是這個新新增的不可擴充套件的新資料檔案上。
SQL> alter tablespace demo add datafile '/oradata/orcl/demo04.dbf' size 2M 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 2097152 256 AVAILABLE 6 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 2097152 256 AVAILABLE 8 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 3145728 384 AVAILABLE 9 YES 3.4360E+10 4194302 1 3080192 376 ONLINE
/oradata/orcl/demo04.dbf 10 DEMO 2097152 256 AVAILABLE 10 NO 0 0 0 2031616 248 ONLINE
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 265 983040 120 9
DEMO 10 9 2031616 248 10
SQL> select count(*) from demo_table;
COUNT(*)
----------
31000
現在表中有31000行,根據我們前面實驗的經驗,差不多128個資料塊可以存放10000行記錄。為了加快實驗速度,我們直接把記錄增加到4萬行。
繼續向測試表中插入資料9000行。
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 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 265 983040 120 9
DEMO 10 9 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 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 9 17 9 1048576 128
DEMO_TABLE DEMO 9 18 137 1048576 128
19 rows selected.
SQL> select count(*) from demo_table;
COUNT(*)
----------
40000
如上所示,這時並未發生新的區的分配。如果這裡再插入資料1000行,就會發生新的區的分配了。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 265 983040 120 9
DEMO 10 137 983040 120 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 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 9 17 9 1048576 128
DEMO_TABLE DEMO 9 18 137 1048576 128
DEMO_TABLE DEMO 10 19 9 1048576 128
20 rows selected.
如上所示,在10號檔案上,分配了一個新區,新區大小128個資料塊。
綜上,可以得出以下幾個觀點:
1、當初始建立表空間後,ORACLE會首先向FILE_ID最大的資料檔案中寫入。
2、區的大小不是不變的,初始是每區8個塊,但隨後就增加到每區128個資料塊。
3、資料檔案中剩餘的連續塊若不夠128個,即不夠一個新區的需要的塊數量時,空間是浪費的。
疑問:由於這個實驗中的資料檔案起始大小過小,非自動擴充套件的資料檔案中已不能容納一個新的區(128個資料塊),所以,再新增加的區只能是寫到新追加的資料檔案或是對可擴充套件的資料檔案進行擴充套件。那麼,如果非自動擴充套件的資料檔案可以容納下一個新的區,情況會是什麼樣子呢?
為此,在下面的實驗中,我們將初始檔案的大小由2M,改為4M。
同時,為了保證實驗的一致性,我們將當前的表空間及其內容和資料檔案全部刪除。
本實驗的後半部分請見 http://blog.itpub.net/22207394/viewspace-1081774/
實驗設想:
所有實驗在ORACLE DATABASE 10.2.0.5上完成,作業系統為Linux localhost.localdomain 2.6.18-194.el5 。建立的表空間均為本地自動管理。
情景1:建立兩個非自動擴充套件的的資料檔案,建立測試用表,向測試用表中插入資料,觀察這兩個資料檔案的空間使用情況。然後增加一個同樣大小的自動擴充套件的資料檔案後,繼續向測試用表中插入資料,觀察這三個資料檔案的空間使用情況。再增加一個同樣大小的非自動擴充套件的資料檔案後,繼續向測試用表中插入資料,並觀察四個資料檔案的空間使用情況。
SQL> create tablespace demo datafile '/oradata/orcl/demo01.dbf' size 2M autoextend off,'/oradata/orcl/demo02.dbf' size 2M autoextend off;
Tablespace created.
SQL> select * from dba_data_files where tablespace_name='DEMO';
FILE_NAME FILE_ID TABLESPACE BYTES BLOCKS STATUS RELATIVE_FNO AUT MAXBYTES MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 2097152 256 AVAILABLE 6 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 2097152 256 AVAILABLE 8 NO 0 0 0 2031616 248 ONLINE
檢查DEMO表空間的管理方式,確認為本地自動管理。
SQL> select tablespace_name,block_size,initial_extent,next_extent,min_extents,max_extents,extent_management,allocation_type from dba_tablespaces where tablespace_name='DEMO';
TABLESPACE BLOCK_SIZE INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS EXTENT_MAN ALLOCATIO
---------- ---------- -------------- ----------- ----------- ----------- ---------- ---------
DEMO 8192 65536 1 2147483645 LOCAL SYSTEM
建立測試用表,並插入1000行記錄
SQL> create table demo_table tablespace demo as select * from dba_objects where 1=2;
Table created.
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
檢視當前空間使用情況
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_ID BLOCK_ID BYTES
-------------------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536
DEMO_TABLE DEMO 8 1 17 65536
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 25 1900544 232 8
如上所示,1000行記當佔用了兩個區,共16個資料塊,每個區由8個資料塊組成,共佔用了16個資料塊。每個資料塊8K,共佔用了128K的空間。但這128K的空間全部來自於FILE_ID為8的資料檔案。
我們繼續插入1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select segment_name,tablespace_name,file_id,extent_id,block_id,bytes from dba_extents where tablespace_name='DEMO' order by file_id,extent_id,block_id;
SEGMENT_NAME TABLESPACE FILE_ID EXTENT_ID BLOCK_ID BYTES
-------------------- ---------- ---------- ---------- ---------- ----------
DEMO_TABLE DEMO 8 0 9 65536
DEMO_TABLE DEMO 8 1 17 65536
DEMO_TABLE DEMO 8 2 25 65536
DEMO_TABLE DEMO 8 3 33 65536
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 41 1769472 216 8
仍然是使用8號檔案。繼續插入資料。
SQL> select count(1) from demo_table;
COUNT(1)
----------
8000
已經插入了8000行(前面插入資料的過程略去)
再插入資料1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 9 2031616 248 6
DEMO 8 129 1048576 128 8
可以看到,這時仍只是使用8號檔案,6號檔案一直未使用。
再插入資料1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
變化了,開始使用6號檔案了,而且一下子就用了128個資料塊,並且,兩個資料檔案目前的可用資料塊數量是相等的。或者說,兩個檔案的可用空間是相同的。
那我們看一下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.
如上所示,6號檔案上只使用了一個extent(區ID為16),但這個區總共佔用了128個資料塊。
我們再插入資料1000行看看。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
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.
資料檔案上的可用空間沒有變化,區和塊的使用上,也和插入前是一樣的。說明新插入的資料仍然是在向6號檔案中寫入(寫入到上次分配的128個資料塊中的空閒塊中)。
我們繼續插入資料,看看6號檔案分配的這128個資料塊用滿後會是什麼情況。
SQL> select count(1) from demo_table;
COUNT(1)
----------
19000
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
insert into demo_table select * from dba_objects where rownum<=1000
*
ERROR at line 1:
ORA-01653: unable to extend table SYS.DEMO_TABLE by 128 in tablespace DEMO
報錯了,提示不能為表DEMO_TABLE以128個資料塊來擴充套件表空間DEMO了。
但實際上,兩個資料檔案中空閒的資料塊合計有240(120+120)個。
我們再看看此時區和塊的使用情況。
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.
和前面沒有區別和變化。
現在追加一個可自動擴充套件的資料檔案到DEMO表空間。
SQL> alter tablespace demo add datafile '/oradata/orcl/demo03.dbf' size 2M 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 2097152 256 AVAILABLE 6 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 2097152 256 AVAILABLE 8 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 2097152 256 AVAILABLE 9 YES 3.4360E+10 4194302 1 2031616 248 ONLINE
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 9 2031616 248 9
繼續向DEMO_TABLE中插入資料1000行。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 137 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 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 9 17 9 1048576 128
18 rows selected.
如上所示,ORACLE直接在新增加的檔案上佔用了128個資料塊。
下面我們試試插入1萬行,把這128個資料塊佔滿,需要再分配新的區時,情況是什麼樣子。
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 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 265 983040 120 9
SQL> select * from dba_data_files where tablespace_name='DEMO';
FILE_NAME FILE_ID TABLESPACE BYTES BLOCKS STATUS RELATIVE_FNO AUT MAXBYTES MAXBLOCKS INCREMENT_BY USER_BYTES USER_BLOCKS ONLINE_
------------------------------ ---------- ---------- ---------- ---------- --------- ------------ --- ---------- ---------- ------------ ---------- ----------- -------
/oradata/orcl/demo01.dbf 6 DEMO 2097152 256 AVAILABLE 6 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 2097152 256 AVAILABLE 8 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 3145728 384 AVAILABLE 9 YES 3.4360E+10 4194302 1 3080192 376 ONLINE
如上,可自動擴充套件的資料檔案產生了空間擴充套件。
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 9 17 9 1048576 128
DEMO_TABLE DEMO 9 18 137 1048576 128
19 rows selected.
新分配的區被寫在了檔案9上。
我們現在按計劃,再新增一個非自動擴充套件的資料檔案,看看新分配的區會寫到可擴充套件的檔案上,還是這個新新增的不可擴充套件的新資料檔案上。
SQL> alter tablespace demo add datafile '/oradata/orcl/demo04.dbf' size 2M 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 2097152 256 AVAILABLE 6 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo02.dbf 8 DEMO 2097152 256 AVAILABLE 8 NO 0 0 0 2031616 248 ONLINE
/oradata/orcl/demo03.dbf 9 DEMO 3145728 384 AVAILABLE 9 YES 3.4360E+10 4194302 1 3080192 376 ONLINE
/oradata/orcl/demo04.dbf 10 DEMO 2097152 256 AVAILABLE 10 NO 0 0 0 2031616 248 ONLINE
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 265 983040 120 9
DEMO 10 9 2031616 248 10
SQL> select count(*) from demo_table;
COUNT(*)
----------
31000
現在表中有31000行,根據我們前面實驗的經驗,差不多128個資料塊可以存放10000行記錄。為了加快實驗速度,我們直接把記錄增加到4萬行。
繼續向測試表中插入資料9000行。
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 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 265 983040 120 9
DEMO 10 9 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 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 9 17 9 1048576 128
DEMO_TABLE DEMO 9 18 137 1048576 128
19 rows selected.
SQL> select count(*) from demo_table;
COUNT(*)
----------
40000
如上所示,這時並未發生新的區的分配。如果這裡再插入資料1000行,就會發生新的區的分配了。
SQL> insert into demo_table select * from dba_objects where rownum<=1000;
1000 rows created.
SQL> select * from dba_free_space where tablespace_name='DEMO' order by file_id;
TABLESPACE FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
DEMO 6 137 983040 120 6
DEMO 8 137 983040 120 8
DEMO 9 265 983040 120 9
DEMO 10 137 983040 120 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 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 9 17 9 1048576 128
DEMO_TABLE DEMO 9 18 137 1048576 128
DEMO_TABLE DEMO 10 19 9 1048576 128
20 rows selected.
如上所示,在10號檔案上,分配了一個新區,新區大小128個資料塊。
綜上,可以得出以下幾個觀點:
1、當初始建立表空間後,ORACLE會首先向FILE_ID最大的資料檔案中寫入。
2、區的大小不是不變的,初始是每區8個塊,但隨後就增加到每區128個資料塊。
3、資料檔案中剩餘的連續塊若不夠128個,即不夠一個新區的需要的塊數量時,空間是浪費的。
疑問:由於這個實驗中的資料檔案起始大小過小,非自動擴充套件的資料檔案中已不能容納一個新的區(128個資料塊),所以,再新增加的區只能是寫到新追加的資料檔案或是對可擴充套件的資料檔案進行擴充套件。那麼,如果非自動擴充套件的資料檔案可以容納下一個新的區,情況會是什麼樣子呢?
為此,在下面的實驗中,我們將初始檔案的大小由2M,改為4M。
同時,為了保證實驗的一致性,我們將當前的表空間及其內容和資料檔案全部刪除。
本實驗的後半部分請見 http://blog.itpub.net/22207394/viewspace-1081774/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22207394/viewspace-1081775/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 表空間新增資料檔案的疑惑
- 錯誤新增表空間的資料檔案
- Oracle9i 同一表空間下寫多個資料檔案的原則 ?Oracle
- MySQL innodb共享表空間新增表空間資料檔案方法MySql
- 表空間和資料檔案的管理
- 表空間和資料檔案管理
- Oracle臨時表空間檢視、新增臨時表空間資料檔案、修改預設臨時表空間 方法!Oracle
- 移動資料檔案、系統表空間檔案、臨時表空間檔案
- 表空間&資料檔案和控制檔案(zt)
- . 資料庫臨時表空間的資料檔案的丟失資料庫
- 備份與恢復--一個表空間能否被多個資料庫讀寫?資料庫
- 一個表空間最多有多少個資料檔案和file#與rfile#的關係
- Oracle系統表空間剛新增的一個資料檔案誤刪除恢復處理Oracle
- 重新命名資料檔案和表空間
- Oracle 查詢各個 “表空間/資料檔案” 的空間使用比情況Oracle
- 表空間中有資料也可以壓縮表空間(資料檔案)大小
- 某個表空間的資料檔案損壞的修復思路
- 資料檔案,表空間的移動
- 新建的表空間(或資料檔案)丟失以及控制檔案丟失,有新建表空間(或資料檔案)前的控制文
- Oracle 表空間與資料檔案Oracle
- oracle 資料檔案表空間管理Oracle
- IMPDP 多個表空間物件匯入到一個表空間中物件
- Oracle資料庫表空間的資料檔案大小上限。Oracle資料庫
- 備份與恢復--一個表空間能否被多個資料庫同時開啟?資料庫
- oracle基礎管理——表空間和資料檔案Oracle
- 臨時表空間資料檔案損壞的解決
- 檢視Oracle資料庫表空間大小,是否需要增加表空間的資料檔案Oracle資料庫
- 當資料檔案表空間丟失的時候怎麼恢復該資料檔案
- oracle 回收表空間的資料檔案大小Oracle
- 把多個資料夾中的檔案批量放到一個資料夾
- 資料結構實驗一:順序表的建立與操作實現、順序表實現約瑟夫環問題資料結構
- oracle 表空間 資料檔案 筆記Oracle筆記
- 表空間資料檔案故障處理
- 線上遷移表空間資料檔案
- Oracle 表空間資料檔案遷移Oracle
- 南郵資料結構實驗1.1 順序表的操作資料結構
- Sqlserver delete表部分資料釋放資料檔案空間SQLServerdelete
- 基礎知識5——表空間和資料檔案