synch/cond/sql/MDL_context::COND_wait_status
当有正等待表元数据锁定的线程时,会发生 synch/cond/sql/MDL_context::COND_wait_status
事件。
支持的引擎版本
以下引擎版本支持此等待事件信息:
-
Aurora MySQL 版本 2,最高 2.09.2
-
Aurora MySQL 版本 1,最高 1.23.1
上下文
事件 synch/cond/sql/MDL_context::COND_wait_status
表示有正等待表元数据锁定的线程。在某些情况下,一个会话在表上保持元数据锁定,而另一个会话则试图在同一个表上获取同一个锁定。在这种情况下,第二个会话将等待 synch/cond/sql/MDL_context::COND_wait_status
等待事件。
MySQL 使用元数据锁定来管理对数据库对象的并发访问并确保数据一致性。元数据锁定适用于通过 get_lock
函数获取的表、架构、计划事件、表空间和用户锁定,以及存储的程序。存储的程序包括过程、函数和触发器。有关更多信息,请参阅 MySQL 文档中的元数据锁定
MySQL 进程列表显示此会话处于状态 waiting for metadata
lock
。在性能详情中,如果 Performance_schema
已开启,将会显示事件 synch/cond/sql/MDL_context::COND_wait_status
。
等待元数据锁定的查询的原定设置超时时间取决于 lock_wait_timeout
参数的值,该值原定设置为 31536000 秒(365 天)。
有关不同 InnoDB 锁定以及可能导致冲突的锁定类型的更多详细信息,请参阅 MySQL 文档中的 InnoDB 锁定
等待次数增加的可能原因
当 synch/cond/sql/MDL_context::COND_wait_status
事件的发生率超过正常(可能表示性能问题)时,典型原因包括以下几点:
- 长时间运行的事务
-
一个或多个事务正在修改大量数据并在表上保持锁定很长一段时间。
- 空闲事务
-
一个或多个事务长时间保持打开状态,而不会被提交或回退。
- 大型表格上的 DDL 语句
-
一个或多个数据定义语句 (DDL) 语句(例如
ALTER TABLE
命令)在非常大的表上运行。 - 显式表锁定
-
表上存在显式锁定,但没有及时释放。例如,应用程序可能会不适当运行
LOCK TABLE
语句。
操作
根据等待事件的原因以及 Aurora MySQL 数据库集群的版本,我们建议采取不同的操作。
确定导致事件的会话和查询
您可以使用性能详情显示被 synch/cond/sql/MDL_context::COND_wait_status
等待事件阻止的查询。但是,要识别阻止的会话,请从中数据库集群上的 performance_schema
和 information_schema
中查询元数据表。
通常,具有中等到大量负载的数据库都会有等待事件。如果性能最佳,等待事件可能是可以接受的。如果性能不佳,请检查数据库花费最多时间的位置。查看导致最高负载的等待事件,并了解是否可以优化数据库和应用程序以减少这些事件。
查找负责高负载的 SQL 查询
登录Amazon Web Services Management Console并通过以下网址打开 Amazon RDS 控制台:https://console.aws.amazon.com/rds/
。 -
在导航窗格中,选择 Performance Insights。
-
选择一个数据库实例。该数据库实例的性能详情控制面板出现。
-
在 Database load(数据库负载)图表中,选择 Slice by wait(按等待切片)。
-
在页面底部,选择 Top SQL(主要 SQL)。
该图表列出了负责加载的 SQL 查询。排在列表前面的负载负有最大的责任。为了解决瓶颈,请关注这些语句。
有关使用性能详情进行故障排除的有用概览,请参阅 Amazon 数据库博客文章使用性能详情分析 Amazon Aurora MySQL 工作负载
检查过去的事件
您可以深入了解此等待事件,以检查过去发生的事件。为此,请完成以下操作:
-
检查数据操作语言 (DML) 和 DDL 吞吐量和延迟,以查看工作负载是否有任何变化。
您可以使用性能详情查找问题发生时等待此事件的查询。此外,您还可以查看接近发布时间运行的查询的摘要。
-
如果为数据库集群开启了审计日志或常规日志,则可以检查在等待事务中涉及的对象 (schema.table) 上运行的所有查询。您还可以检查在事务之前已完成运行的查询。
可用于排除过去事件故障的信息有限。执行这些检查不会显示哪个对象正在等待信息。但是,您可以识别事件发生时负载大的表以及在发布时导致冲突的频繁操作行集。然后,您可以使用此信息在测试环境中重现问题并提供有关其原因的洞察。
在 Aurora MySQL 版本 1 上运行查询
在 Aurora MySQL 版本 1 中,您可以在 information_schema
和 performance_schema
中查询表以识别阻止会话。要运行查询,请确保数据库集群配置了 performance_schema
使用者 events_statements_history
。此外,在 performance_schema
的 events_statements_history
表中保持足够数量的查询。您可以使用 performance_schema_events_statements_history_size
参数控制该表中保持的查询数量。如果所需的数据未提供在 performance_schema
中,您可以检查审计日志或常规日志。
一个例子可以说明如何查询表以识别阻止的查询和会话。在此示例中,每个会话运行的语句少于 10 个,并且在数据库集群上启用了所需的使用者。
在以下进程列表输出中,进程 ID 59
(运行 TRUNCATE
命令)和进程 ID 53
(运行 INSERT
命令)已等待元数据锁定 33 秒钟。此外,两个线程都在名为 sbtest.sbtest1
的同一个表上运行查询。
MySQL [(none)]> select @@version, @@aurora_version; +-----------+------------------+ | @@version | @@aurora_version | +-----------+------------------+ | 5.6.10 | 1.23.0 | +-----------+------------------+ 1 row in set (0.00 sec) MySQL [performance_schema]> select * from setup_consumers where name='events_statements_history'; +---------------------------+---------+ | NAME | ENABLED | +---------------------------+---------+ | events_statements_history | YES | +---------------------------+---------+ 1 row in set (0.00 sec) MySQL [performance_schema]> show global variables like 'performance_schema_events_statements_history_size'; +---------------------------------------------------+-------+ | Variable_name | Value | +---------------------------------------------------+-------+ | performance_schema_events_statements_history_size | 10 | +---------------------------------------------------+-------+ 1 row in set (0.00 sec) MySQL [performance_schema]> show processlist; +----+------------------+--------------------+--------------------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------------------+--------------------+--------------------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+ | 11 | rdsadmin | localhost | NULL | Sleep | 0 | cleaned up | NULL | | 14 | rdsadmin | localhost | NULL | Sleep | 1 | cleaned up | NULL | | 15 | rdsadmin | localhost | NULL | Sleep | 14 | cleaned up | NULL | | 16 | rdsadmin | localhost | NULL | Sleep | 1 | cleaned up | NULL | | 17 | rdsadmin | localhost | NULL | Sleep | 214 | cleaned up | NULL | | 40 | auroramysql56123 | 172.31.21.51:44876 | sbtest123 | Query | 1843 | User sleep | select sleep(10000) | | 41 | auroramysql56123 | 172.31.21.51:44878 | performance_schema | Query | 0 | init | show processlist | | 48 | auroramysql56123 | 172.31.21.51:44894 | sbtest123 | Execute | 0 | delayed commit ok initiated | COMMIT | | 49 | auroramysql56123 | 172.31.21.51:44899 | sbtest123 | Execute | 0 | delayed commit ok initiated | COMMIT | | 50 | auroramysql56123 | 172.31.21.51:44896 | sbtest123 | Execute | 0 | delayed commit ok initiated | COMMIT | | 51 | auroramysql56123 | 172.31.21.51:44892 | sbtest123 | Execute | 0 | delayed commit ok initiated | COMMIT | | 52 | auroramysql56123 | 172.31.21.51:44898 | sbtest123 | Execute | 0 | delayed commit ok initiated | COMMIT | | 53 | auroramysql56123 | 172.31.21.51:44902 | sbtest | Query | 33 | Waiting for table metadata lock | INSERT INTO sbtest1 (id, k, c, pad) VALUES (0, 5021, '91560616281-61537173720-56678788409-8805377477 | | 56 | auroramysql56123 | 172.31.21.51:44908 | NULL | Query | 118 | User sleep | select sleep(10000) | | 58 | auroramysql56123 | 172.31.21.51:44912 | NULL | Sleep | 41 | cleaned up | NULL | | 59 | auroramysql56123 | 172.31.21.51:44914 | NULL | Query | 33 | Waiting for table metadata lock | truncate table sbtest.sbtest1 | +----+------------------+--------------------+--------------------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+ 16 rows in set (0.00 sec)
根据此输出,请运行以下查询。此查询用连接 ID 59
识别已运行超过 33 秒的事务,与等待表格锁定的时间相同。
MySQL [performance_schema]> select b.id, a.trx_id, a.trx_state, a.trx_started, TIMESTAMPDIFF(SECOND,a.trx_started, now()) as "Seconds Transaction Has Been Open", a.trx_rows_modified, b.USER, b.host, b.db, b.command, b.time, b.state from information_schema.innodb_trx a, information_schema.processlist b where a.trx_mysql_thread_id=b.id and TIMESTAMPDIFF(SECOND,a.trx_started, now()) > 33 order by trx_started; +----+---------+-----------+---------------------+-----------------------------------+-------------------+------------------+--------------------+-----------+---------+------+------------+ | id | trx_id | trx_state | trx_started | Seconds Transaction Has Been Open | trx_rows_modified | USER | host | db | command | time | state | +----+---------+-----------+---------------------+-----------------------------------+-------------------+------------------+--------------------+-----------+---------+------+------------+ | 40 | 1907737 | RUNNING | 2021-02-02 12:58:16 | 1955 | 0 | auroramysql56123 | 172.31.21.51:44876 | sbtest123 | Query | 1955 | User sleep | | 56 | 3797992 | RUNNING | 2021-02-02 13:27:01 | 230 | 0 | auroramysql56123 | 172.31.21.51:44908 | NULL | Query | 230 | User sleep | | 58 | 3895074 | RUNNING | 2021-02-02 13:28:18 | 153 | 0 | auroramysql56123 | 172.31.21.51:44912 | NULL | Sleep | 153 | cleaned up | +----+---------+-----------+---------------------+-----------------------------------+-------------------+------------------+--------------------+-----------+---------+------+------------+ 3 rows in set (0.00 sec)
在输出中,进程 40、56 和 58 已经处于活动状态很长一段时间。我们来识别 sbtest.sbtest1
表上的这些会话运行的查询。
MySQL [performance_schema]> select t.processlist_id, t.thread_id, sql_text from performance_schema.threads t join events_statements_history sh on t.thread_id=sh.thread_id where processlist_id in (40,56,58) and SQL_TEXT like '%sbtest1%' order by 1; +----------------+-----------+------------------------------------------+ | processlist_id | thread_id | sql_text | +----------------+-----------+------------------------------------------+ | 56 | 84 | select * from sbtest123.sbtest10 limit 1 | | 58 | 86 | select * from sbtest.sbtest1 limit 1 | +----------------+-----------+------------------------------------------+ 2 rows in set (0.01 sec)
在此输出中,processlist_id
为 58
的会话在表格上运行查询并持有打开的事务。那个打开的事务正在阻止 TRUNCATE
命令。
在 Aurora MySQL 版本 2 上运行查询
在 Aurora MySQL 版本 2 中,您可以通过查询 performance_schema
表或 sys
架构视图来直接识别被阻止的会话。一个例子可以说明如何查询表以识别阻止的查询和会话。
在以下进程列表输出中,连接 ID 89
正在等待元数据锁定,它正在运行 TRUNCATE TABLE
命令。在 performance_schema
表或 sys
架构视图上的查询中,输出显示阻止会话为 76
。
MySQL [(none)]> select @@version, @@aurora_version; +-----------+------------------+ | @@version | @@aurora_version | +-----------+------------------+ | 5.7.12 | 2.09.0 | +-----------+------------------+ 1 row in set (0.01 sec) MySQL [(none)]> show processlist; +----+-----------------+--------------------+-----------+---------+------+---------------------------------+-------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+--------------------+-----------+---------+------+---------------------------------+-------------------------------+ | 2 | rdsadmin | localhost | NULL | Sleep | 0 | NULL | NULL | | 4 | rdsadmin | localhost | NULL | Sleep | 2 | NULL | NULL | | 5 | rdsadmin | localhost | NULL | Sleep | 1 | NULL | NULL | | 20 | rdsadmin | localhost | NULL | Sleep | 0 | NULL | NULL | | 21 | rdsadmin | localhost | NULL | Sleep | 261 | NULL | NULL | | 66 | auroramysql5712 | 172.31.21.51:52154 | sbtest123 | Sleep | 0 | NULL | NULL | | 67 | auroramysql5712 | 172.31.21.51:52158 | sbtest123 | Sleep | 0 | NULL | NULL | | 68 | auroramysql5712 | 172.31.21.51:52150 | sbtest123 | Sleep | 0 | NULL | NULL | | 69 | auroramysql5712 | 172.31.21.51:52162 | sbtest123 | Sleep | 0 | NULL | NULL | | 70 | auroramysql5712 | 172.31.21.51:52160 | sbtest123 | Sleep | 0 | NULL | NULL | | 71 | auroramysql5712 | 172.31.21.51:52152 | sbtest123 | Sleep | 0 | NULL | NULL | | 72 | auroramysql5712 | 172.31.21.51:52156 | sbtest123 | Sleep | 0 | NULL | NULL | | 73 | auroramysql5712 | 172.31.21.51:52164 | sbtest123 | Sleep | 0 | NULL | NULL | | 74 | auroramysql5712 | 172.31.21.51:52166 | sbtest123 | Sleep | 0 | NULL | NULL | | 75 | auroramysql5712 | 172.31.21.51:52168 | sbtest123 | Sleep | 0 | NULL | NULL | | 76 | auroramysql5712 | 172.31.21.51:52170 | NULL | Query | 0 | starting | show processlist | | 88 | auroramysql5712 | 172.31.21.51:52194 | NULL | Query | 22 | User sleep | select sleep(10000) | | 89 | auroramysql5712 | 172.31.21.51:52196 | NULL | Query | 5 | Waiting for table metadata lock | truncate table sbtest.sbtest1 | +----+-----------------+--------------------+-----------+---------+------+---------------------------------+-------------------------------+ 18 rows in set (0.00 sec)
接下来,performance_schema
表或 sys
架构视图上的查询会显示阻止会话为 76
。
MySQL [(none)]> select * from sys.schema_table_lock_waits; +---------------+-------------+-------------------+-------------+------------------------------+-------------------+-----------------------+-------------------------------+--------------------+-----------------------------+-----------------------------+--------------------+--------------+------------------------------+--------------------+------------------------+-------------------------+------------------------------+ | object_schema | object_name | waiting_thread_id | waiting_pid | waiting_account | waiting_lock_type | waiting_lock_duration | waiting_query | waiting_query_secs | waiting_query_rows_affected | waiting_query_rows_examined | blocking_thread_id | blocking_pid | blocking_account | blocking_lock_type | blocking_lock_duration | sql_kill_blocking_query | sql_kill_blocking_connection | +---------------+-------------+-------------------+-------------+------------------------------+-------------------+-----------------------+-------------------------------+--------------------+-----------------------------+-----------------------------+--------------------+--------------+------------------------------+--------------------+------------------------+-------------------------+------------------------------+ | sbtest | sbtest1 | 121 | 89 | auroramysql5712@192.0.2.0 | EXCLUSIVE | TRANSACTION | truncate table sbtest.sbtest1 | 10 | 0 | 0 | 108 | 76 | auroramysql5712@192.0.2.0 | SHARED_READ | TRANSACTION | KILL QUERY 76 | KILL 76 | +---------------+-------------+-------------------+-------------+------------------------------+-------------------+-----------------------+-------------------------------+--------------------+-----------------------------+-----------------------------+--------------------+--------------+------------------------------+--------------------+------------------------+-------------------------+------------------------------+ 1 row in set (0.00 sec)
响应阻止会话
当您识别会话时,您的选项包括:
-
联系应用程序拥有者或用户。
-
如果阻止会话处于空闲状态,请考虑结束阻止会话。此操作可能会触发长时间回滚。要了解如何结束会话,请参阅《Amazon RDS 用户指南》中的结束会话或查询。
有关识别阻止事务的更多信息,请参阅 MySQL 文档中的使用 InnoDB 事务和锁定信息