共计 4752 个字符,预计需要花费 12 分钟才能阅读完成。
本篇内容主要讲解“数据库表空间高水位的知识有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“数据库表空间高水位的知识有哪些”吧!
一、对于手动段空间管理(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 )
begin
dbms_output.put_line( rpad(p_label,40, .) ||p_num );
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);
/
我们知道,在 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 各种技术的认识和了解后,我们才能够制定出适合我们需要的空间维护手段。
到此,相信大家对“数据库表空间高水位的知识有哪些”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!