本篇内容主要讲解“数据库表空间高水位的知识有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“数据库表空间高水位的知识有哪些”吧!
一、对于手动段空间管理(MSSM)的表空间
-
高水位标记(HWM)是指这个段空间中已使用和未使用的block的分界线,HWM之上的空间在格式化之前不能被使用。即在HWM以上的数据块均为未格式化的块,这些未格式化的块在格式化之前是不能被 insert数据的。
-
在数据库事务中,当请求新的空闲块并且现有空闲列表中的块不能满足要求时,HWM会向上移动,然后格式化一组数据块并加入Free List提供使用。
-
在HWM之下的数据块也可能存在空闲的情况,当数据被删除时,数据块被释放重新回到FreeList,又可以被其它数据变更所用,HWM通常只能向上增长,不会自动收缩。
-
HWM会影响Oracle执行全表扫描时的读取行为,对于全表扫描操作,Oracle必须读取HWM下的所有数据块,如果一个数据表由于DELETE操作删除了大部分记录,但是HWM并不会降低,所以再次执行全表扫描时,Oracle仍然需要读取对象段中所有的数据块(也就是HWM以下的所有数据块)
-
对于通常的对象,我人不太需要关注其HWM的影响,但是如果表的删除操作非常频繁,表中的在部分Block已经为空,那么可能就需要关注其空间性能问题。
二、简单的估算表中的空块的数据
通过dba_tables视图查出表所占用的blocks数量
SELECT blocks FROM dba_tables WHERE table_name='表名';
通过rowid计算出实际表中的数据占用blocks数量
目前Oracle(8i以后版本)的rowid格式是 OOOOOO.FFF.BBBBBB.RRR共18位,占用10个字节,代表80位二进数,
其中 O 代表 对象号,F代表文件号,B代表块号,R代表行号,这80位的方式 为:
32bit obj# + 10bit rfile# + 22bit block# + 16bit row#
因此我们通过这样一个SQL就可以大概算出表占用的block数量(取rowid的前15位)
SELECT COUNT(DISTINCT(SUBSTR(ROWID,1,15))) FROM 表名;
两步得出来的结果相除就可以得出使用数据块占用比和空块的占用比
三、对于自动段空间管理(ASSM)的表空间
-
对于ASSM方式管理的段,在其段头是会存在两种高水位标记,分别是LHWM和HHWM,即低高水位和高高水位
-
由于在ASSM管理方式下不存在Free List ,所以LHWM和HHWM概念被引入用于实现段空间管理,在ASSM管理模式下,当一个会话向表中插入数据时,数据库首先格式化一个位图块(而不是像以前那样格式化一组块),这个位图块代替Free List用于跟踪段中的数据块的状态变化,数据库通过位图块去寻找空闲块并在使用前对其进行格式化。
-
ASSM管理方式下的Segment 的LHWM和HHWM的特点如下:
所有在HHWM以上的数据块一定是未格式化的块
所有在LHWM以下的数据块一定是格式化的块
在LHWM和HHWM之间的数据块有可能是格式化的也有可能是未格式化的
Oracle在全表扫描一个Segment时,会一直扫描到HHWM为止
-
对于使用ASSM管理的Segment,可以通过Oracle提供的DBMS_SPACE直接计算其空间使用情况
-
create or replace procedure show_space_assm( p_segname in varchar2, p_owner in varchar2 default user, p_type in varchar2 default 'TABLE' ) as l_fs1_bytes number; l_fs2_bytes number; l_fs3_bytes number; l_fs4_bytes number; l_fs1_blocks number; l_fs2_blocks number; l_fs3_blocks number; l_fs4_blocks number; l_full_bytes number; l_full_blocks number; l_unformatted_bytes number; l_unformatted_blocks number; procedure p( p_label in varchar2, p_num in number ) is begin dbms_output.put_line( rpad(p_label,40,'.') ||p_num ); end; begin dbms_space.space_usage( segment_owner => p_owner, segment_name => p_segname, segment_type => p_type, fs1_bytes => l_fs1_bytes, fs1_blocks => l_fs1_blocks, fs2_bytes => l_fs2_bytes, fs2_blocks => l_fs2_blocks, fs3_bytes => l_fs3_bytes, fs3_blocks => l_fs3_blocks, fs4_bytes => l_fs4_bytes, fs4_blocks => l_fs4_blocks, full_bytes => l_full_bytes, full_blocks => l_full_blocks, unformatted_blocks => l_unformatted_blocks, unformatted_bytes => l_unformatted_bytes); p('free space 0-25% Blocks:',l_fs1_blocks); p('free space 25-50% Blocks:',l_fs2_blocks); p('free space 50-75% Blocks:',l_fs3_blocks); p('free space 75-100% Blocks:',l_fs4_blocks); p('Full Blocks:',l_full_blocks); p('Unformatted blocks:',l_unformatted_blocks); end; /
-
我们知道,在ASSM下,block的空间使用分为free space: 0-25%,25-50%,50-75%,70-100%,full 这样5中情况,show_space_assm会对需要统计的table汇总这5中类型的block的数量。
我们来看table HWM1的空间使用情况:
SQL> exec show_space_assm('HWM1','DLINGER');
free space 0-25% Blocks:……………..0
free space 25-50% Blocks:……………1
free space 50-75% Blocks:……………0
free space 75-100% Blocks:…………..8
Full Blocks:……………………………….417
Unformatted blocks:…………………….0
这个结果显示,table HWM1,full的block有417个,free space 为75-100% Block有8个,free space 25-50% Block有1个。当table HWM下的blocks的状态大多为free space较高的值时,我们考虑来合并HWM下的blocks,将空闲的block释放,降低table的HWM。
四、降低高水位的方法
-
导出/导入与TRUNCATE结合
truncate命令可以降低高水位,但是可能这种方法的场景非常少
可以通过EXP导出数据或者使用CTAS创建一张香表,然后Truncate表,再导入或者insert回数据,但是对于不间断服务的数据表并不合适
-
RENAME和INSERT结合
对于连续使用的数据表,如果数据是以写为主的日志类数据,则可以通过RENAME将数据表更名,然后按原来的结构重建数据表,此时插入操作可以恢复,这个过程非常迅速,对于数据库影响较小,然后可以将RENAME表中的数据插入回来,这就完成了数据整理,HWM可以降低,这种方法适用于写为主的业务类型,不适合增删改查频繁的对象。
-
在线重定义(DBMS_REDEFINITION)
从Oracle 9I开始引入了在线重定义特性,通过DBMS_REDEFINITION包可以对表进行在线重定义,如修改表字段名称、增加字段等,当然也可以借用这个包进行空间整理。
在线重定义过程中,Oracle通过中间的临时表来记录中间变化数据,完成重定义后可以将数据整合到重定义表中,数据库的正常操作可以继续进行。
-
Shrink特性
从Oracle 10g开始引入了用于支持在线空间重整,这僦是联机段空间回收功能 (Shrink Database Segments Online)
联机段收缩公对ASSM表空间中的表有效,Shrink的本质就是对表执行一系列的DML操作,删除表末端的稀疏行,并在表的顶端重新插入。通过这样的一系列操作,可以填满表段中的“漏洞”空间,逐步将所有剩余空间留在表的末端,然后Oracle可以重置该表的HWM,释放空间。由于Shrink是针对数据行进行处理的 ,在表上会获得行级排他锁,所以并不会影响全表的DML操作,这也是Online的意义所在,但是Shrink可能会产生大量Redo,影响归档量,在操作时需要考虑。
由于回收段空间需要移动行数据,数据的rowid会发生变化,索引会被同时维护,也因此在执行Shrink之前,需要设置表的ENABLE ROW MOVEMENT属性。
但需要注意的是,由于段空间重整是通过DML操作来完成的,所以会产生额外的redo,如果数据表非常大,那么产生的Redo可能是生产接受的
-
alter table 表名 enable row movement;
-
alter table 表名 shrink space;
不支持Shrink的表:
IOT mapping tables
Tables with rowid based materialized views
Tables with function-based indexes
SECUREFILE LOBs
Compressed tables
-
Move对象
通过Move操作移动对象,可以降低HWM,但是Move之后,索引需要重建,而且在Move的过程中会影响在线应用,所以这种方法使用较为有限
-
其它方法
空间的重建始终是一个难题,各种方法都是以一定的性能牺牲为代价的,这就使得很多方法在实际的生产过程中并不可用,所以更好的办法应该是从应用入手、从规划入手,从最开始就能够避免一些可能出现的问题。
在最常采用的方法中,分区是一个常用的手段,涉及大量数据变更的数据表,很多可以通过分区来处理,由于分区表可以针对分区进行诸如DROP、TRUNCATE等操作,从而可以很容易地对分区进行维护,进而解决一系列的空间问题。
当然分区并不是万能的,其适用环境也是有限的,所以真正能够解决问题的方法还是来自己我们自己,通过对Oracle各种技术的认识和了解后,我们才能够制定出适合我们需要的空间维护手段。
到此,相信大家对“数据库表空间高水位的知识有哪些”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/205327.html