Postgres 9.6 WAL文件归档后未自动删除问题及清理方法咨询
问题分析与解决方案
一、为什么pg_xlog里的WAL文件没被删除?
首先得明确一个核心逻辑:你的archive_command只负责把WAL文件复制到归档目录,PostgreSQL本身不会因为归档完成就立刻删除pg_xlog里的原文件!归档成功只是标记这个WAL为「可被清理」,但实际删除要满足几个关键条件,和你的主备架构、WAL保留配置直接相关:
先确认归档是否真的成功
虽然日志没报错,但可以通过系统视图验证归档状态:SELECT archived_count, failed_count, last_archived_wal FROM pg_stat_archiver;如果
failed_count为0,说明所有触发归档的WAL都复制成功了,那没删除就是保留策略的问题;如果有失败,得排查rsync的细节(比如归档目录权限、磁盘空间不足等)。主库的WAL保留规则在起作用
一主一备架构下,主库会自动保留备库还未接收/重放完成的WAL,另外还有两个核心配置控制保留:wal_keep_segments:指定主库额外保留的WAL文件数量(即使已归档),默认值可能是0,但如果备库偶尔落后,主库会临时保留更多WAL;max_wal_size/min_wal_size:控制WAL文件的总大小阈值,当pg_xlog目录的WAL总大小超过max_wal_size时,PostgreSQL会触发清理已归档且不再需要的WAL。
你可以查询当前配置:
SHOW wal_keep_segments; SHOW max_wal_size;备库的复制进度影响主库清理
如果备库的重放进度落后于主库,主库会一直保留备库还没处理的WAL。你可以在主库上查看备库状态:SELECT client_addr, state, replay_lsn FROM pg_stat_replication;对比主库当前LSN(
SELECT pg_current_wal_lsn();),如果replay_lsn差距很大,说明备库还在追赶,主库不会删除这些未处理的WAL。
二、主备架构下旧WAL文件的删除流程
主库侧的清理逻辑
- WAL生成与归档触发:当主库切换到新的WAL文件(比如写满、手动切换或checkpoint触发),会调用
archive_command将旧WAL复制到归档目录; - 标记可清理:如果
archive_command返回成功(返回码0),PostgreSQL会标记该WAL为「已归档,可清理」; - 条件判断后删除:自动清理进程(由checkpoint触发,或定期运行)会检查每个已归档的WAL:
- 是否超过
wal_keep_segments设置的保留数量; - 是否所有备库都已接收并重放完成该WAL;
- 是否pg_xlog目录总大小超过
max_wal_size阈值;
满足所有条件的WAL才会被删除。
- 是否超过
- 手动清理辅助:如果需要主动清理已归档的旧WAL,推荐用PostgreSQL自带的
pg_archivecleanup工具,绝对不要手动删除pg_xlog里的文件(容易破坏数据一致性):pg_archivecleanup /var/lib/pgsql/9.6/data/pg_xlog /home/archive/
备库侧的清理逻辑
备库的WAL清理逻辑和主库类似,但因为备库不需要归档(除非是级联备库),核心逻辑是:
- 备库重放完成WAL后,会标记该WAL为可清理;
- 同样根据
wal_keep_segments、max_wal_size的配置,自动清理不再需要的WAL; - 备库的WAL保留只受自身配置和重放进度影响,和主库状态无关。
针对你的场景的建议
- 先通过
pg_stat_archiver和pg_stat_replication确认归档状态和备库进度; - 如果备库正常追赶且归档完全成功,那pg_xlog里的WAL只是暂时保留,满足清理条件后会自动删除;
- 如果想调整保留策略,可以适当降低
wal_keep_segments(如果备库网络稳定)或调小max_wal_size(根据磁盘空间调整),但不要设置得太小,避免备库跟不上导致复制中断。
内容的提问来源于stack exchange,提问作者ddinde
相关产品推荐
相关产品推荐

