【问题标题】:RDS MySQL Insights: Top Query "commit"RDS MySQL Insights:热门查询“提交”
【发布时间】:2020-11-28 07:02:03
【问题描述】:

我们正在尝试通过查看性能洞察来减少 AWS RDS 实例的负载。

洞察力中列出的最上面的 SQL 语句是“commit”:

特别是,commit 语句大部分时间都处于“init”状态:

当按状态查看整体负载时,这个“初始化”状态确实构成了负载的很大一部分:

所以,现在,我们不太确定从这些信息中得出什么结论。

  1. 首先,我们启用了自动提交。这个“COMMIT”语句是否包含自动提交配置中的自动 COMMIT 语句,还是仅在我们的应用程序执行事务时显式 COMMIT 语句独有?
  2. 我检查了更多,似乎这种“初始化”状态与数据库将 binlog 刷新到磁盘有关 (https://dev.mysql.com/doc/refman/8.0/en/general-thread-states.html)。这可能是有道理的,因为我们的主人有sync_binlog=1。但这个猜测是否正确,还是可能涉及更多内容?
  3. 如果是这种情况,我阅读了有关调整 sync_binlog(例如 sync_binlog=0 或 sync_binlog>1)的信息,但在硬件故障的情况下风险更大(https://aws.amazon.com/blogs/database/best-practices-for-configuring-parameters-for-amazon-rds-for-mysql-part-2-parameters-related-to-replication/)。对于这一部分,我不清楚在使用一个 master 和一些 read-replicas 扩展 RDS 时什么是好的做法:在 master 上触摸这个设置是一种标准做法,还是我们应该更多地关注减少我们的事务量从应用程序执行?
  4. 在运行SHOW FULL PROCESSLIST 时,我能够看到这些“COMMIT”语句停留在初始化状态。但是,我想知道是否有办法查看与该 COMMIT 语句相关的查询。否则,我们似乎不得不猜测根本原因是什么交易。

【问题讨论】:

  • 是的,当COMMIT 位于列表顶部时,这很烦人。使用慢日志找出第二繁忙的查询是什么。

标签: mysql performance load amazon-rds commit


【解决方案1】:

我们终于能够解决这个“提交”加载问题。

关于我们系统的一些事实:

  • 我们大约 95% 的 SQL 查询是读取的
  • 大约 5% 的写入查询是写入
  • 我们的大多数查询都是通过自动提交完成的,而不是通过显式事务完成的

经过进一步调查,我们的发现如下:

  • 性能洞察中的“提交”负载来自将查询写入磁盘上的 binlog 所需的时间
  • 因为我们的大多数写入查询都是通过自动提交执行的,所以所有这些查询都会执行提交,从而触发一些 binlog 刷新
  • 读取查询不会增加这种“提交”负载,很可能是因为它们不需要写入二进制日志
  • 因此,执行写入的 5% 查询导致了大部分数据库负载!

对我们来说,修复它的最有效方法是在单个事务中一起批量写入。 我们正在执行的许多写入操作不需要立即写入数据库,丢失其中一些可能是可以的(我们的大多数写入操作都与统计或跟踪有关)。 因此,我们当前的解决方案是将我们的统计/跟踪写入存储到缓存中,并在单个事务中不时将它们刷新到 DB。这减少了提交的数量,有效地减少了负载。

此解决方案可能不适用于所有人,或者可能需要进行一些调整。据我了解,有一些替代解决方案,例如:

  • 对数据库进行分片并将导致大量写入负载的表移动到另一个实例
  • 减少写查询次数
  • 使用二进制日志刷新设置。默认情况下,它会在每次 COMMIT 后将 binlog 刷新到磁盘,但可以进行不同的配置。但是,如果数据库崩溃,这可能会引入一些可恢复性问题!
  • 使用更快的磁盘

我还在下面回答了我最初的问题。

希望这对其他人有所帮助。我发现网上相关的资料很少。

首先,我们启用了自动提交。这个“COMMIT”语句 包括来自自动提交的自动 COMMIT 语句 配置,还是仅显式 COMMIT 语句独有 我们的应用程序何时执行事务?

此“COMMIT”语句包括使用自动提交执行的查询。

此外,在我们的上下文中,此“COMMIT”语句中没有包含任何读取查询,很可能是因为读取查询后不需要将 binlog 刷新到磁盘。

我检查了更多,似乎这种“初始化”状态与 数据库将 binlog 刷新到磁盘 (https://dev.mysql.com/doc/refman/8.0/en/general-thread-states.html)。 这可能是有道理的,因为我们的 master 上有 sync_binlog=1。但 这个猜测是否正确,还是可能涉及更多?

对我们来说,只有 binlog 刷新导致了这个初始化状态的高负载。

如果是这样,我阅读了有关调整 sync_binlog 的信息(例如 sync_binlog=0, 或 sync_binlog>1),但风险更大 硬件故障 (https://aws.amazon.com/blogs/database/best-practices-for-configuring-parameters-for-amazon-rds-for-mysql-part-2-parameters-related-to-replication/)。 对于这一部分,我不清楚扩展 RDS 时什么是好的做法 有一个主人和一些只读副本:这是一种标准做法吗? 在master上触摸这个设置,还是我们应该更专注于减少 我们从应用程序执行的交易量?

标准做法是将sync_binlog=1 保留在主服务器上以避免崩溃后的可恢复性问题,尤其是在您配置了只读副本的情况下。

我的回答中列出了解决此问题的其他方法。

当我看到这些“COMMIT”语句停留在初始化状态时 运行 SHOW FULL PROCESSLIST。但是,我想知道是否有一个 查看与该 COMMIT 语句相关的查询的方法。 否则,似乎我们不得不猜测根本原因是什么交易。

如本博文所述,这是可行的:https://www.psce.com/en/blog/2015/01/22/tracking-mysql-query-history-in-long-running-transactions/

但是,它需要启用 events_statements_history。在 RDS 上,这是禁用的,据我所知不允许启用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 2013-05-24
    相关资源
    最近更新 更多