8

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

log_min_duration_statement = 200

然后我使用PgBadger分析日志文件。到目前为止,占用大部分时间的语句是:

COMMIT;

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

4

3 回答 3

10

正如@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 服务器

于 2012-10-30T10:32:40.087 回答
6

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

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

于 2012-10-30T09:31:46.077 回答
1

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

log_min_duration_statement = 0

于 2012-10-30T09:48:10.897 回答