DB2提供了多种数据压缩技术,包括行压缩、页压缩和自适应压缩等。压缩可以显著降低存储空间占用,减少I/O操作,但压缩和解压过程会消耗CPU资源,如果表的数据特征不适合压缩,收益可能微乎其微。因此,在决定对表启用压缩之前,准确评估压缩率是一项关键工作;在启用之后,持续监控压缩率变化则能帮助DBA及时发现数据增长、分布变化或压缩失效等问题。压缩率通常定义为压缩前大小与压缩后大小的比值,或者用节省空间的百分比来表示。例如,一个表原始数据占用10GB,压缩后占用3GB,那么压缩率为3.33:1,节省空间70%。这个数值越高,说明压缩效果越好。

DB2内部通过字典压缩和基于页的压缩算法来消除重复值。当表中存在大量重复字符串、固定长度列未充分使用、或者数据按某种规律重复出现时,压缩率会比较高。反过来,如果表中数据接近随机分布,例如加密后的哈希值、已经压缩过的二进制内容,压缩算法很难找到冗余,压缩率可能接近1,甚至因为元数据开销导致压缩后更大。所以评估压缩率不能只看表大小,还要分析列的数据分布特征。
一、DB2压缩率评估的核心方法与系统函数
DB2提供了专门的表函数来评估实际压缩效果和预估压缩潜力。最常用的是ADMIN_GET_TAB_COMPRESS_INFO,它能够返回指定表在启用压缩后的实际压缩信息,包括压缩前大小、压缩后大小、压缩率、节省空间百分比以及压缩类型等。这个函数接受两个参数:模式名和表名。调用方式如下面的SQL语句所示。
SELECT
TABSCHEMA,
TABNAME,
COMPRESSION_ATTR,
ROW_COMPRESSED,
PAGE_COMPRESSED,
TOTAL_SAVED_PERCENT,
COMPRESS_RATIO
FROM
TABLE(SYSPROC.ADMIN_GET_TAB_COMPRESS_INFO('MYSCHEMA', 'MYTABLE')) AS T
需要注意的是,ADMIN_GET_TAB_COMPRESS_INFO反映的是已经启用压缩的表的状态。如果表尚未压缩,但DBA希望提前估算压缩收益,可以使用ADMIN_GET_TAB_COMPRESS_INFO_EST函数。该函数基于表统计信息和采样数据来模拟压缩效果,返回预估的压缩率和节省空间比例。预估结果与实际执行压缩后的结果可能存在偏差,因为在正式压缩时,DB2会构建完整的字典,而采样只能捕获数据分布的一个子集。对于数据倾斜明显的表,采样比例过低可能会导致预估偏差较大。
另一个关键维度是区分行压缩与页压缩。行压缩通过复用行内的重复值来减少存储,而页压缩则在同一数据页内寻找跨行的重复模式。DB2的压缩类型属性COMPRESSION_ATTR可以取值为B(行和页压缩均启用)、R(仅行压缩)、P(仅页压缩)或N(未启用压缩)。DBA需要根据表的访问模式来选择压缩类型:如果表经常整页扫描,页压缩可能带来更好的I/O节省;如果主要是按索引访问单行或多行,行压缩的CPU开销相对更低。
除了系统函数,DB2的db2pd工具也能输出压缩相关信息。例如db2pd -d sample -tablespaces可以查看表空间的页使用情况,结合表的物理大小变化间接评估压缩效果。但更精确的压缩率统计还是建议使用SQL表函数,因为它们直接取自数据库内部的压缩元数据。
二、DB2压缩率监控的常用视图与脚本实现
持续监控压缩率是保障长期存储效率的关键。数据表会不断插入、更新和删除数据,原本适合压缩的数据分布可能随着时间推移发生变化。例如,初期表中一个字符列的值集中在少数几种状态,行压缩效果非常好;后来业务扩展,该列出现了大量互不相同的值,压缩率就会明显下降。如果不进行监控,DBA可能意识不到存储空间被重新撑大。
DB2的系统视图SYSIBMADM.ADMINTABCOMPRESSINFO汇总了所有表的压缩状态和压缩统计信息。这个视图基于内存中的实时数据,开销很低,适合用于日常查询。下面的SQL语句可以列出数据库中压缩率低于2的所有表,帮助定位压缩收益不明显的对象。
SELECT
TABSCHEMA,
TABNAME,
COMPRESSION_ATTR,
TOTAL_SAVED_PERCENT,
COMPRESS_RATIO,
ROW_COMPRESSED,
PAGE_COMPRESSED
FROM
SYSIBMADM.ADMINTABCOMPRESSINFO
WHERE
COMPRESS_RATIO < 2
AND COMPRESSION_ATTR <> 'N'
ORDER BY
COMPRESS_RATIO ASC
为了观察压缩率随时间的变化趋势,DBA可以建立一个监控表,定期将ADMINTABCOMPRESSINFO中的关键字段快照保存下来。这样做的好处是当压缩率突然下降时,可以通过历史数据回溯变化发生的时间点,并与应用发布、批量加载等事件进行关联分析。下面是一个简单的快照表结构示例。
CREATE TABLE COMPRESSION_MONITOR_SNAPSHOT (
SNAPSHOT_TIME TIMESTAMP NOT NULL,
TABSCHEMA VARCHAR(128) NOT NULL,
TABNAME VARCHAR(128) NOT NULL,
COMPRESSION_ATTR CHAR(1),
COMPRESS_RATIO DECIMAL(10,2),
TOTAL_SAVED_PERCENT DECIMAL(5,2),
PRIMARY KEY (SNAPSHOT_TIME, TABSCHEMA, TABNAME)
)
然后使用一个定时任务(例如DB2的ADMIN_TASK_ADD或者外部调度工具)执行INSERT SELECT语句,将当前压缩信息写入快照表。监控频率可以根据表的变动速度灵活设置:对于每天大量批量写入的表,建议每天一次;对于变化缓慢的历史表,每周一次即可。快照数据积累后,可以通过简单的趋势查询发现异常点,例如压缩率从5下降到1.5,说明表的数据特征发生了根本变化。
除了数据库自带的视图,操作系统层面的存储监控也不能忽视。压缩率虽然反映了逻辑数据与物理存储的比值,但实际占用的磁盘空间还要考虑表空间容器、索引和日志等因素。DBA应该将DB2报告的压缩率与文件系统层看到的数据文件大小进行交叉验证,确保压缩收益真正落到了存储成本上。
三、压缩率评估与监控的实践调优策略
当评估或监控发现压缩率低于预期时,DBA可以采取多种措施进行调优。第一步通常是检查表的统计信息是否新鲜。DB2的压缩字典和统计信息会影响压缩算法的效率,如果统计信息过期,压缩预估和实际执行都可能不准确。运行RUNSTATS命令更新统计信息后,重新评估压缩率,有时会看到明显改善。
RUNSTATS ON TABLE MYSCHEMA.MYTABLE
WITH DISTRIBUTION AND DETAILED INDEXES ALL
第二步是调整压缩类型。如果当前只启用了行压缩,可以改为同时启用行压缩和页压缩,通过设置表的COMPRESS YES并指定VALUE COMPRESSION或ROW COMPRESSION来实现。需要注意的是,修改压缩类型需要重新组织表(REORG),这会产生一定的维护窗口和日志开销。对于大型表,可以在业务低峰期分批次执行。
第三步是针对特定列优化数据布局。DB2允许对变长字符列使用VALUE COMPRESSION来压缩尾随空格,对固定长度列如果实际存储值很短,可以考虑改为变长类型并配合压缩。例如一个CHAR(200)列实际值平均只有10个字符,将其改为VARCHAR(200)并启用压缩,压缩率可以大幅度提升。不过这涉及表结构变更,需要评估应用兼容性和SQL绑定问题。
最后,监控阈值应该结合业务目标来设定。一个合理的做法是:当压缩率低于2(节省空间小于50%)时,发送提醒通知DBA;当压缩率低于1.2(节省空间小于17%)时,发出警告并启动自动评估流程。阈值的设定不能一刀切,需要根据存储成本与CPU成本的相对权重来调整。对于CPU非常紧张的服务器,即使压缩率很高,也可能需要降低压缩级别或关闭部分表的压缩。
压缩率的评估和监控并不是一次性工作,而是一个循环反馈的过程。通过定期评估新表和已有表的数据特征,结合持续监控中的异常检测,DBA可以逐步建立一套适合自身业务的数据压缩管理规范。最终目标是在存储节省和性能稳定之间找到动态平衡,让DB2的压缩能力真正为成本优化服务。