Laurenz Albe:为什么我的PostgreSQL中COMMIT很慢?

Laurenz Albe:为什么我的PostgreSQL中COMMIT很慢?

💡 原文英文,约1600词,阅读约需6分钟。
📝

内容提要

本文讨论了PostgreSQL中慢COMMIT的原因和解决方法,包括磁盘问题、延迟约束和触发器、游标WITH HOLD和同步复制。建议通过检查磁盘I/O、优化查询、使用低网络延迟的机器进行同步复制以及检查数据库中的扩展来解决问题。

🔎

延伸解读

磁盘I/O:慢COMMIT的首要排查点

PostgreSQL的COMMIT通常很快,但若WAL刷盘遇到磁盘瓶颈,就会变慢。文章建议先用vmstat或sar检查CPU的I/O等待时间(wa或%iowait),若持续高于10%,说明I/O系统压力大。对于NAS,还需检查TCP网络是否过载;共享SAN/NAS则要留意其他机器的争用。此外,磁盘故障或内核问题也可能导致间歇性性能下降,应查看内核日志。

延迟约束与触发器:提交时的额外检查

延迟约束和约束触发器将检查推迟到COMMIT时执行,虽然单次检查很快,但大事务中大量检查累积起来会拖慢提交。例如,循环外键场景常用延迟约束,这本身是合理设计,但若因此导致COMMIT慢,需评估是否可接受。文章指出,若确认是此原因,可能无需过度担心,因为约束总得在某个时刻检查。

WITH HOLD游标:提交时物化结果集的开销

WITH HOLD游标允许在事务结束后继续使用,但PostgreSQL会在COMMIT时物化整个结果集。如果游标背后的查询很昂贵,提交就会变得很慢。此外,忘记关闭这类游标会导致物化结果集占用服务器资源直到会话结束。优化方法包括调整游标查询使其更快,或设置cursor_tuple_fraction为1.0以加速提交处理。

同步复制与第三方扩展:网络与回调的影响

同步复制要求主库等待备库确认收到WAL,若网络延迟高,COMMIT就会变慢。可通过pg_stat_activity查看是否有频繁或长时间的“SyncRep”等待事件。建议仅在低网络延迟的机器间使用同步复制。另外,第三方扩展可通过RegisterXactCallback()在提交时执行回调,例如外部数据包装器可能需提交远程事务,若远程网络延迟高或处理慢,也会拖慢本地COMMIT。

❓

Q&A

PostgreSQL中慢COMMIT的常见原因是什么?

慢COMMIT的常见原因包括磁盘I/O问题、延迟约束和触发器、游标WITH HOLD以及同步复制。

如何检查PostgreSQL的磁盘I/O性能?

可以使用Linux命令如'vmstat 1'或'sar -p 1'来测量CPU等待I/O的时间,如果该值持续超过10,说明I/O系统可能承受压力。

延迟约束如何影响PostgreSQL的COMMIT性能?

延迟约束会在事务结束时检查约束,可能导致COMMIT处理变慢,尤其是在大事务中,多个检查的执行时间会累积。

游标WITH HOLD会如何导致慢COMMIT?

游标WITH HOLD在提交时需要物化结果集,如果查询复杂,会使COMMIT变得非常缓慢,因此需要优化游标定义中的查询。

同步复制如何影响PostgreSQL的COMMIT速度?

在使用同步复制时,如果主服务器与备用服务器之间的网络延迟高,COMMIT将会变慢,因为需要等待备用服务器确认接收到所有WAL信息。

如何解决PostgreSQL中慢COMMIT的问题?

可以通过检查磁盘I/O、优化查询、使用低延迟的机器进行同步复制以及检查数据库中的扩展来解决慢COMMIT的问题。

🏷️

标签

➡️

继续阅读