如何让Patroni standby节点的PostgreSQL清理pg_wal文件?
PostgreSQL Standby节点WAL无法清理致磁盘耗尽的排查方案
关键排查步骤
- 定位WAL保留的触发点
先执行pg_controldata找到Latest checkpoint's REDO WAL file,对比pg_wal目录中最早未删除的WAL文件,确认是否因checkpoint未推进导致WAL无法回收。再查询SELECT * FROM pg_stat_wal;,观察wal_files数量和recycled字段的变化,判断WAL回收逻辑是否正常触发。 - 深挖非活跃复制槽的真实影响
不要仅依赖active字段判断,执行SELECT slot_name, active, restart_lsn FROM pg_replication_slots;,重点关注restart_lsn是否指向较早的WAL段——即使复制槽显示非活跃,只要restart_lsn未更新,PostgreSQL就会保留对应WAL文件。同时检查Patroni配置中replication_slots相关设置,比如是否开启use_pg_rewind导致复制槽被强制锁定无法清理。 - 排查Patroni版本差异的隐性问题
该节点使用Patroni 4.0.1,而正常集群为4.0.2,需对比两者生成的postgresql.conf:比如wal_keep_size是否被Patroni动态设置为超大值,或者archive_cleanup_command配置异常。执行show archive_cleanup_command;确认是否指向正确的pg_archivecleanup脚本,且postgres用户拥有执行权限。同时查看Patroni日志,寻找wal cleanup相关的报错或警告,比如是否因权限不足无法删除WAL文件。 - 检查文件系统与权限
确认pg_wal目录权限归postgres用户所有:ls -ld $PGDATA/pg_wal,再检查磁盘inode是否耗尽:df -i $PGDATA,以及文件系统是否存在挂载异常(如只读):mount | grep $(df $PGDATA | awk 'NR==2{print $1}')。 - 手动触发清理验证
尝试手动执行pg_archivecleanup $PGDATA/pg_wal <最早需删除的WAL文件名>,观察是否能成功删除,同时查看PostgreSQL日志是否有报错。另外强制触发检查点:CHECKPOINT;,之后再验证WAL是否被回收。
临时缓解方法(无需重新初始化节点)
如果暂时未找到根因,可先将wal_keep_size设置为合理值(比如1GB),重启PostgreSQL服务以释放磁盘空间,之后再逐步排查根本问题。调整前需确认没有其他依赖该节点的复制进程。
内容的提问来源于stack exchange,提问作者danieljm
相关产品推荐
相关产品推荐

