凌晨 2 点 ( AI 这货为了流量, 每次都捏造凌晨2点, 你不睡人家也不睡吗? ),你被一条告警吵醒:
ERROR: all replication slots are in use
你赶紧登录数据库检查,发现 max_replication_slots = 10,10 个槽全被逻辑复制订阅占满了。
但问题是——业务最近在跑大表的 REPACK CONCURRENTLY,每次 REPACK 都需要一个临时复制槽。现在它抢不到槽,直接报错了。
你陷入了两难:
max_replication_slots**?会影响 WAL 保留开销,所有订阅要重新对接这是很多 PostgreSQL DBA 真实经历过的痛点。
而现在,这个提交 e76d8c749c3 引入了一个新参数,彻底终结了这个问题。
新参数叫 **max_repack_replication_slots**,专门给 REPACK 命令预留一批独立的复制槽。
形象地说:
以前:所有复制槽是一整个大池子,逻辑复制和 REPACK 互相抢现在:复制槽被切成两半,一边是"逻辑复制专用",一边是"REPACK 专用",各用各的,互不干扰
PostgreSQL 的复制槽在内存里是一个连续的数组。
改动之前:所有槽混在一起,谁都能申请
改动之后:数组从逻辑上被分成两段
[0 ~ max_replication_slots) -> 逻辑复制订阅专用
[max_replication_slots ~ max_replication_slots + max_repack_replication_slots) -> REPACK 专用
当 REPACK 申请槽时,它只在后半段找空闲槽;当逻辑复制订阅申请槽时,它只在前半段找。
max_repack_replication_slots 默认值是 5,意味着最多支持 5 个并发 REPACK 同时运行。
对大多数业务场景来说,这个数字够用了。如果真的需要更多并发,调整这个参数即可,不需要动 max_replication_slots。
当槽耗尽时,新的 hint 会直接告诉你应该调哪个参数:
max_replication_slotsmax_repack_replication_slots不再需要猜了。
【改动前:所有槽混在一个池子里】
max_replication_slots = 10
┌─────────────────────────────────────┐
│ [槽1][槽2][槽3][槽4][槽5][槽6][槽7][槽8][槽9][槽10] │
└─────────────────────────────────────┘
↑逻辑复制订阅×8 ↑REPACK×2(用完了)
结果:REPACK 和订阅争抢剩下的 2 个槽,容易报错
【改动后:两个独立池子】
max_replication_slots = 10(逻辑复制专用)
max_repack_replication_slots = 5(REPACK专用)
┌──────────────────┬─────────────┐
│ [槽1~10 逻辑复制] │ [槽11~15 REPACK] │
└──────────────────┴─────────────┘
8个订阅用掉8个 2个REPACK用掉2个
还剩2个空闲 还剩3个空闲
结果:各用各的,互不影响
在 postgresql.conf 中添加一行即可:
# 逻辑复制订阅用
max_replication_slots = 10
# REPACK 专用(新增)
max_repack_replication_slots = 5
注意:这是一个 PGC_POSTMASTER 级别参数,必须在服务器启动前设置,不支持 ALTER SYSTEM 动态修改。
如果想彻底禁止 REPACK 使用任何槽:
max_repack_replication_slots = 0
此时任何 REPACK 命令都会直接报错:
ERROR: REPACK can only be used if "max_repack_replication_slots" > 0
这是最典型的场景。比如你有 8 个逻辑复制订阅,同时业务在多个大表上跑 REPACK。
以前:10 个槽,8 个订阅占满,REPACK 抢剩下 2 个,高并发时必报错现在:REPACK 有独立的 5 个槽专用池,互不干扰
有些业务会同时对多张大表做 REPACK,默认 5 个并发基本够用。不够时只需调大 max_repack_replication_slots,不需要动逻辑复制侧的任何配置。
通过设置 max_repack_replication_slots = 0,DBA 可以精确控制是否允许 REPACK 使用复制槽,比以前的"一刀切"更灵活。
max_repack_replication_slots 是静态参数,调整需要重启实例。
建议在上线前评估好两个池的大小:
max_replication_slots:根据逻辑复制订阅数量预留max_repack_replication_slots:根据并发 REPACK 数量预留(默认 5)如果你发现默认的 5 不够用,说明业务对 REPACK 的依赖程度很高,或许值得重新审视一下表的设计是否合理。
这个改动的核心思想是资源隔离——让专业工具各司其职。
max_replication_slots,行为完全不变max_repack_replication_slots,不再和业务抢槽这是 PostgreSQL 在运维灵活性上的又一次小步改进。对于有高并发 REPACK 需求的系统,这是一个值得升级到位的功能。
相关提交:e76d8c749c3152657711ed733f0aea61c0e36a91适用版本:PostgreSQL 19+(待正式发布)
如果文章有帮助,欢迎转发给身边的 PostgreSQL DBA 朋友。
有疑问或踩过类似坑的,欢迎留言区交流。