复制槽能把磁盘写满,TOAST 能让大字段查询变慢:两个 Postgres 的隐形坑
✦
← CSDN

复制槽能把磁盘写满,TOAST 能让大字段查询变慢:两个 Postgres 的隐形坑

楼主:超级管理员 · 2026-11-06 12:05 · 浏览 14

PostgreSQL 复制槽 TOAST 存储
超级管理员 楼主

复制槽能把磁盘写满,TOAST 能让大字段查询变慢:两个 Postgres 的隐形坑

PostgreSQL 有两个机制,平时不显眼,出事时很难查。

坑一:复制槽会吃满磁盘

逻辑复制的复制槽会保留「还没被消费的 WAL」。如果下游订阅端停了、卡了、或者被删了但槽还在,WAL 就会一直堆积。主库磁盘写满,整个实例只读。

这个问题的恶劣之处在于:它不是查询慢,是整库挂掉。而且监控如果只看「磁盘使用率」,你会在 90% 的时候才发现,那时已经很难腾出空间。

排查与处置

查 pg_replication_slots,看 active 状态与 restart_lsn 推进情况。对确认不再需要的槽,用 pg_drop_replication_slot 删掉。注意:删槽意味着那部分变更无法再被消费,先确认下游确实不要了。

预防手段是给 max_slot_wal_keep_size 设上限。超过上限时槽会失效,下游需要重建,但主库不会挂。这是一个明确的取舍:宁可重建订阅,不要主库宕机。

坑二:TOAST 让大字段变慢

PostgreSQL 的行大小有上限,超长字段会被存到 TOAST 表里,行内只留指针。压缩与「行外存储」都有阈值。

问题在于:即使你只查主键和几个小字段,只要涉及的行里有被 TOAST 的字段,读取路径可能仍然要触碰那些页。加上压缩解压的开销,扫描会明显变慢。

实践建议

大文本、JSONB 文档这类字段,考虑拆到独立表,用主键关联。查询热点表时只取需要的列,别用 SELECT 星号。

另外,TOAST 的压缩与阈值参数对典型 JSONB 文档是否合适,值得实测。默认值是为通用场景设的,不一定是你的场景。

共同点

这两个坑都属于「机制正确、默认配置不适合你的负载」。Postgres 的可配置性很强,代价是你得知道自己跑的是什么。

复制槽能把磁盘写满,TOAST 能让大字段查询变慢:两个 Postgres 的隐形坑 示意图


本文由奇幻维度内容助手整理发布,欢迎在评论区交流你的看法。

郑军

复制槽吃满磁盘是整库挂掉,不是查询慢,这个区别很致命。给 max_slot_wal_keep_size 设上限,宁可重建订阅也别让主库宕机。

路人0916

复制槽吃满磁盘这事我们踩过,订阅端停了但槽留着,主库两天就写满转只读。现在监控盯的是槽的 restart_lsn 落后量,超过 5G 就告警。TOAST 那个坑更隐蔽,查询条件命中大字段必然全表扫,得先用别的列把范围缩下来。

登录 后参与回复