一、dba_free_space的说明:
dba_free_space显示的是有free 空间的tablespace ,如果一个tablespace 的free 空间不连续,那每段free空间都会在dba_free_space中存在一条记录。如果一个tablespace 有好几条记录,说明表空间存在碎片,当采用字典管理的表空间碎片超过500就需要对表空间进行碎片整理。
二、关于dba_free_space的疑问:
根据如下查询:
SQL>select tablespace_name from dba_free_space;
根据查询结果可发现,出现了多个相同的表空间名;为什么呢?这个问题可根据dba_free_space的说明得到解答:dba_free_space显示的是有free 空间的tablespace ,如果一个tablespace 的free 空间不连续,那每段free空间都会在dba_free_space中存在一条记录。如果一个tablespace 有好几条记录,说明表空间存在碎片,当采用字典管理的表空间碎片超过500就需要对表空间进行碎片整理。
根据如下查询语句可发现:
SQL>select * from dba_free_space;
一个表空间有两个不连续的block_id,正是因为这样才会导致一个表空间在dba_free_space视图中存在两条记录;
三、关于dba_free_space视图的问题
看下面的例子,请高手解释一下好吗?
------------------------
一开始:
环境:Windows xp+Oracle 10g 10.2.0;
数据库:PAXDB,
表空间:TEST_TABLESPACE
test_tablespace(create tablespace test_tablespace datafile 'D:/oracle/ORADATA/PAXDB/test_datafile.dbf' size 300M extent managerment local uniform size 40K);
用户:test/manager
说明:新建立的表空间test_tablespace对应的数据文件大小是300m,所在的数据库的数据块大小是8192k,所以对于刚建立的表空间来说,由于数据文件头部占据了0-8共9个数据块。从下面的查询block_id=9 我们可以看出,oracle保留了数据文件前面9个block(block 0~8),所以刚开始查询表空间的空闲空间时,数据块bloci_id是从9开始的,总共的字节数是314490880,总共有314490880/8192=38390个数据块,共314490880/1024/1024=299.921875m.总共使用的空间数目是8192*9/1024/1024=0.0703125m.
下面我们来看看这9个block的具体情况:
block 0: OS header
block 1: datafile header
block 2: bitmapped file space header
block 3~8: Head portion of bitmap blocks
至于如何看某个block的结构,用bbed再方便不过了,那下面我们就用bbed来看看这9个block是什么样的
SQL>select * from dba_free_space where tablespace_name='TEST_TABLESPACE';
得到:
然后在TEST_TABLESPACE tablespace中建一表:
create table cba( cba number(20) ); ---(初始为40k)
SQL>select * from dba_free_space where tablespace_name='TEST_TABLESPACE';
说明:在表空间初始化建立时指定了uniform参数,说明该表空间里所有的segment的extent大小都相同为40k,所以当在该表空间里建立一个表时,该表所对应的段的扩展extent一次为40k,即40*1024/8192=5个数据块。所以建立一个表后该表空间的空闲空间的数据块block_id从原来的9增加5后递增到14开始。
再drop它
drop table cba;
再查询:
SQL>select * from dba_free_space where tablespace_name='TEST_TABLESPACE';
得到:
(此处就多了一条记录)
然后再建一表
create table abc( abc number(20) ); ---(初始为40k)
查询:
select * from dba_free_space where tablespace_name='TEST_TABLESPACE';
得到:
再drop :
drop table abc;
再查询:
select * from dba_free_space where tablespace_name='TEST_TABLESPACE';
得到:
然后建一个初始值为80k的表:
create table abc( abc number(10) ) storage( initial 80k next 80k );
再查询:
select * from dba_free_space where tablespace_name=TEST_TABLESPACE';
得到:
解答:
SQL>desc dba_free_space;
TABLESPACE_NAME:Name of the tablespace containing the extent
FILE_ID:ID number of the file containing the extent
BLOCK_ID:Starting block number of the extent
BYTES:Size of the extent in bytes
BLOCKS:Size of the extent in ORACLE blocks
RELATIVE_FNO:Relative number of the file containing the extent
你建的表,占据了数据文件中的一部分。
而dba_free_space记录的是某个数据文件,从某一个block(BLOCK_ID)开始,连续的多少字节(BYTES),同时也换算成多少block(BLOCKS),是空闲的。
所以你新建一个表后,由于表占据了数据文件的中间一部分,空闲区域被分成两块,你看到的记录也是两条了
建表后dba_free_space视图中的记录并未变成2条,而是在将该表drop后变成2条了。而且一条记录的block_id为89701 , blocks为5
而另一条记录的block_id为 89706 。 这样看来的,这两块空闲空间应该是相连的,为什么不并为一块显示呢?
由于有一块是原来使用的,后释放出来的,所以没有马上合并。
这种空闲空间的合并,一般是要表空间的pctincrease参数大于0时,SMON进程会自动进行,或者也可以由管理员手工执行命令强制进行。