[ORACLE]数据库高水位线(转载)

一、ORACLE高水位线(HWM)
       1.1 ORACLE用HWM来界定一个段中使用的块和未使用的块。
       当我们创建一个表时, ORACLE就会为这个对象分配一个段, 在这个段中即使我们未插入任何记录, 也至少有一个区被分配, 第一个区的第一个块就称为段头块(SEGMENT_HEADER), 段头中就储存了一些信息, 其中HWM的信息就存储在此。此时, 因为第一个区的第一块用于存储段头的一些信息, 虽然没有存储任何实际的记录, 但也算是被使用, 此时HWM是位于第2个块, 当我们不断插入数据后, 第一个块已经放不下后面新插入的数据, 此时, ORACLE将高水位之上的块用于存储新增数据, 同时, HWM本身也向上移, 也就是说, 当我们不断插入数据时, HWM会不断上移, 这样, 在HWM之下的, 就表示使用过的块。 HWM之上的就表示已分配但从未使用过的块。
        1.2 HWM在插入数据时, 当现有空间不足而进行空间的扩展时会向上移, 但删除数据时不会往下移。
        1.3 HWM本身的信息是存储在段头, 在段空间是手工管理方式时, ORACLE是通过FREELIST(一个单向链表)来管理段内的空间分配, 在段空间是自动管理方式时, ORACLE是通过BITMAP来管理段内的空间分配。
        1.4 ORACLE的全表扫描是读取高水位标记(HWM)以下的所有块。
         所以问题就产生了, 当用户发出一个全表扫描时, ORACLE始终必须从段一直扫描到HWM, 即使它什么也没有发现。 该任务延长了全表扫描的时间
二、SHRINK(收缩) TABLE(表空间收缩)
       从10g开始, ORACLE开始提供SHRINK的命令, 假如我们的表空间中支持自动段空间管理(ASSM), 就可以使用这个特性缩小段, 即降低HWM。 10g的这个新特性, 仅对ASSM表空间有效, 否则会报ORA-10635: Invalid segment or tablespace type。
       如果经常在表上执行DML操作, 会造成数据库块中数据分布稀疏, 浪费大量空间。 同时也会影响权标扫描的性能。 因为全表扫描需要访问更多的数据块。从oracle10g开始, 表可以通过SHRINK来重组数据使数据分布更紧密, 同时降低HWM释放空闲数据块。
       segment shrink分为两个阶段:
       1 数据重组(compact): 通过一系列insert、delete操作, 将数据尽量排列在段的前面。 在这个过程中需要在表上加RX锁, 即只在需要移动的行上加锁。由于涉及到rowid的改变, 需要enable row movement, 同时要disable基于rowid的trigger。  这一过程对业务影响比较小
       2. HWM调整, 第二阶段是调整HWM位置, 释放空闲数据块。此过程需要在表上加X锁, 会造成表上的所有DML语句阻塞。 在业务特别繁忙的系统上可能造成比较大的影响
       shrink space语句两个阶段都执行。
       shrink space compact只执行第一个阶段。如果系统业务比较繁忙, 可以先执行shrink space compact重组数据, 然后在业务不忙的时候再执行shrink space降低HWM释放空闲数据块。
        shrink必须开启行迁移功能。 alter table table_name enable row movement ; 注意, alter table table_name row movement语句会造成引用表table_name的对象(如存储过程、包、视图等)变为无效。 需要执行utlrp.sql来编译无效的对象。
          语法:   alter table table_name shrink space [ | compact | cascade] ;
         alter table table_name shrink space compact ; 收缩表, 相当于把块中数据打结实了, 但会保持high water mark 。
         alter table table_name shrink space ; 收缩表, 降低high water mark 。
         alter table table_name shrink space cascade ; 收缩表, 降低high water mark, 并把相关索引也要收缩一下。
         alter index idx_name shrink space ; 回缩索引。
         普通表
         Sql脚本,改脚本会生成相应的语句
         select'alter table '||table_name||' enable row movement;'||chr(10)||'alter table '||table_name||' shrink space;'||chr(10)from user_tables;
         select'alter index '||index_name||' shrink space;'||chr(10)from user_indexes;
         分区表
         进行shrink space时 发生ORA-10631错误.shrink space有一些限制.
         在表上建有函数索引(包括全文索引)会失败。
         Sql脚本,改脚本会生成相应的语句
         select 'alter table '||table_name||' enable row movement;'||chr(10)||'alter table '||table_name||' shrink space;'||chr(10) from user_tables where ;
         select 'alter index '||index_name||' shrink space;'||chr(10) from user_indexes where uniqueness='NONUNIQUE' ;
         select 'alter table '||segment_name||' modify subpartition '||partition_name||' shrink space;'||chr(10) from user_segments where segment_type='TABLE SUBPARTITION' ';

你可能感兴趣的:(日常报错问题,ORACLE)