【问题标题】:Lots of "COMMIT;" in the PostgreSQL log of slow queries很多“承诺”;在 PostgreSQL 慢查询日志中
【发布时间】:2012-10-30 08:47:14
【问题描述】:

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

log_min_duration_statement = 200

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

COMMIT;

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

【问题讨论】:

    标签: ruby-on-rails postgresql


    【解决方案1】:

    正如@mvp 所说,如果COMMIT 很慢,通常的原因是fsync()s 很慢,因为每次事务提交都必须将数据刷新到磁盘——通常使用 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

    【讨论】:

    • 谢谢!我会考虑将数据库服务器移动到 SSD 磁盘
    • @ollak 如果您这样做,请确保您获得了少数(可悲的是昂贵)具有可靠写入缓存的设备之一。他们中的许多人会在突然断电时无可救药地破坏您的数据。你不想要那个。您需要具有适当超级电容器、备用电容阵列、电池或其他电源保护的 SSD。
    【解决方案2】:

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

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

    【讨论】:

    • 虽然非常准确,但请记住,在事务中包装确实会改变应用程序的工作,因为一个错误将意味着没有任何内容保存到磁盘!
    • 在开启 AutoCommit 的情况下运行时,您不会在日志中看到 COMMIT 语句。 AutoCommit 很可能已关闭,并且每个查询都被显式包装在事务块中。这将使得在不开启完整日志记录的情况下准确诊断导致长时间运行同步的查询变得更加困难。
    • 谢谢!我将寻找将查询包装成更大块的可能性。
    【解决方案3】:

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

    log_min_duration_statement = 0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-01
      • 1970-01-01
      相关资源
      最近更新 更多