由 John Doe 十一月 6, 2025
你是否遇到过因为复制槽闲置,引起表数据膨胀和事务 ID 回卷的问题?

特性提交日志
使闲置复制槽失效。
本次提交新增了idle_replication_slot_timeout这一配置参数,允许在检查点(checkpoint)触发时使闲置复制槽失效。由于检查点会按照checkpoint_timeout设定的间隔执行,因此当复制槽闲置时间超过idle_replication_slot_timeout后,到下次检查点触发复制槽失效之间,可能会存在一定延迟。若需避免此类延迟,用户可强制触发一次检查点,以快速使闲置复制槽失效。
需注意,闲置超时失效机制不适用于以下两类复制槽:
- 不保留 WAL 预写日志的复制槽;
- 备库上从主库同步而来的复制槽(即备库中
synced字段为true的复制槽)。 同步来的复制槽始终被视为“闲置状态”,因为它们不会执行逻辑解码以生成数据变更(无需参与失效判断)。
若订阅端因系统错误宕机或网络问题无法访问,对应的复制槽可能会长期处于闲置状态。若此类情况持续存在,相比尝试恢复故障节点并等待其追平数据(该过程可能耗时较长),重新创建订阅端往往是更切实可行的选择。
此外,外部工具(例如用于数据迁移或版本升级的工具)在创建复制槽后,若因执行错误未能删除这些槽,会留下未使用的“僵尸槽”,它们会占用磁盘空间与系统资源。手动清理这些槽不仅繁琐,还容易出错;若不进行干预,这些残留的槽会导致 WAL 日志被不必要地保留,进而引发系统膨胀。
由于idle_replication_slot_timeout的时间单位为分钟,基于该参数的测试会耗费较长时间。我们计划后续通过注入点框架提交一个补充补丁,以完善相关测试。
讨论:https://postgr.es/m/CALj2ACW4aUe-_uFQOjdWCEN-xXoLGhmvRFnL8SNw_TZ5nJe+aw@mail.gmail.com
示例
在该特性推出前,PostgreSQL 复制槽的闲置问题长期困扰运维人员,典型痛点场景包括:
- 订阅端故障导致槽长期闲置:若订阅端因服务器宕机、网络分区等问题离线数天,对应的复制槽会持续保留,主库无法清理该槽所需的 WAL 日志,导致磁盘空间以 GB / 天的速度增长,甚至撑满磁盘。
- 临时槽遗忘删除:外部工具(如数据迁移脚本、版本升级工具)创建临时复制槽后,若因报错中断未删除,这些 “僵尸槽” 会长期占用资源,且手动排查需遍历
pg_replication_slots,效率低下。 - 事务 ID 回卷风险:闲置槽会保留其
xmin(需保留的最旧事务 ID),若槽长期闲置,xmin会阻塞 VACUUM 清理工作,可能引发事务 ID 回卷,导致数据库无法写入。
设定闲置复制槽 1 小时超时:
ALTER SYSTEM SET idle_replication_slot_timeout = '1h';
SELECT pg_reload_conf();
恢复闲置槽超时默认值(禁用自动失效):
ALTER SYSTEM SET idle_replication_slot_timeout = 0;
SELECT pg_reload_conf();
看起来确实很有用。非常感谢所有参与其中的相关人员。
参考
提交日志:https://git.postgresql.org/pg/commitdiff/ac0e33136abc4668c9b08e1ba7db69afe1e0e2c3