为什么我的 MySQL 数据库实例在性能详情中显示大量活动会话正在 SYNCH 等待事件状态下等待?

上次更新日期:2022 年 12 月 27 日

我激活性能详情时,我的数据库实例显示大量平均活动会话(AAS)正在同步(SYNCH)等待事件状态下等待。我想提高我的数据库实例的性能。

简短描述

以下所有服务均已激活性能详情:

  • Amazon Relational Database Service(Amazon RDS)for MySQL。
  • Amazon RDS for MariaDB。
  • Amazon Aurora MySQL 兼容版。

如果您在性能详情中看到 MySQL SYNCH 等待事件,则数据库中的大量会话正在尝试访问相同的受保护对象或内存结构。MySQL 中的受保护对象包括以下内容:

  • 二进制日志源实例中的活动二进制日志文件:包含每次只允许一个会话执行读取或写入的互斥锁。
  • 数据字典:用于通常由数据控制语言(DCL)或数据定义语言(DDL)语句引起的写入。
  • 自适应哈希索引:包含每次只允许一个会话执行读取或写入的互斥锁。
  • 打开的表缓存:只有一个会话可以在该缓存中添加或删除表。
  • InnoDB 缓冲池内的每个单数据库块:每次只有一个会话可以修改内存中块的内容。

解决方法

确保数据库实例有足够的 CPU 资源来处理工作负载

如果您有大量会话在 SYNCH 事件下等待,则会导致 CPU 使用率过高。如果使用率达到 100%,则正在等待的会话的数量会增加。进行故障排查时,请升高数据库实例的大小,以确保有足够的 CPU 来处理额外的工作负载。

由于这些事件通常很短暂,Amazon CloudWatch CPU 利用率指标可能无法正确显示峰值使用率。检查此问题的最佳方法是使用 RDS 增强监控中的一秒钟 CPU 计数器。这些计数器更加具体和详细。

增加 MySQL 的互斥锁/锁定等待阵列

MySQL 使用内部数据结构来协调线程。默认情况下,此阵列的大小为 1。这适用于单 CPU 计算机,但在拥有多个 CPU 的计算机上可能会产生问题。如果您的工作负载有大量等待线程,请增加阵列大小。将 MYSQL 参数 innodb_sync_array_size 设置为 CPU 的数量(或更高,最高 1024)。

注意:innodb_sync_array_size 参数仅在数据库启动时应用。

减少并发

一般来说,并行性有助于提高吞吐量。但是,当大量会话尝试执行相同或类似的活动时,会话需要访问相同的受保护对象。会话数量越多,您所用的 CPU 中正在等待的就越多。

分散这些活动的时间,或者将其安排为连续进行。您还可以将多个操作捆绑到单个语句中,例如多行插入。

检查具体的等待事件

使用以下示例来对您的特定等待事件进行故障排查。有关 Aurora MySQL 等待事件的更多信息,请参阅使用等待事件优化 Aurora MySQL

  • synch/rwlock/innodb/dict sys RW lock
    synch/rwlock/innodb/dict_operation_lock:这表示同时触发了 DDL 的大量并发 DCL。减少应用程序在常规应用活动期间对使用 DDL 的依赖。
  • synch/cond/sql/MDL_context::COND_wait_status:这表示尝试访问 DCL 或 DDL 正在修改的表的 SQL(包括选择)的数量很多。避免在常规应用程序活动期间将 DDL 语句运行到高流量表。
  • synch/mutex/sql/LOCK_open
    synch/mutex/sql/LOCK_table_cache:这表示您的会话打开的表数量超过表定义缓存或表打开缓存的大小。升高这些缓存的大小
  • synch/mutex/sql/LOG:您的数据库可能正在执行大量语句,并且当前的日志记录方法不支持。如果您使用的是 TABLE 输出方法,请尝试改用 FILE。如果您使用的是常规日志,请改用 Amazon Aurora 的高级审计。如果您使用的 long_query_time 参数值为 0 或小于 1,请尝试增加该值。
  • synch/mutex/innodb/buf_pool_mutex
    synch/mutex/innodb/aurora_lock_thread_slot_futex

    synch/rwlock/innodb/index_tree_rw_lock
    :有大量相似的 DML 正在同时访问同一个数据库对象。使用多行语句,并使用分区将工作负载分布到不同的数据库对象上。
  • synch/mutex/innodb/aurora_lock_thread_slot_futex:当一个会话锁定了要更新的行,而另一个会话尝试更新同一行时,就会发生这种情况。您的操作取决于您看到的其他等待事件。查找并响应造成此等待事件的 SQL 语句,或是查找并响应阻塞会话。 
  • synch/cond/sql/MYSQL_BIN_LOG::COND_done
    synch/mutex/sql/MYSQL_BIN_LOG::LOCK_commit
    synch/mutex/sql/MYSQL_BIN_LOG::LOCK_log:您已开启二进制日志记录,且可能存在以下情况之一:

                         - 提交吞吐量较高。

                         - 正在进行大量事务。

                         - 正在读取二进制日志的副本。

                         - 以上情况的组合。

考虑将数据库升级到与 5.7 或更高版本兼容的主要版本。此外,使用多行语句,或将多个语句捆绑到单个事务中。在 Amazon Aurora 中,使用全局数据库而非二进制日志复制,或者使用 aurora_binlog 参数。


这篇文章对您有帮助吗?


您是否需要账单或技术支持?