(2011-01-27)通过dba_free_space视图查看表空间的空间分配过程

 

一、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-89个数据块。面的查询block_id=9  我们可以看出,oracle保留了数据文件前面9blockblock 0~8,所以刚开始查询表空间的空闲空间时,数据块bloci_id是从9开始的,总共的字节数是314490880,总共有314490880/8192=38390个数据块,共314490880/1024/1024=299.921875m.总共使用的空间数目是8192*9/1024/1024=0.0703125m.

下面我们来看看这9block的具体情况:

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来看看这9block是什么样的


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参数,说明该表空间里所有的segmentextent大小都相同为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_NAMEName of the tablespace containing the extent
FILE_IDID number of the file containing the extent
BLOCK_IDStarting block number of the extent
BYTESSize of the extent in bytes
BLOCKSSize of the extent in ORACLE blocks
RELATIVE_FNORelative number of the file containing the extent

你建的表,占据了数据文件中的一部分。
dba_free_space记录的是某个数据文件,从某一个blockBLOCK_ID)开始,连续的多少字节(BYTES),同时也换算成多少blockBLOCKS),是空闲的。
所以你新建一个表后,由于表占据了数据文件的中间一部分,空闲区域被分成两块,你看到的记录也是两条了

建表后dba_free_space视图中的记录并未变成2条,而是在将该表drop后变成2条了。而且一条记录的block_id89701 ,  blocks5
而另一条记录的block_id为 89706  。 这样看来的,这两块空闲空间应该是相连的,为什么不并为一块显示呢?

由于有一块是原来使用的,后释放出来的,所以没有马上合并。

这种空闲空间的合并,一般是要表空间的pctincrease参数大于0时,SMON进程会自动进行,或者也可以由管理员手工执行命令强制进行。

你可能感兴趣的:(oracle,数据库,扩展,oracle10g)