很多“COMMIT;”在PostgreSQL慢速查询日志中

时间:2012-10-30 08:47:14

标签: ruby-on-rails postgresql

我正在尝试为我正在开发的Rails应用优化 PostgreSQL 9.1数据库。在 postgresql.conf 中我已经设置了

log_min_duration_statement = 200

然后我使用 PgBadger 来分析日志文件。迄今为止占据大部分时间的声明是:

COMMIT;

我没有比这更多的信息,我对这是什么声明感到很困惑。有谁知道我能做些什么来获得有关COMMIT查询的更多详细信息?所有其他查询显示语句中使用的变量,SELECT,UPDATE等。但不是COMMIT查询。

3 个答案:

答案 0 :(得分:7)

正如@mvp所指出的,如果COMMIT很慢,通常的原因是fsync()慢,因为每个事务提交都必须将数据刷新到磁盘 - 通常使用fsync()调用。但这并不是缓慢提交的唯一可能原因。你可以:

  • 有慢速fsync(),如前所述
  • 缓慢检查点停止I / O
  • 设置了commit_delay - 我没有验证延迟提交是否记录为长时间运行的语句,但似乎是合理的

如果fsync()很慢,那么最好的选择是重新构建您的工作,这样您就可以在更少的大型事务中运行它。一个合理的替代方法是使用commit_delay对提交进行分组;这将提交组提交以提高整体吞吐量,但实际上会降低单个事务的速度。

更好的是,解决问题的根源。升级到具有电池备份回写高速缓存的RAID控制器,或升级到电源故障安全的高质量SSD。请注意,普通磁盘通常每转不到一个fsync(),或者每分钟5400到15,000之间,具体取决于硬盘驱动器。有大量的事务和大量的提交,这将大大限制您的吞吐量,特别是因为那是最佳情况,如果它们所做的只是微不足道的刷新。相比之下,如果你在RAID控制器或SSD上有一个持久的写缓存,操作系统不需要确保数据实际上在硬盘上,它只需要确保它已经到达持久写缓存 - 这是大规模更快,因为它通常只是一些受电源保护的RAM。

fsync()可能不是真正的问题;它可能很慢checkpoints。最好的方法是检查日志,看看是否有关于检查点发生频率过高或持续时间过长的投诉。您还可以启用log_checkpoints来记录检查点的长度和频率。

如果检查点花费的时间过长,请考虑调整bgwriter完成目标(请参阅文档)。如果它们太频繁,请增加checkpoint_segments

有关详细信息,请参阅Tuning your PostgreSQL server

答案 1 :(得分:6)

COMMIT是完全有效的语句,其目的是提交当前待处理的事务。由于其真正的性质 - 确保数据真正刷新到磁盘,它可能需要花费大部分时间。

如何让您的应用更快地运作? 现在,您的代码可能正在使用所谓的自动提交模式 - 也就是说,每个语句都是隐式COMMIT。 如果您明确地将更大的块包装到BEGIN TRANSACTION; ... COMMIT;块中,您将使您的应用程序更快地工作并减少提交次数。 祝你好运!

答案 2 :(得分:1)

尝试将每个查询记录几天,然后在COMMIT语句之前查看事务中发生了什么。

  

log_min_duration_statement = 0