Oracle中的Low HWM与 High HWM 高水位

在MSSM的FREELIST下, 高水位High Water Mark代表所有相关块, 高水位以上就是未格式化unformatted 的数据块,INSRT数据时不能直接使用。当FREELIST中不包含可插入数据块时 HWM默认每次上升5个数据块。

对于ASSM管理的BITMAP 数据段而言,Oracle允许在数据段的中部出现unformatted blocks未格式化的数据块,  基于以下的原因:

一、在以前 HWM以下的数据块必然是formatted , 为了维护这一点代价是昂贵的:

  1. 长时间持有HW enqueue  队列锁对并发的抑制
  2. 过于频繁的持有HW enqueue在Oracle研发看来是罪恶的

上涨HWM 而不格式化 这样的话更有效率,因为格式化往往涉及到 IO,是一种较慢的操作

 

二、 在直接路径加载过程中,最后的一个extent中的数据块将被全部format 格式化,而如果下一次还是direct load直接路径加载数据的话,它不会从Freelist上获取数据块,而是使用HWM以上新的数据盘区extent。 如果这个数据段是典型的一直在direct load加载数据的话,则可能在freelist上有很多unused block从来不被使用,而被浪费了。 这可能造成空间的浪费,尤其是在Extent size 很大的时候 或者 数据段几乎从来不传统路径插入数据的时候。保留这些数据块为unformatted则可以让加载数据时利用到这些空间空洞

 

为了实现这一点就需要使用2个High Water Mark 即Low HWM和High HWM;  Low HWM以下都是formatted 数据块 而 High HWM以上都是unformatted数据块。

 

 

  Extent Header:: spare1: 0      spare2: 0      #extents: 18413  #blocks: 147304
                  last map  0xabc23541  #maps: 36     offset: 2716
      Highwater::  0xabc23f6c  ext#: 18412  blk#: 3      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 147299
  mapblk  0xabc23541  offset: 325
                   Unlocked
  --------------------------------------------------------
  Low HighWater Mark :
      Highwater::  0xabc23f6c  ext#: 18412  blk#: 3      ext size: 8
  #blocks in seg. hdr's freelists: 0
  #blocks below: 147299
  mapblk  0xabc23541  offset: 325
  Level 1 BMB for High HWM block: 0xabc23ef9
  Level 1 BMB for Low HWM block: 0xabc23ef9
  --------------------------------------------------------
  Segment Type: 1 nl2: 2      blksz: 8192   fbsz: 0
  L2 Array start offset:  0x00001434
  First Level 3 BMB:  0x00000000
  L2 Hint for inserts:  0xabc0000a
  Last Level 1 BMB:  0xabc23ef9
  Last Level II BMB:  0xabc1d5fa
  Last Level III BMB:  0x00000000
     Map Header:: next  0xabc009a1  #extents: 307  obj#: 99039  flag: 0x10000000
  Inc # 0
  Extent Map

 

在顺序读取过程中,那些unformatted数据块将被忽略。关于一个数据块究竟是format了还是没有的信息是存放在2个高水位之间的bitmap中。 当扫描数据段的块时,扫描算法并不参考LOW HWM以下的bitmap block; High HWM用来作为顺序读取该数据段时 停止扫描的位置。

 

格式化数据块一般发生在搜索空间时,如果数据块被发现时unformatted,则格式化一部分数据块(至少16个)。 格式化数据块未必更新Low HWM。

 

何时更新LOW HWM是一个问题: Low HWM在当前extent和之前的extent中的所有数据块均被格式化的情况下被更新,否则不更新。

 

来举2个场景: HENO=高水位盘区号, HBNO= 高水位数据块号,MyEno = My Extent number; MyBno = My block number. :

 

如果(HEno == MyEno && MyBno == HBno+1), 例如在同一个extent中格式化下一个范围的block

如果(HEno + 1 == MyEno && HBno == HExtentSize &&MyBno == 0),例如在前一个extent中所有的数据块均已format 然后要format下一个extent时

 

对于High HWM而言,如果High HWM以下的数据块不够用,则可能上升High HWM,这个过程需要用到HW Enqueue队列锁。High HWM移动的块数目取决于一级bitmap block控制的块数目,HIGH HWM以下包含了所有的L1 bitmap block。

 

 

Comments

  1. _bump_highwater_mark_count5how many blocks should we allocate per free list on advancing HWM

  2. maclean says

    Low HWM: Below which all blocks are formatted andHigh HWM : Above which all blocks are formatted. Between the two high water marks there could be some unformatted blocks

  3. SQL> create tablespace mssm datafile size 100M extent management local uniform size 1M segment space management manual;表空间已创建。SQL> create tablespace assm datafile size 100M extent management local uniform size 1M segment space management auto;表空间已创建。SQL> create table direct_load1 (t1 char(2000)) tablespace mssm pctfree 99 pctused 1 ;表已创建。SQL> insert /*+ APPEND */ into direct_load1 select ‘MACLEAN’ from dual connect by level<=131;已创建 131 行。SQL> commit;提交完成。SQL> insert /*+ APPEND */ into direct_load1 select ‘MACLEAN’ from dual connect by level<=131;已创建 131 行。SQL> commit;提交完成。SQL> insert /*+ APPEND */ into direct_load1 select ‘MACLEAN’ from dual connect by level<=131;已创建 131 行。SQL> commit;提交完成。SQL> insert /*+ APPEND */ into direct_load1 select ‘MACLEAN’ from dual connect by level<=131;已创建 131 行。SQL> commit;提交完成。SQL> select count(*) from DIRECT_LOAD1; COUNT(*)———- 524SQL> select header_file,header_block from dba_segments where segment_name=’DIRECT_LOAD1′;HEADER_FILE HEADER_BLOCK———– ———— 15 128SQL> alter system dump datafile 15 block 128;系统已更改。 Extent Header:: spare1: 0 spare2: 0 #extents: 5 #blocks: 639 last map 0x00000000 #maps: 0 offset: 4128 Highwater:: 0x03c0028d ext#: 4 blk#: 13 ext size: 128 #blocks in seg. hdr’s freelists: 0 #blocks below: 524 SQL> create table direct_load2(t1 char(2000)) tablespace assm pctfree 99 pctused 1 ;表已创建。insert /*+ APPEND */ into direct_load2 select ‘MACLEAN’ from dual connect by level<=131;commit;SQL> select count(*) from DIRECT_LOAD2; COUNT(*)———- 524SQL> select header_file,header_block from dba_segments where segment_name=’DIRECT_LOAD2′;HEADER_FILE HEADER_BLOCK———– ———— 16 131SQL> alter system dump datafile 16 block 131;系统已更改。 Extent Header:: spare1: 0 spare2: 0 #extents: 5 #blocks: 640 last map 0x00000000 #maps: 0 offset: 2716 Highwater:: 0x04000298 ext#: 4 blk#: 24 ext size: 128 #blocks in seg. hdr’s freelists: 0 #blocks below: 536 mapblk 0x00000000 offset: 4 Unlocked ——————————————————– Low HighWater Mark : Highwater:: 0x04000298 ext#: 4 blk#: 24 ext size: 128 #blocks in seg. hdr’s freelists: 0 #blocks below: 536 mapblk 0x00000000 offset: 4 Level 1 BMB for High HWM block: 0x04000280 Level 1 BMB for Low HWM block: 0x04000280

  4. tolywang says

    大师,还有一点不清楚, ASSM 下,普通的插入数据,一般是在 low HWM 与 HWM 之间,如果low HWM以下还有可用空间的话,也会插入到low HWM以下的数据块中, 假设一个大操作, 需要插入的数据行太多, 而需要推进 HWM , 假设这时HWM 向前推进 32 blocks , 新分配的blocks 一部分会被formatted ,而进行数据插入, 还有一部分是剩下来的,不做formatted , 这时 low HWM 的标线推进到了原 HWM 的位置 ? 还是在新分配blocks中formatted blocks和unformatted blocks 的分割线部分 ?

  5. tolywang says

    看了 Oracle的文档, 大致知道了答案, HWM 推进后, 原low HWM与原HWM之间的空间应该是满了,但是原HWM与新的HWM之间的空间,formatted 的blocks 可以使任意的, 不一定是连续的, 而low HWM 要求它之下的blocks必须是formatted, 所以原low HWM 只能是推进到原HWM的位置。而没有所谓的“ 新分配blocks中formatted blocks和unformatted blocks 的分割线” 。 不知道是否正确。 请大师指正 。

Comment

*

沪ICP备14014813号-2

沪公网安备 31010802001379号