在业务繁忙时,PostgreSQL中的WAL生成量非常大。checkpointer进程会定期清理过期的WAL日志,但在实际生产中,一些不恰当的使用方式可能导致WAL日志未被清理,从而占用大量存储空间。本文介绍主库和只读库发生WAL日志堆积问题时的排查方法。
背景信息
WAL是PostgreSQL中确保数据安全、提高系统可靠性和性能的关键组件。通过WAL机制,PostgreSQL能够在各种故障情况下保证数据不丢失,并且能够可靠地进行恢复。
主库日志堆积
WAL日志堆积问题发生在主库时,可以进行以下排查。
非活跃的复制槽或消费端未及时上报LSN
复制槽(replication slot)是PostgreSQL高可用性和灾难恢复策略的关键工具,其最主要的作用是防止WAL被删除,从而避免复制中断。然而,当复制槽处于非活跃状态时,未被清理的WAL日志会不断累积,导致日志增长过快。
消费端未及时上报LSN时,会导致WAL日志不断增长。
通过系统视图pg_replication_slots可以查看复制槽的各种信息(包括LSN信息)。例如,可以通过以下SQL语句来判断复制槽延迟删除WAL日志的大小。
SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_insert_lsn(), restart_lsn)) AS delay_size
FROM pg_replication_slots;
如果查询得到的结果较大或与WAL日志堆积量匹配,请根据业务需求评估并删除相应的复制槽。
错误的参数设置
wal_keep_segments、wal_keep_size和max_wal_size参数设置过大都可能会导致实例保留大量WAL日志,请检查这些参数配置并根据业务需求进行调整。
VACUUM风暴和大量写入
VACUUM风暴通常是指在数据库中同时发生大量的自动或手动VACUUM操作,这些操作可能会产生大量WAL日志,从而导致I/O负载显著增加,影响数据库性能,同时也可能导致WAL无法被及时清理。建议您根据业务需求合理配置VACUUM参数,规划VACUUM操作的执行时间。
大规模写入时出现的情况与VACUUM风暴相似,请根据业务需求合理安排数据写入。
只读库日志堆积
WAL日志堆积问题发生在只读库时,可以进行以下排查。
复制延迟
比较常见的是WAL日志在只读库上的replay延迟,可能的原因有:
只读库上有长时间运行的事务,与WAL日志的replay产生冲突。请根据业务需求评估并调整相关参数(hot_standby_feedback和max_standby_streaming_delay)。
例如,在hot_standby_feedback=off,且max_standby_streaming_delay设置较大时,只读库上运行长事务可能会导致replay延迟。
主库和只读库的规格配置存在差异。如果只读库的计算和存储配置低于主库,可能会导致复制延迟,从而导致未replay的WAL无法清理。请根据业务需求评估并选择合理的只读库配置。
其他原因
对于RDS PostgreSQL实例,如果上述排查后仍未解决WAL堆积的问题,可联系RDS PostgreSQL技术支持进行解决。
相关文档
RDS PostgreSQL实例,您还可以通过手动删除非活跃的Replication Slot来让RDS PostgreSQL内核自动清理WAL日志。具体方法,请参见WAL日志管理。