正如@mvp 所指出的, ifCOMMIT
很慢,通常的原因是 slow fsync()
s,因为每个事务提交都必须将数据刷新到磁盘 - 通常使用 fsync() 调用。不过,这并不是缓慢提交的唯一可能原因。你可能会:
- 如前所述,fsync() 速度较慢
- 有缓慢的检查点停止 I/O
- 有一套
commit_delay
- 我还没有验证延迟提交是否被记录为长时间运行的语句,但这似乎是合理的
如果 fsync() 很慢,最好的选择是重新组织你的工作,这样你就可以在更少的大事务中运行它。一个合理的替代方法是使用 acommit_delay
来分组提交;这将组提交以提高整体吞吐量,但实际上会减慢单个事务的速度。
更好的是,解决问题的根源。升级到具有电池支持的回写式缓存的 RAID 控制器或电源故障安全的高质量 SSD。看,普通磁盘每次旋转通常可以执行不到一个 fsync(),或者每分钟 5400 到 15,000 次,具体取决于硬盘驱动器。有大量事务和大量提交,这将大大限制您的吞吐量,特别是因为如果他们所做的只是微不足道的刷新,那是最好的情况。相比之下,如果您在 RAID 控制器或 SSD 上有一个持久写入缓存,则操作系统不需要确保数据实际上在硬盘驱动器上,它只需要确保它到达持久写入缓存 - 这是速度大大提高,因为这通常只是一些受电源保护的 RAM。
fsync() 可能不是真正的问题。它可能是缓慢的检查点。最好的查看方法是检查日志,看看是否有任何关于检查点发生过于频繁或耗时过长的投诉。您还可以启用log_checkpoints
记录检查点的时间和频率。
如果检查点花费的时间太长,请考虑调高 bgwriter 完成目标(请参阅文档)。如果他们太频繁,增加checkpoint_segments
。
有关更多信息,请参阅调整 PostgreSQL 服务器。