暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

段空间管理技术-手工段空间管理

原创 eygle 2019-10-14
799

在Oracle数据库内部,对象空间是以段的形式(Segment)存在和管理的,通过不同的段类型Oracle将段区分开来,在Oracle 9i中,主要的段类型有:

SQL> select distinct(segment_type) from dba_segments;
SEGMENT_TYPE
------------------
CACHE
CLUSTER
INDEX
INDEX PARTITION
LOBINDEX
LOBSEGMENT
NESTED TABLE
ROLLBACK
TABLE
TABLE PARTITION
TYPE2 UNDO
 
11 rows selected.


当一个段被创建时,区间(Extent)就被分配,随着后续的不断使用,一个段的空间可以以区为单位不断扩展。


前面提到Extent的管理技术是通过字典或本地的方式进行的,那么当Extent被分配给Segment,这个空间又是如何管理的呢?“SEGMENT SPACE MANAGEMENT AUTO”这个语句就是定义的段空间管理方式。


Oracle的段空间管理方式主要有两种,一种是手工段空间管理(Manual Segment Space Management,缩写为MSSM),由于这种方式使用自由列表来管理段空间,所以也被称为自由列表管理方式(Freelist Mangement,缩写为FLM),一种就是Oracle 9i带来的全新的自动段空间管理(Auto Segment Space Management,缩写为ASSM)。

手工段空间管理(Manual Segment Space Management)


MSSM管理方式是Oracle最初实现的一种段空间管理技术。前面提到,区间(Extent)是Oracle的最小空间分配单元,而Block是Oracle的最小IO操作单元,也就是说,Oracle以区间为单位将空间分配给对象段,而段内则是以Block为单位进行空间使用和管理的。


这个段空间管理在Oracle 9i之前是通过手工段空间管理技术实现的,这种技术的具体实现方式是通过在段头(Segment Header)分配自由列表(freelist)来管理Block的使用,简单一点,可以把自由列表想象成一个数据表,Oracle依赖一系列的算法通过向自由列表中加入或移出Block来实现段空间管理。


当创建对象时(如数据表)可以定义freelist的数量,对于数据表缺省的freelist为1,可以通过dba_segments查询得到这些数据:

SQL> select SEGMENT_NAME,SEGMENT_TYPE,FREELISTS,FREELIST_GROUPS
  2  from DBA_SEGMENTS where TABLESPACE_NAME='EYGLE';
SEGMENT_NA SEGMENT_TYPE        FREELISTS FREELIST_GROUPS
---------- ------------------ ---------- ---------------
TEST       TABLE                       1               1
TEST3      TABLE                       1               1


当向一个对象中插入数据时,Oracle首先在该对象的freelist上寻找可用于插入数据的Block,当一个Block用完之后,就会从freelist上摘除,当这个Block上由于数据删除等空间释放后,可以再次回到freelist上来,而这主要是通过存储参数PCTFREE和PCTUSED来实现。


当向一个对象中插入数据时,假设PCTFREE=20,PCTUSED=40,这就表明当一个Block的空间使用率达到了80%时,这个block就不再允许被用于新增数据(insert),而保留下来的这20%的空间则被预留为行更新(update)所可能需要的空间扩展,此时这个Block就从freelist上被移除;当这个Block中有数据被删除(delete)时,空间不断被释放,当空间使用低于PCTUSED参数设置时(此处即为40%),这个数据块块才会重新被加入到freelists中,加入freelist后这个Block又可以被插入新的数据,如图5-3所示。


image.png

图5-3  数据库空间的使用


通过以上的描述可以看到,如果一个段的操作非常频繁,那么很多用户就会同时请求访问freelist,并对freelist进行修改,这就很容易产生竞争。对于表来说,缺省的freelist为1,这就很容易引发竞争,虽然可以通过增加freelist的方法缓解这种竞争,但是我们已经看到这种管理方式存在的缺陷。所以从Oracle 9i开始,Oracle推出了ASSM的管理方式。


接下来可以通过DUMP的方式来转储数据块的头信息,发现freelist的设置等:

SQL> select segment_name,file_id,block_id,blocks
  2  from dba_extents where tablespace_name='EYGLE';
SEGMENT_NA    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
TEST                3          9        128
TEST                3        137        128
TEST3               3        777        128
SQL> alter system dump datafile 3 block 9;
System altered.


检查trace文件就可以发现如下信息:

buffer tsn: 4 rdba: 0x00c00009 (3/9)
scn: 0x0004.6c1e9774 seq: 0x01 flg: 0x00 tail: 0x97741001
frmt: 0x02 chkval: 0x0000 type: 0x10=DATA SEGMENT HEADER - UNLIMITED
  Extent Control Header
  -----------------------------------------------------------------
  Extent Header:: spare1: 0      spare2: 0      #extents: 2      #blocks: 255
                  last map  0x00000000  #maps: 0      offset: 4128
      Highwater::  0x00c00056  ext#: 0      blk#: 76     ext size: 127
  #blocks in seg. hdr's freelists: 76
  #blocks below: 76
  mapblk  0x00000000  offset: 0
                   Unlocked
     Map Header:: next  0x00000000  #extents: 2    obj#: 9969   flag: 0x40000000
  Extent Map
  -----------------------------------------------------------------
   0x00c0000a  length: 127
   0x00c00089  length: 128
 
  nfl = 1, nfb = 1 typ = 1 nxf = 1 ccnt = 0
  SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
  XCT LST:: flg: USED   lhd: 0x00c00055 ltl: 0x00c0000a xid: 0x0001.008.00000256
End dump data blocks tsn: 4 file#: 3 minblk 9 maxblk 9


这里的hdr's freelists就是指freelist里面的数据块数量,本例的表中,freelist中有76个空闲数据块。有兴趣的读者可以进行一点深入研究,这里不再过多介绍

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论