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

ORACLE高水位线(HWM)和shrink table(表空间收缩)

原创 天之道 2023-05-15
986

一、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 [<null> | 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' ';

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

评论