PostgreSQL码农集散地

PostgreSQL 逻辑复制必看:slotsync worker 内存泄漏问题

PostgreSQL 逻辑复制必看:slotsync worker 内存泄漏问题

先搞清楚:什么是 slotsync?

如果你跑的是 PostgreSQL 逻辑复制(不是普通的流复制),你的从库上会有一个 slotsync worker。

它的职责很明确:把主库的复制槽同步到从库。

主库创建了一个逻辑复制槽(比如用于订阅某个表的变更)
    ↓
从库的 slotsync worker 发现有新槽
    ↓
定期同步,确保从库知道这个槽的存在

逻辑复制比流复制更灵活,支持:

  • 只复制特定表
  • 支持 schema 变更
  • 可以在订阅端进行数据转换

这次出了什么问题?

slotsync worker 启动时有个内存泄漏 bug:

slotsync worker 被 fork 出来
    ↓
继承了 postmaster 的工作内存上下文(PostmasterContext)
    ↓
Bug:忘记释放这个上下文
    ↓
内存一直占用着

其他后台 worker 都没这个问题:autovacuum、syslogger 等都正确释放了 PostmasterContext,唯独 slotsync 遗漏。

影响大吗?

如果你不跑逻辑复制:完全不受影响。

如果你跑逻辑复制:

  • 短期内可能不明显
  • 长时间运行后,slotsync 的内存可能持续增长
  • 如果从库跑了几个月都没重启,可能有几百 MB 的额外内存占用

怎么验证?

-- 1. 找到 slotsync worker 的 PID
SELECT pid, 
       application_name, 
       state, 
       backend_start
FROM pg_stat_activity
WHERE backend_type = 'slotsync worker';

-- 2. 让它输出内存上下文日志
SELECT pg_log_backend_memory_contexts(pid)
FROM pg_stat_activity
WHERE backend_type = 'slotsync worker';

查看日志中是否还有 PostmasterContext 残留。升级后,PostmasterContext 应该已经被正确释放。

顺便一提:log_lock_waits 测试覆盖

log_lock_waits 是诊断锁等待的重要参数。这次它新增了完整的测试覆盖。

对 DBA 的实际意义:这个功能被测试保护了,未来不容易出 bug。

-- 如果你用 log_lock_waits 排查锁问题
-- 现在可以更放心地依赖它了
ALTERSYSTEMSET log_lock_waits = on;
ALTERSYSTEMSET deadlock_timeout = '1s';

建议:跑逻辑复制的同学,升级后注意观察 slotsync 的内存表现。如果从库跑了很久,可以对比一下修复前后的内存差异。