zoukankan      html  css  js  c++  java
  • 浅谈Oracle的高水位线--HWM

    https://www.2cto.com/database/201302/188402.html

        高水位是记录段里能容纳数据的上限,高水位存在段里

           全表扫先读段头块,而后在段头块里面找到HWM

            下面用实验由内而外来理解Oracle的HWM  www.2cto.com  

    [sql] 

    --t表有一条数据  

      

    hr@ORCL> select * from t;  

      

            ID NAME  

    ---------- ----------  

             1 AAAAA  

      

    --找t段的段头块    www.2cto.com  

      

    hr@ORCL> select header_file,header_block from dba_segments where segment_name='T' and owner='HR';  

      

    HEADER_FILE HEADER_BLOCK  

    ----------- ------------  

              4          387  

      

    --另开一个session,dump段头块  

      

    sys@ORCL> alter session set tracefile_identifier='sys_dump_t_01';  

      

    Session altered.  

      

    sys@ORCL> alter system dump datafile 4 block 387;  

      

    System altered.  

           dump的部分trc内容摘入  www.2cto.com  

    [sql] 

    Extent Control Header  

    -----------------------------------------------------------------  

    Extent Header:: spare1: 0      spare2: 0      #extents: 1      #blocks: 8  

                    last map  0x00000000  #maps: 0      offset: 2716  

        Highwater::  0x01000189  ext#: 0      blk#: 8      ext size: 8   --Highwater就是高水位, 0x01000189这个是HWM的地址  

    #blocks in seg. hdr's freelists: 0  

    #blocks below: 5  

    mapblk  0x00000000  offset: 0  

                     Unlocked  

    --------------------------------------------------------  

    Low HighWater Mark :  

        Highwater::  0x01000189  ext#: 0      blk#: 8      ext size: 8  

    #blocks in seg. hdr's freelists: 0  

    #blocks below: 5  

    mapblk  0x00000000  offset: 0  

    Level 1 BMB for High HWM block: 0x01000181  

    Level 1 BMB for Low HWM block: 0x01000181  

    --------------------------------------------------------  

    Segment Type: 1 nl2: 1      blksz: 8192   fbsz: 0  

    L2 Array start offset:  0x00001434  

    First Level 3 BMB:  0x00000000  

    L2 Hint for inserts:  0x01000182  

    Last Level 1 BMB:  0x01000181  

    Last Level II BMB:  0x01000182  

    Last Level III BMB:  0x00000000  

       Map Header:: next  0x00000000  #extents: 1    obj#: 52713  flag: 0x10000000  

    Inc # 0  

    Extent Map  

    -----------------------------------------------------------------  

     0x01000181  length: 8  

      

    Auxillary Map  

    --------------------------------------------------------  

     Extent 0     :  L1 dba:  0x01000181 Data dba:  0x01000184  

    --------------------------------------------------------  

      

     Second Level Bitmap block DBAs  

     --------------------------------------------------------  

     DBA 1:   0x01000182  

      

    d dump data blocks tsn: 4 file#: 4 minblk 387 maxblk 387  

    [sql] 

    --对t表做一次全表扫  

      

    hr@ORCL> set autot traceonly  

    hr@ORCL> select * from t;  

      

      

    Execution Plan  

    ----------------------------------------------------------  

    Plan hash value: 1601196873  

      

    --------------------------------------------------------------------------  

    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |  

    --------------------------------------------------------------------------  

    |   0 | SELECT STATEMENT  |      |     1 |    20 |     3   (0)| 00:00:01 |  

    |   1 |  TABLE ACCESS FULL| T    |     1 |    20 |     3   (0)| 00:00:01 |  

    --------------------------------------------------------------------------  

      

    Note  

    -----  

       - dynamic sampling used for this statement  

      

      

    Statistics  

    ----------------------------------------------------------  

              0  recursive calls  

              0  db block gets  

              7  consistent gets   --全表扫读了6个块  

              0  physical reads  

              0  redo size  

            469  bytes sent via SQL*Net to client  

            385  bytes received via SQL*Net from client  

              2  SQL*Net roundtrips to/from client  

              0  sorts (memory)  

              0  sorts (disk)  

              1  rows processed  

           这6个块是如何算出来的呢?

    [sql] 

    hr@ORCL> select file_id,block_id,blocks from dba_extents where segment_name='T';  

      

       FILE_ID   BLOCK_ID     BLOCKS  

    ---------- ---------- ----------  

             4        385          8  

           这t段一共用了8个块,分别是385 386 387 388 389 390 391 392 393

           Highwater::  0x01000189  即:4号文件的393号块

           这个可由下面dbms_utility包算出

    [sql] 

    sys@ORCL> select to_number('01000189','xxxxxxxx') from dual;  

      

    TO_NUMBER('01000189','XXXXXXXX')  

    --------------------------------  

                            16777609  

      

    sys@ORCL> select dbms_utility.data_block_address_file(16777609) from dual;  

      

    DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(16777609)  

    ----------------------------------------------  

                                                 4  

      

    sys@ORCL> select dbms_utility.data_block_address_block(16777609) from dual;  

      

    DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(16777609)  

    -----------------------------------------------  

                                                393  

           读了一次段头块:4号文件387号块

           读了高水位之下的388 389 390 391 392 等5个块

           这样一共就读了6个块

           注:

             385是FIRST LEVEL BITMAP BLOCK

             386是SECOND LEVEL BITMAP BLOCK

             

           接着分析我们所dump的内容:  www.2cto.com  

         

    [sql] 

    Low HighWater Mark :  

        Highwater::  0x01000189  ext#: 0      blk#: 8      ext size: 8   

           

           接下来谈谈highwater mark 和 low highwater mark

           

           low high water mark与high water mark 之间可能存在formated block也可以可能存在 unformatted block

             

           先来理清dba_tables里面的字段blocks的含义

           

           dba_tables.blocks记录的是分析得到的 formatted block 的总数

           而 low hwm 和 high hwm之间可能同时存在 formatted block 和 unfomatted block

           所以准确地说  blocks 不能代表 low hwm 或high hwm

           如果 low hwm 和 high hwm之间正好没有formatted block时,dba_tables.blocks和 low hwm下的blocks一致

           

           那么什么是Oracle中未格式化的块呢?

           

           未格式化,意思就是这个块,已经是属于这个段了,但是还保留着原来的样子没动

           格式化就是把块中的数据清除掉,并把块头改为这个对象的

           MSSM表空间中的段,只有一个高水位,高水位下的块都是格式化了的

           但是ASSM表空间中的段,有两个高水位:低高水位和高高水位

           即上文trc里的:Highwater::  0x01000189和Low HighWater Mark Highwater::  0x01000189

           低高水位下的块全部是格式化了的

           但是低高水位和高高水位之间的块,则可能是格式化了的,也可能是没有

           

           现在的t的高高水位是file 4,block 393;其低高水位是file 4,block 393

           

           我们现在再来看一下t现在data_object_id是多少:

    [sql] 

    hr@ORCL> select object_id,data_object_id from dba_objects where object_name='T';  

      

     OBJECT_ID DATA_OBJECT_ID  

    ---------- --------------  

         52713          52714  

           这里很明显t的data_object_id大于object_id

           也就是说,在t上曾经发生过move或truncate操作

           注意,对于truncate操作而言,truncate后其data_object_id不一定就是在原先的data_ object_id上加1

    [sql] 

    sys@ORCL> select to_char('52714','XXXXXXXX') from dual;  

      

    TO_CHAR('  

    ---------  

         CDEA  

           换句话说,t中现在在其低高水位和其高高水位之间的block,只要这个block上记录的data _object_id不等于CDEA

           我们可以通过dump里面的Block header dump部分中的seg/obj来判断其data_object_id 是否与段编号相等

           那么这个block 就是一个未格式化的块

           也就是说,可以通过data_object_id来确定块是在HWM和LHWM的位置

           

           那么Oracle为什么要增加低高水位设置?出于什么目的?全表扫描时,是到低高水位, 还是到高高水位?

           

           Oracle设计有一个原则,就是把一个大操作分散到很多小操作中,以保证某个大操作不会 花费太长时间

           无论是延迟提交,还是什么,都体现了这种思想,这和Linux的理念有异曲同工之妙哦

           而低高水位线与高高水位线结合,正是这种思想的体现

           可以不用一次性格式化所有新分配的块,留一部分给下次操作来完成

           

           全表扫描时,通常都是读至低高水位线,然后根据位图去读低高与高高之间格式化过的块, 避开未格式化的块

         

           如何查看HWM?如何知道HWM下有多少空闲的空间?

           

           最实用的方法就是dump segment_header,速度快,而且对应用没有影响

           而且,trc里面的"#blocks in seg. hdr's freelists:"可以告诉我们HWM下有多少空闲块

           这里需要注意,如果dba_segments.freelist_groups > 1,那么freelist不再segment header中

           比如,freelist_group = 3 ,则你便要分别dump header后面的3个块,来看每个group 的freelist的个数

           

           那么如何降低HWM呢?  www.2cto.com  

            

           ① expdp/impdp

           ② 10G及以后的版本可以采用shrink,需要注意的是,表所在表空间须为自动段空间管理

              alter table tab_name enable row movement;

              alter table tab_name shrink space;

           ③ 使用move,不过在Move期间,会影响到DML语句,如UPDATE,也需要考虑空间问题

              总之move会锁表 而且是TM  另外还会影响index,所以,之后记得rebuild index

              alter table move tab_name;  在当前表空间中move

              alter table move tab_name tablespace tbs_name;  将其move到其他表空间

           ④ CTAS  然后rename,rebuild index

           ⑤ 在线重定义

            等等.......

    All for u
  • 相关阅读:
    Flex4之关于Embed外部资源的使用方法总结
    Flex tree的开发 后台数据连接
    Flex4之Tree开发
    Flex自定义组件开发
    解决AS3请求数据的“安全沙箱冲突”问题
    purMVC代码备份
    译:如何配置Red5应用程序
    关于RED5——配置文件详解
    关于socket使用Amf直接进行对象传输的
    垃圾回收机制
  • 原文地址:https://www.cnblogs.com/ayumie/p/7685647.html
Copyright © 2011-2022 走看看