PostgreSQL的wal_keep_size是如何替代wal_keep_segments的?

来源:Docker教程作者:叶知晏头衔:草根站长
导读:本期聚焦于叶知晏创作的《PostgreSQL的wal_keep_size是如何替代wal_keep_segments的?》,敬请观看详情。PostgreSQL 13 发布后,wal_keep_segments 参数为什么会被 wal_keep_size 取代?如果升级了主库却仍沿用旧配置,会出现什么样的警告和风险?这一调整的核心是把 WAL 保留策略的计量单位从段数改为字节数,让配置值不再依赖 WAL 段大小。wal_keep_size 指定 pg_wal 目录中为备用服务器保留的过去日志文件的最小总大小,默认值为 0MB;而旧的 wal_keep_segments 在 13 版本中仍可被识别,但会被自动换算并给出弃用警告,从 14 版本起彻底移除。理解参数替换规则、换算关系以及对磁盘空间的影响,可以避免主库过早清理 WAL 导致备库无法追平,也能让流复制环境的容量规划更直观。

在 PostgreSQL 流复制环境中,主库需要保留一定量的 WAL 文件,以便备库断开连接后重新建立复制时能够获取缺失的日志。长期以来,wal_keep_segments 承担这一职责,它接受一个整数值,表示 pg_wal 目录中至少保留的 WAL 段数量。但从 PostgreSQL 13 开始,这个参数被正式标记为废弃,并被 wal_keep_size 取代。二者并非简单的重命名,而是计量模型的改变。理解这一变化的内部逻辑,对升级和日常运维都有实际价值。

PostgreSQL的wal_keep_size是如何替代wal_keep_segments的?

参数演进:为什么从段数走向字节数

wal_keep_segments 的定义一直围绕 WAL 段数量展开。WAL 段是 PostgreSQL 中预写日志的物理存储单元,默认大小为 16MB,但这个值在编译数据库时可以通过 --with-wal-segsize 参数调整,可选范围通常为 1MB 到 1024MB。因此,同样设置 wal_keep_segments = 64,在默认段大小为 16MB 的实例上保留约 1GB 日志,而在段大小为 64MB 的实例上则会保留 4GB。这种隐藏的差异给容量评估带来不确定性,尤其在混合部署环境中,运维人员容易误判磁盘占用。

改为 wal_keep_size 之后,参数直接表达需要保留的 WAL 总字节数,单位统一为 MB。它不关心底层 WAL 段是 16MB 还是 64MB,只要计算出需要保留多少 MB 即可。对于磁盘规划和监控来说,这种表达方式更符合直觉。例如,你希望主库在备库掉线后还能保留最近 2GB 的 WAL,直接设置 wal_keep_size = 2048 或 wal_keep_size = '2GB',而不必先换算出 128 个段。当段大小在未来发生变化时,配置值也不需要重新计算。

这一调整也反映了 PostgreSQL 在复制与高可用场景下对配置友好性的持续改进。旧的段数模型诞生于流复制早期,当时 WAL 段大小既定且默认值普及,后来随着可调段大小的部署增多,字节数便成为更通用的度量方式。从代码演进角度看,把 wal_keep_segments 标记为废弃并引入 wal_keep_size,也是为了降低新用户的理解门槛,同时为后续版本移除旧参数铺平道路。

wal_keep_size 的配置与换算

wal_keep_size 是一个整型参数,默认值为 0,单位是 MB。可以在 postgresql.conf 中直接写入:

wal_keep_size = 512MB

也可以使用 ALTER SYSTEM 命令动态修改并持久化到 postgresql.auto.conf:

ALTER SYSTEM SET wal_keep_size = '512MB';
SELECT pg_reload_conf();

如果仍保留旧参数 wal_keep_segments,在 PostgreSQL 13 中系统会接受它,但会按当前 WAL 段大小自动换算成 wal_keep_size,并在启动或重载日志中输出类似 wal_keep_segments is deprecated 的警告。例如,假设 WAL 段大小为 16MB,旧的 wal_keep_segments = 64 就等价于 wal_keep_size = 1024MB。反过来,如果希望保留 256 个默认段,可以设置 wal_keep_size = 4096MB。实际查询当前 WAL 段大小可以使用以下语句:

SELECT name, setting, unit
FROM pg_settings
WHERE name IN ('wal_segment_size', 'wal_keep_size');

wal_segment_size 返回以字节为单位的整数值,例如 16777216 对应 16MB。通过 current_setting 函数也能获取当前配置:

SELECT current_setting('wal_segment_size') AS segment_bytes,
       current_setting('wal_keep_size') AS keep_size_mb;

需要注意的是,wal_keep_size 的值并不会因为设置了 wal_keep_segments 而自动出现在 pg_settings 视图中。PostgreSQL 是在启动时将旧参数值转换为内部等效字节数,对应用户看到的 wal_keep_size 可能并非实际生效值。要确定最终生效的保留量,建议在升级后显式移除旧参数,只用 wal_keep_size 一项来配置。

升级兼容与常见问题

从 13 升级到 14 及以上版本时,wal_keep_segments 参数会被彻底移除。如果 postgresql.conf 或 postgresql.auto.conf 中仍然包含该参数,数据库可能拒绝启动并报错 unrecognized configuration parameter wal_keep_segments。因此,在执行 pg_upgrade 或大版本升级前,需要先检查并替换配置文件中的旧参数。一个快速检查命令是:

grep -r "wal_keep_segments" /etc/postgresql/14/main/

找到相关行后,将其替换为 wal_keep_size,并按前文公式换算。例如原配置 wal_keep_segments = 32,在 16MB 段大小下改为 wal_keep_size = 512MB。改完后执行 pg_ctl reload 加载新配置,并用 SHOW wal_keep_size 验证。

另一个常见问题是 wal_keep_size 与复制槽同时存在时的行为。复制槽会强制主库保留所有尚未被备库消费的 WAL,而 wal_keep_size 只是额外的基础保留量。如果备库长期宕机,复制槽可能导致主库 WAL 无限增长,直到磁盘耗尽。因此,在高可用架构中通常会搭配 max_slot_wal_keep_size 来限制复制槽的保留上限。此时 wal_keep_size 仍独立生效,它保证即使没有复制槽或复制槽已被删除,pg_wal 目录也至少保留指定大小的日志,便于重新建立复制关系。

还有用户会在升级后遇到同时设置 wal_keep_size 和 wal_keep_segments 的情况。在 PostgreSQL 13 中,如果两者同时出现且 wal_keep_size 显式设置,新参数优先,旧参数被忽略;如果只设置旧参数,则使用换算值。但从 14 开始,旧参数会直接导致错误,所以不建议同时保留两个参数,应尽早清理。

容量规划与监控建议

合理的 wal_keep_size 取决于两个关键指标:WAL 生成速率和备库允许的最大离线时间。WAL 生成速率可以通过查询 pg_stat_wal 或比较 pg_current_wal_lsn 在不同时间点的位置得到。例如,记录当前 LSN,等待 10 分钟再记录一次,计算差值就是这段时间产生的 WAL 字节数。按此速度乘以可容忍的离线小时数,就能得出基础保留量。一般建议设置至少能覆盖一次完整的备份或网络分区恢复周期,例如 2 到 4 小时。

可以通过 pg_ls_waldir 函数查看当前 pg_wal 目录中文件大小和数量,评估参数是否生效:

SELECT count(*) AS walfile_count,
       pg_size_pretty(sum(size)) AS total_size
FROM pg_ls_waldir();

监控时还应关注 pg_stat_replication 中的 write_lag、flush_lag 和 replay_lag,这些字段反映备库落后主库的时间。如果备库已经掉线,这些值会停止更新,此时主库的 WAL 保留只能依赖 wal_keep_size 或复制槽。一旦保留不足,备库重新连接后会报 requested WAL segment has already been removed 错误,此时只能重新做基础备份。

最后需要明确,wal_keep_size 只负责保留 pg_wal 目录中的在线 WAL 文件,不负责归档。如果同时配置了 archive_command,归档的 WAL 会转存到其他位置,wal_keep_size 的值可以相应降低。获取共享存储或对象存储上的归档后,主库不需要长期保留本地 WAL,从而减少本地磁盘压力。但归档不可用时,wal_keep_size 就是保住复制连续性的最后一道防线,所以不能设为过小值。

PostgreSQLwal_keep_sizewal_keep_segments修改时间:2026-10-04 13:02:10

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/1004/65565.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。