DB2的日志利用率通常指事务日志空间中被已分配但尚未释放的空间所占的百分比。在官方监控中,它对应LOG_UTILIZATION_PERCENT字段,很多运维人员直接称它为log utilization。日志利用率本身不是故障,但如果持续逼近100%,意味着事务日志已经没有可扩展空间,数据库会开始拒绝新的日志写入,现象包括SQL报错SQL0964C、事务被强制回滚、甚至整个数据库进入只读或不可用状态。因此,对日志利用率的监控和干预是DB2日常运维中非常基础但关键的一环。

一、日志利用率从哪里看:核心监控命令
在DB2 9.7及之后的版本中,最直接的监控方式是查询管理视图SYSIBMADM.LOG_UTILIZATION。这个视图把当前数据库的日志使用情况汇总得非常清楚,包括日志利用率百分比、已用日志空间、可用日志空间、日志使用峰值等。下面这条SQL可以快速获取当前数据库的日志压力:
SELECT
DB_NAME,
LOG_UTILIZATION_PERCENT,
TOTAL_LOG_USED_KB,
TOTAL_LOG_AVAILABLE_KB,
TOTAL_LOG_USED_TOP_KB,
DBPARTITIONNUM
FROM SYSIBMADM.LOG_UTILIZATION
这里LOG_UTILIZATION_PERCENT就是我们要看的日志利用率。需要特别提醒的是,这个数字反映的是当前事务日志空间的使用比例,它并不等于日志文件系统磁盘占用率。即使日志利用率只有30%,如果文件系统已经写满,同样会触发日志写入失败。反过来,日志利用率飙到95%以上,但文件系统还剩很多空间,数据库也可能因为主日志和辅助日志数量用尽而报错。所以排查日志问题时,必须同时观察数据库日志参数和操作系统层面的磁盘空间。
除了管理视图,数据库快照也能提供类似信息。在旧版本或者某些定制监控场景中,可以通过GET SNAPSHOT FOR DATABASE命令获取日志空间使用情况。快照输出中的Log space used by the database和Maximum total log space就是已用和总可用的日志空间。对于频繁出现的日志利用率告警,建议把上述查询做成脚本,每隔五分钟采集一次,并记录对应时间段内的活跃事务数量,这样便于事后追溯是哪一类业务操作推高了日志使用量。
二、日志利用率飙高的五个常见原因
日志利用率突然升高,通常不是数据库参数本身有问题,而是某类事务行为发生了变化。最常见的诱因是长时间未提交的事务。只要一个事务没有执行COMMIT或ROLLBACK,它产生的日志就始终被占用,无法被释放或归档。即使这个事务只修改了一行数据,如果一直悬挂着,后续所有日志空间都可能在几个小时后被逐渐填满。定位这类事务可以使用MON_GET_UNIT_OF_WORK表函数,按事务启动时间排序,找出运行时间最长的活跃事务。
SELECT
APPLICATION_HANDLE,
UOW_START_TIME,
UOW_LOG_SPACE_USED,
APPL_STATUS
FROM TABLE(MON_GET_UNIT_OF_WORK(NULL, -2)) AS T
WHERE UOW_LOG_SPACE_USED > 0
ORDER BY UOW_START_TIME ASC
第二个常见原因是批量数据处理任务没有设置合理的提交间隔。例如一个删除历史数据的存储过程,如果使用DELETE FROM大表而不分批提交,日志会持续增长,直到整个删除完成或日志空间耗尽。第三个原因是日志归档或日志镜像速度跟不上。归档日志如果写到慢速网络存储,或者镜像日志路径与活动日志路径在同一块磁盘上,都可能拖慢日志释放速度。第四个原因是辅助日志数量配置过少。DB2在主日志文件写满后会按需分配辅助日志,如果辅助日志数量为零或很少,日志空间弹性不足,遇到突发大事务就会快速触顶。第五个原因是高并发小事务叠加,虽然单个事务日志不多,但同一时刻大量事务同时持有日志,峰谷叠加也会把利用率推高。
这些原因往往不是单独出现的。实际故障中,很可能是批量作业开启了一个大事务,同时又赶上业务高峰期的小事务并发,再加上归档目录IO抖动,三个因素叠加导致日志利用率在几分钟内从40%冲到100%。所以在排查时不要只盯着一个应用连接,要把应用事务、数据库参数和IO路径放在一起分析。
三、降低日志利用率的配置与代码调整
优化日志利用率的第一条思路是压缩单个事务的日志占用。对于批量作业,最有效的办法是分批提交。例如把一次删除一千行改为每次删除两百行就COMMIT一次。对于Java或C应用,尽量把业务流程中的只读查询和写入操作拆开,避免把查询也放在事务里拖长锁和日志持有时间。对于INSERT、UPDATE、DELETE操作,使用游标或分页方式,每处理一批就提交,可以显著降低日志峰值的持续时间。
第二条思路是调整数据库日志相关参数。DB2的日志配置包括主日志文件大小、主日志文件数量、辅助日志文件数量等。可以通过数据库配置参数查看:
SELECT
NAME,
VALUE,
VALUE_FLAGS
FROM SYSIBMADM.DBCFG
WHERE NAME IN ('logfilsiz', 'logprimary', 'logsecond', 'logbufsz', 'logarchmeth1')
其中logfilsiz是单个日志文件的大小,单位是4KB页;logprimary是主日志文件数量;logsecond是辅助日志文件数量。如果当前日志利用率经常接近100%,可以适当增加logprimary或logsecond。但要注意,单纯增大日志空间只是给大事务续命,如果日志文件系统磁盘空间有限,过大的日志配置反而可能导致归档空间不足。通常的做法是先把logsecond设置为一个合理值,比如20到50,让数据库在突发压力下能自动扩展日志空间,同时监控文件系统使用率。对于归档日志,建议把logarchmeth1配置为磁盘归档路径,并确保归档目录和活动日志目录不在同一物理磁盘上,避免IO争抢。
第三条思路是使用技术手段减少日志写入。对于确实无法拆分的长事务,可以考虑在会话级别使用NOT LOGGED INITIALLY选项,这个选项可以让后续的CREATE TABLE、INSERT等操作在事务初始阶段不记日志,但要注意一旦事务回滚或数据库崩溃,这些表可能被标记为不可用,只适合临时表和可重建的数据。另一个方法是评估是否可以使用LOAD命令替代大量INSERT或DELETE操作。LOAD本身记录日志的方式与普通DML不同,配合NONRECOVERABLE或COPY NO选项可以显著降低日志压力,但同样会影响可恢复性,需要根据业务对数据恢复的要求谨慎选择。
修改日志参数需要重启数据库实例或重新激活数据库才能生效,并且要和业务窗口配合。生产环境建议先在测试环境验证参数调整后的日志行为,再安排变更窗口执行。日志利用率的优化不是一次性的,应当结合监控告警、事务审计和容量规划形成长期机制。