ITPub博客

首页 > 数据库 > Oracle > Ora Ora Oracle电子杂志:关于剩余数据块的检验 之6-8

Ora Ora Oracle电子杂志:关于剩余数据块的检验 之6-8

原创 Oracle 作者:yaanzy 时间:2005-07-29 17:09:21 0 删除 编辑

订阅Ora Ora Oracle电子杂志已经有几个月了,今天把它的第一个专题《关于剩余数据块的检验》整理了一下

想订阅该杂志的可以访问:http://www.performance-insight.com/china/

[@more@]
<关于剩余数据块的检验 之6>

这次要从表的角度检验剩余数据块的空间分配方式,我会按照下面的顺序说明。

接着上次的内容,这次要继续介绍如何检验剩余数据块。有如下三个知识点:

1. 理解minimum extent
2. 最大程度防止剩余空间碎片的方式﹝本次主题﹞
3. 图解Oracle如何使用剩余空间﹝以后再说明﹞

这次要向大家说明第2个主题:最大程度防止剩余空间碎片化的方法。先请大家看看检验的结果。

“Oracle分配空间的时候不会分配低于5个Block的空分区(extent)。”说明书上虽然写着不会分配少于5个Block的分区,但是根据我在7.3.2版本以上的检验结果,其实也可以是5以下。现在,我们就来看看“不会分配低于5个Block的空分区”的空间分配情况。

*************************************************************
/*建立剩余数据块105的表空间*/

create tablespace cre20 datafile
'../shome/share/cre20.ora' SIZE 212k
default storage (pctincrease 0);

(注意:datafile的开头一定存在1个数据块的Header)
*************************************************************

先在空间中建立INITIAL 10 block的表,然后分配10BLOCK×9EXTENT。
*************************************************************
create table cre20 (col1 number)  tablespace cre20 
storage(initial 20k next 20k pctincrease 0);

alter table cre20 allocate extent (size 20k);
alter table cre20 allocate extent (size 20k);
alter table cre20 allocate extent (size 20k);
alter table cre20 allocate extent (size 20k);
alter table cre20 allocate extent (size 20k);
alter table cre20 allocate extent (size 20k);
alter table cre20 allocate extent (size 20k);
alter table cre20 allocate extent (size 20k);
alter table cre20 allocate extent (size 20k);
*************************************************************

看看dba_extents视图。
*************************************************************
SEGMENT_NAME  EXTENT_ID  BLOCK_ID  BYTES  BLOCKS
------------------------------------------------
CRE20         0          2         20480  10
CRE20         1          12        20480  10
CRE20         2          22        20480  10
CRE20         3          32        20480  10
CRE20         4          42        20480  10
CRE20         5          52        20480  10
CRE20         6          62        20480  10
CRE20         7          72        20480  10
CRE20         8          82        20480  10
CRE20         9          92        30720  15     ←注意
*************************************************************

请注意EXTENT_ID 9 BLOCK_ID 92的extent,应该分配10 block却变成15block。
*************************************************************
create tablespace cre20 datafile
'../shome/share/cre20.ora' SIZE 214k
default storage (pctincrease 0);
*************************************************************

按照上面的方式建立了106 block的剩余数据块之后,上面的dba_extents都会分配10 block。因为Oracle不会把6个数据块以上的剩余数据块当成碎片。

是不是所有情况都会这样?以下面2种条件检验是不是真的不会留下5个数据块以下的剩余空间。

2_1:在create tablespace指定Size参数,让空闲空间在5个Block以下
2_2:在create tablespace指定minimum extent参数

2_1的检验在真实应用中并不存在,我们只是看看建立5个Block以下的表空间Oracle是否会发生错误,所以还是检验看看。结果如下,这是做了1block到5block的空间分配之后检索dba_free_space的结果。
*************************************************************
TABLESPACE_NAME  BLOCK_ID  BYTES  BLOCKS
----------------------------------------
CRE1L            2         2048   1
CRE2L            2         4096   2
CRE3L            2         6144   3
CRE4L            2         8192   4
CRE5L            2         10240  5
*************************************************************

结果就像上面这样,没有发生问题,产生了5block以下的剩余空间。请先将这个结果视为特殊情况。

接下来看看2_2的情况。minimum extent会决定分配单位,所以这次的检验方法和刚才几乎相同,只是修改了minimum extent。
*************************************************************
/*在db_block_size=2k的环境,建立SIZE 212k的表空间,让剩余数据块有105个资料块*/
----------------------------------------
create tablespace min0 datafile
'../shome/share/min0.ora' SIZE 212k
default storage (pctincrease 0);

create tablespace min1 datafile
'../shome/share/min1.ora' SIZE 212k
minimum extent 2k
default storage (pctincrease 0);

create tablespace min10 datafile
'../shome/share/min10' SIZE 212k
minimum extent 20k
default storage (pctincrease 0);
*************************************************************

之后同样在各个表空间建立initial 10 block的表,执行九次
alter table <表的名称> allocate extent (size 20k);
分配extent,结果如下。
*************************************************************
SEGMENT_NAME  TABLESPACE_NAME  EXTENT_ID  BYTES  BLOCKS
-------------------------------------------------------
MIN0          MIN0             0          20480  10
MIN0          MIN0             1          20480  10
MIN0          MIN0             2          20480  10
.......................................................
MIN0          MIN0             7          20480  10
MIN0          MIN0             8          20480  10
MIN0          MIN0             9          30720  15 ←都一样

MIN1          MIN1             0          20480  10
MIN1          MIN1             1          20480  10
MIN1          MIN1             2          20480  10
.......................................................
MIN1          MIN1             7          20480  10
MIN1          MIN1             8          20480  10
MIN1          MIN1             9          30720  15 ←都一样

MIN10         MIN10            0          20480  10
MIN10         MIN10            1          20480  10
MIN10         MIN10            2          20480  10
MIN10         MIN10            3          20480  10
.......................................................
MIN10         MIN10            7          20480  10
MIN10         MIN10            8          20480  10
MIN10         MIN10            9          30720  15 ←都一样
*************************************************************

结果每个分配最后都是15个数据块,全都和刚才的结果一样。虽然没有把完整的输出结果放上来,其实还是和刚才一样,刚开始建立了剩余数据块为106 block的表空间,结果都是分配10个数据块,只有第11个例外。由检验结果可知,“不管minimum extent是多少,Oracle分配空间时都不会留下5 block以下的空extent。”

下次我们会继续针对minimum extent说明。

 

<关于剩余数据块的检验 之7>

这次要从表的角度检验剩余数据块的空间分配方式,我会按照下面的顺序说明。

接着上次的内容,这次要继续介绍剩余数据块的检验。有如下三个知识点:

1. 理解minimum extent
2. 最大程度防止剩余空间碎片的方式﹝本次主题﹞
3. 图解Oracle如何使用剩余空间

上次说明了两种情况:

2_1:在create tablespace指定Size参数,让空闲空间在5个Block以下
2_2:在create tablespace指定minimum extent参数

这次要对2_2.进一步说明,上次我们验证在没有指定minimum extent时(也就是使用默认值0)的情况下,当db_block_size=2k时,分区(extent)分配单位为10个Block(即20K)。当空闲空间少于5个Block时,extent的分配情况看上去就像是minimum extent=2k(1个block)这个参数起效了,而当空闲空间在6个block以上时,系统会默认以minimum extent=10k(5个block)分配extent,给minimum extent指定任何小于5的值该参数都会被忽略掉。那么这个结论是否对于任何情况都适用?请大家先回答下面的问题。

问题:
在DB_BLOCK_SIZE=2K的环境下,minimum extent为0的时候(预设)和minimum extent为10K (5 block)的时候,在有114 block连续剩余数据块的表空间中建立initial 114 block的表之后,分别会发生什么情况?
(1). 企图分配115 block而导致错误
(2). 恰好分配114 block

正确答案如下:
minimum extent为0的时候:(2). 恰好分配114个block
minimum extent为10K的时候:(1). 企图分配115个block而导致错误

指定minimum extent为10K(5 block)的时候,会以5个block分配空间。当指定minimum extent为0的时候,若要分配5 block以下的分区时,会尝试以5个block分配,如果无法顺利分配,就取进位之前的数值,在上面的例子就是4个block。为了尽量不要留下剩余数据块碎片,所以才出现这种差异。下面就是检验结果。

*************************************************************
/*分别以minimum extent 0和minimum extent 10k建立剩余数据块有114个block的表空间*/

create tablespace tbs114_m0 datafile
'/shome/share/tbs114_m0' SIZE 230k
minimum extent 0
default storage (pctincrease 0);

create tablespace tbs114_m5 datafile
'/shome/share/tbs114_m5' SIZE 230k
minimum extent 10k
default storage (pctincrease 0);
*************************************************************

*************************************************************
/*在表空间中分别建立initial 114 block的表*/

create table tb114_m0 (col1 number)  tablespace tbs114_m0 
storage(initial 228k  minextents 1);
*************************************************************

表已经建好了。
*************************************************************
create table tb114_m5 (col1 number)  tablespace tbs114_m5 
storage(initial 228k  minextents 1);

发生错误。
ORA-01658: 表空间: TBS114_M5无法建立segment用的INITIAL EXTENT。
*************************************************************

大家应该可以从检验结果看出问题的答案。

请到下面的网页,上面有表示Oracle如何使用剩余空间的图。这是经过检验完成的图解,请大家复习目前为止的内容,就能了解图的内容。

http://www.performance-insight.com/html/ora3/ora3_ref/reference2_e.gif


下次是<关于剩余数据块的检验>的最后一节,敬请期待。以后我们会陆续介绍大家感兴趣的内容,例如Oracle 10g的新功能。要让我们感到发行免费电子杂志是一件有意义的事业,我们希望看到读者人数不断增加。如果您觉得杂志的内容很好,请帮忙介绍给其他朋友。读者人数增多,大家就能每周看到更多Oracle的精彩介绍!

 

读者问题
把回滚段(rollback segment)的表空间和临时区段(temporary segment,临时表空间)设定为pctincrease=0,那么是将SMON设为每隔5分钟执行临近空闲段合并比较好,还是设为总不执行合并比较好?

《回答》
一般来说上面的两个表空间设为pctincrease=0并不执行空闲段合并比较好。这是因为即使执行合并,也没有什么意义。尤其对于那些执行合并会对CPU造成负荷的资料库,就更应该这样设定。如果总是收到ORA-01575“timeout waiting for space management resource”的出错消息,就应该考虑减轻执行合并所造成的负荷。下面是详细的说明。

《关于暂时表空间》
先从空间管理的观点说明临时表空间。

1. 临时表空间的DEFAULT STORAGE语句的重要性:
通常表或索引会使用表空间的DEFAULT STORAGE语句指定的INITIAL、NEXT参数,在建立表、索引的时候是否明确指定INITIAL、NEXT参数并不是很重要。临时表空间会为临时区段指定的INITIAL、NEXT参数值,所以指定临时表空间的默认存储参数非常重要。

2. 临时表空间的属性差异

“TEMPORARY”
表空间的属性如果是TEMPORARY就一定要设定PCTINCREASE=0。TEMPORARY是指,该表空间在重新启动数据库后才会释放临时区段的空间加以再利用。即使没有连续的空闲空间,每个独立的空闲空间都会和要分配的extent大小一致,所以即使不执行合并也能有效再利用空间。

“PERMANENT”
表空间的属性如果是PERMANENT,排序结束后就会释放暂时区段,无法再利用。所以这种情况下更应该设定PCTINCREASE=0,减轻结合所造成的负荷。

“TEMPORARY和PERMANENT的比较”
临时表空间设为TEMPORARY 比PERMANENT好,因为没有了取得/释放所造成的空间管理的负荷,性能就会比较好。

《关于回滚段的表空间》
回滚段是可以再利用的。而且回滚段本身不能指定PCTINCREASE。(内部是PCTINCREASE=0)考虑这些特点,临时表空间同样不需要执行合并也能有效再利用,所以设为总不执行合并比较好。

 

<关于剩余数据块的检验 之8>

这次的检验包括
1. 有多个数据文件的表空间的extent分配
2. 指定Free list group之后的段标题(segment header)

先从1.[有多个数据文件的表空间的extend的分配]开始检验。
1_1.建立拥有三个数据文件TEST3X的表空间。

*************************************************************
create tablespace TEST3X
datafile '/export1/home1/oradata/test3a' SIZE 1M,
         '/export2/home1/oradata/test3b' SIZE 1M,
         '/export3/home1/oradata/test3c' SIZE 1M;
*************************************************************

1_2.创建表dummy1,并且在这个表中插入1500条记录。
*************************************************************
/*db_block_size=2k的环境,t10man_org是EMP表扩大到10万笔记录的表*/

create table dummy1  ( dm number)
tablespace TEST3X
storage (initial 2k next 2k pctincrease 0 maxextents unlimited);

insert into dummy1 select empno from t10man_org where rownum <1501;

commit;
*************************************************************

1_3.再看看dba_extents。
*************************************************************
select TABLESPACE_NAME, SEGMENT_NAME, EXTENT_ID, FILE_ID, BLOCK_ID, BLOCKS
>from dba_extents where segment_name='DUMMY1'order by extent_id

TABLESPACE_NAME  SEGMENT_NAME  EXTENT_ID  FILE_ID  BLOCK_ID  BLOCKS
-------------------------------------------------------------------
TEST3X           DUMMY1        0          34       2         2
TEST3X           DUMMY1        1          32       26        1
TEST3X           DUMMY1        2          33       93        1
TEST3X           DUMMY1        3          34       69        1
TEST3X           DUMMY1        4          32       82        1
TEST3X           DUMMY1        5          33       39        1
TEST3X           DUMMY1        6          34       101       1
TEST3X           DUMMY1        7          32       85        1
TEST3X           DUMMY1        8          33       59        1
TEST3X           DUMMY1        9          34       21        1
*************************************************************

请大家注意在extent分配的时候,是按照数据文件FILE_ID 34,32,33的顺序分配。这是因为Oracle会自动将数据平均分散到三个数据文件中。

如果需要明确指定数据保存到指定的数据文件中,就按照下面的方法指定数据文件。
*************************************************************
alter table dummy1 allocate extent 
(size 100k datafile '/export1/home1/oradata/test3a')
*************************************************************

为了防止大量频繁的对表进行插入时产生Freelist冲突,OPS(Oracle Parallel Server Option)会事先分配extent。

2.指定Free list group之后的段标题(segment header)

Freelist Group在OPS环境下,尤其在经常执行INSERT的表,用来在instance之间分配insert。Freelist Group会存在段标题。在OPS环境下,可能会有大量的访问集中在这个段标题。这次我们要看看FREELIST GROUP会在段标题用掉多少数据块。
*************************************************************
/*db_block_size=2k的环境,以minimum extent 2k建立是因为不希望以5block单位被进位*/

create tablespace TEST4a
datafile '/export/home1/oradata/test4a' SIZE 1M
minimum extent 2k;
*************************************************************

接着,
*************************************************************
/*以2、3、4建立freelist groups */
create table dummy4_fg2  ( dm number)
tablespace TEST4a
storage (initial 2k next 2k pctincrease 0 freelist groups 2 
maxextents unlimited);

create table dummy4_fg3  ( dm number)
tablespace TEST4a
storage (initial 2k next 2k pctincrease 0 freelist groups 3
 maxextents unlimited);

create table dummy4_fg4_m2k  ( dm number)
tablespace TEST4a
storage (initial 2k next 2k pctincrease 0 freelist groups 4
maxextents unlimited);
*************************************************************

看看DBA_EXTETNS结果如下。
*************************************************************
TABLESPACE_NAME  SEGMENT_NAME   EXTENT_ID  FILE_ID  BLOCK_ID  BLOCKS
--------------------------------------------------------------------
TEST4A           DUMMY4_FG2     0          36       2         4
TEST4A           DUMMY4_FG3     0          36       6         5
TEST4A           DUMMY4_FG4_M2K 0          36       11        6
*************************************************************

如果指定多个freelist groups,每个会分别分配一个数据块。

例如DUMMY4_FG4_M2K的INITIAL EXTENT的组成如下。
*************************************************************
SEGMENT    FREELIST    FREELIST    FREELIST    FREELIST     DATA
HEADER     GROUP 1     GROUP 2      GROUP 3     GROUP 4
1个数据块  1个数据块    1个数据块   1个数据块    1个数据块   1个数据块
                              合计 6个数据块
*************************************************************

以minimum extent为0建立的表空間,建了freelist groups 4的表。
*************************************************************
/*minimum extent 0*/
create tablespace TEST4b
datafile '/export/home1/oradata/test4b' SIZE 1M;

/*freelist groups 4*/
create table dummy4_fg4_m0  ( dm number)
tablespace TEST4b
storage (initial 2k next 2k pctincrease 0 freelist groups 4
maxextents unlimited);
*************************************************************

一起看看DBA_EXTENTS。TEST4B是以5block为单位无条件进位,所以会分配10block。我想避免这种情况,因此在上面的检验中指定了minimum extent=2K。
*************************************************************
TABLESPACE_NAME  SEGMENT_NAME   EXTENT_ID  BLOCKS
--------------------------------------------------
TEST4B           DUMMY4_FG4_M0  0          10      ←进位到10个数据块
TEST4A           DUMMY4_FG4_M2K 0          6       ←看起来好像没有进位
*************************************************************

关于剩余数据库的校验全部介绍完了。敬请期待下次的新主题。

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

请登录后发表评论 登录
全部评论
  • 博文量
    108
  • 访问量
    762186