← 返回题目列表

PostgreSQL 复制槽是什么?为什么复制槽可能导致磁盘被 WAL 撑满?

困难 第 26 / 31 题 更新于 2026/07/30
PostgreSQL复制槽WAL

简化版

复制槽用于让 PostgreSQL 保留下游还没消费的 WAL,保证物理或逻辑复制客户端断开后还能继续追上。风险是下游长期不消费时,WAL 不能被清理,磁盘可能被撑满。

详细版

没有复制槽时,下游断开太久,主库可能已经清理旧 WAL,导致下游无法继续复制。复制槽记录消费位置,主库会保留该位置之后的 WAL。

这提高了复制可靠性,但也把下游故障转化成主库磁盘风险。逻辑订阅、CDC、Debezium、备库都可能使用复制槽。

治理重点是监控槽的延迟、WAL 保留量、磁盘空间和失效槽,设置合理告警,停用不用的槽。

完整版教学

一、复制槽解决什么问题

复制依赖 WAL。下游消费 WAL 才能追上主库。如果下游断开很久,而主库已经把旧 WAL 清理掉,下游就会断档。

复制槽像一个书签,告诉主库“这个消费者还读到这里,请不要删后面的日志”。

WAL: 100 --- 200 --- 300 --- 400
slot confirmed at 200
主库必须保留 200 之后的 WAL

二、为什么会撑满磁盘

复制槽保护的是下游消费能力,而不是主库磁盘。如果下游停止消费,槽的位置不前进,主库就必须持续保留 WAL。

假设主库每小时产生 20GB WAL,下游故障 10 小时,可能额外保留 200GB WAL。如果磁盘只剩 100GB,就会出现严重风险。

这类事故很典型:真正坏的是下游 CDC 或订阅程序,但最后报警的是主库磁盘。

三、物理槽和逻辑槽

物理复制槽通常服务于流复制备库,保留物理 WAL。逻辑复制槽用于逻辑解码,把 WAL 转成表级变更事件。

类型常见用途风险
物理槽备库复制备库断开导致 WAL 堆积
逻辑槽CDC、逻辑订阅消费程序慢导致 WAL 堆积
临时槽临时复制任务连接断开自动清理

逻辑槽在数据同步系统里很常见,也更容易因为消费程序异常被忽视。

四、如何监控复制槽

可以查看 pg_replication_slots。关注槽是否 active、restart_lsn、confirmed_flush_lsn 以及与当前 WAL 的差距。

SELECT slot_name, slot_type, active, restart_lsn, confirmed_flush_lsn
FROM pg_replication_slots;

还要结合磁盘空间和 WAL 目录大小监控。只看槽 active 不够,因为慢消费的 active 槽也可能大量滞后。

五、如何治理和预防

不用的槽要删除,不能让历史测试槽留在线上。下游故障时,要尽快恢复消费或评估是否丢弃槽重新全量同步。

新版本 PostgreSQL 可以通过参数限制 slot 保留 WAL 的上限,降低磁盘被无限撑满风险。但设置上限也意味着下游可能复制失败,需要重新初始化。

这就是取舍:要么主库为下游保留更多恢复能力,要么保护主库磁盘优先。

六、常见误区与追问

  • 误区:复制槽只会让复制更可靠,没有副作用。 它会保留 WAL,下游不消费就占磁盘。
  • 误区:槽 active 就一定安全。 active 但消费慢,也会产生大量 WAL 滞后。
  • 误区:删除槽没有影响。 删除后下游可能无法继续增量复制,需要重新同步。
  • 追问:如何查看复制槽? 查询 pg_replication_slots 并计算 WAL 滞后。
  • 追问:CDC 停了为什么主库磁盘涨? 逻辑复制槽阻止旧 WAL 清理,WAL 不断堆积。

七、加强记忆

记忆钩子:复制槽是给消费者留书签;读者不回来,图书馆就一直不敢清掉后面的旧报纸,仓库迟早堆满。

回答这题时讲清“保留 WAL 的可靠性收益”和“下游停滞导致主库磁盘风险”。这比只背物理复制和逻辑复制更贴近线上事故。