如何在EDB PostgreSQL 9.6启用WAL归档后避免日志占满磁盘
解决EDB PostgreSQL 9.6 WAL归档占满磁盘的问题
首先得戳破核心问题:你现在只是把WAL文件复制到本地的/postgres/cluster/wals/文件夹,但完全没对这些归档文件做生命周期管理,再加上业务持续生成新的WAL,磁盘很快被撑爆简直是必然结果。下面给你几个接地气的解决思路:
1. 给归档WAL做自动清理
PostgreSQL本身不会主动删除归档目录里的文件,得咱们自己动手或者写脚本搞定:
- 先搞清楚哪些WAL能删:只要你已经完成了基于这些WAL的有效备份(比如基础备份+后续WAL能完整恢复到最新状态),或者超过了你的保留策略(比如只留最近7天的归档),就可以放心删。
- 写个shell脚本自动化清理,比如每天删7天前的归档:
#!/bin/bash # 保留最近7天的WAL归档文件 find /postgres/cluster/wals/ -type f -mtime +7 -delete
然后把这个脚本加到crontab里,每天凌晨自动执行:
0 2 * * * /path/to/your/cleanup_script.sh >> /var/log/wal_cleanup.log 2>&1
⚠️ 执行前务必确认这些WAL已经没用了,比如你已经做过完整的基础备份且备份有效。
2. 把归档迁移到外部存储
如果本地磁盘空间本来就小,别死磕本地,换个更大的存储:
- 挂载NFS共享存储,修改
archive_command把WAL复制到NFS目录:
archive_command = 'cp %p /mnt/nfs_postgres_wals/%f'
- 用对象存储(比如S3兼容的存储),直接把WAL上传到云端,本地就不用存归档了:
archive_command = 'aws s3 cp %p s3://your-bucket/postgres-wals/%f'
这样本地pg_xlog里的WAL文件会在归档完成后被PostgreSQL自动清理(只要wal_keep_segments设置合理,这个参数控制为流复制备库保留的WAL数量)。
3. 从源头减少WAL生成量
如果业务产生WAL的速度快得离谱,也可以从根源优化:
- 检查有没有批量写入操作(比如一次性插几十万条数据),改成分批提交,能大幅减少单事务生成的WAL大小。
- 启用
wal_compression(PostgreSQL 9.5+支持),压缩WAL文件,能砍掉差不多一半的体积:
wal_compression = on
修改后需要重启PostgreSQL才能生效。
- 调整
full_page_writes:如果你的存储本身支持原子写入(比如带写缓存的RAID卡),可以考虑把full_page_writes设为off,能减少WAL生成量,但要确保存储可靠性,避免数据损坏。
4. 检查pg_xlog目录的清理异常
有时候就算归档完成,pg_xlog里的WAL也可能没被清理,大概率是这两个原因:
- 流复制备库延迟太高:PostgreSQL会保留备库需要的WAL,直到备库追上进度。可以查一下备库延迟:
SELECT pg_xlog_location_diff(pg_current_xlog_location(), replay_location) AS replay_delay FROM pg_stat_replication;
如果延迟很大,得排查备库的网络、性能瓶颈。
wal_keep_segments设得太大:这个参数指定要保留的WAL段数量,默认是32(每个16MB,合计512MB),如果设得过大,也会占用额外空间,根据备库延迟情况调整就行。
最后再啰嗦一句:操作前一定要做好备份,别误删重要WAL导致数据恢复不了!
内容的提问来源于stack exchange,提问作者SQLDBA
相关产品推荐
相关产品推荐

