合理但非普适,仅适用于pg 9.6前;10+版本应设为-1(自动计算,上限16mb),手动设shared_buffers/32易致wal刷盘延迟、内存浪费及恢复风险。

wal_buffers 设置成 shared_buffers 的 1/32 合理吗?
合理,但只在特定条件下成立——不是硬性公式,而是 PostgreSQL 9.6 之前遗留的“经验阈值”。现代版本(10+)默认已设为 -1(自动计算),手动设为 shared_buffers / 32 反而可能浪费内存或引发写放大。
- PostgreSQL 会按
shared_buffers自动推导wal_buffers:10+ 版本中wal_buffers = -1表示“取shared_buffers / 32,但上限 16MB”,且会随shared_buffers动态调整 - 手动固定为
shared_buffers / 32容易踩坑:比如shared_buffers = 8GB→wal_buffers = 256MB,远超实际 WAL 日志生成速率所需,导致 WAL 写入延迟升高(因 buffer 太大、刷盘不及时) - 真实瓶颈常不在
wal_buffers大小,而在checkpoint_timeout、max_wal_size和磁盘 I/O 吞吐能力
怎么查当前 wal_buffers 实际生效值?
别信配置文件里写的,要看运行时实际加载值。因为 wal_buffers = -1 时,PostgreSQL 启动时才计算并固化为具体字节数。
- 用
SHOW wal_buffers查当前值(单位是 8KB page 数),比如返回1024表示 8MB - 用
SELECT name, setting, unit FROM pg_settings WHERE name = 'wal_buffers'查带单位的原始设置和生效值 - 注意:修改
wal_buffers必须重启实例,它不是postgresql.conf中可pg_reload_conf()生效的参数
什么场景下需要调大 wal_buffers?
仅当出现批量写入 + 高并发 WAL 生成 + 磁盘刷写慢的组合时,才可能受益。典型信号是 pg_stat_bgwriter 中 buffers_checkpoint 占比异常高,或日志里频繁出现 WARNING: checkpoints are occurring too frequently。
- 常见触发场景:大批量
COPY、逻辑复制初始同步、OLAP 场景下单事务更新数百万行 - 调大建议:从默认(或
-1推导值)开始,每次 +2MB(即 +256),观察pg_stat_bgwriter.checkpoint_write_time是否下降,超过 16MB 基本无收益 - 反模式:为缓解
WAL file not found或could not fsync log segment错误而盲目调大wal_buffers——这些错误根源通常是磁盘满、权限错或wal_level配置不当
为什么 wal_buffers 不是越大越好?
它本质是 WAL 写入的“预分配缓存池”,不是通用缓冲区。过大反而延长 WAL 刷盘周期,增加 crash 恢复时间与主从延迟风险。
-
wal_buffers全部驻留在共享内存中,每多 1MB 就少 1MB 给shared_buffers或连接工作内存用 - WAL 写入路径:事务日志 →
wal_buffers→wal_writer进程刷到 WAL 文件 →checkpointer触发 fsync;buffer 过大会让wal_writer刷得更懒散 - 实测表明:在 NVMe 盘上,
wal_buffers超过 16MB 后,TPS 和延迟几乎无变化;但在 HDD 上,超过 8MB 就可能因刷盘不及时导致事务卡顿
wal_buffers 值,未必是 PostgreSQL 正在用的那个——它只在启动时快照一次,改了配置不重启就等于没改。











