问:MySQL 8.X版本中如何查看加锁的sql语句

在MySQL 8.X中排查加锁的SQL语句,可以通过查询特定的信息 schema 表或使用一些内置命令来实现。以下是一些常用的查询方法:
查询方法 | 关键 SQL 语句/命令 | 主要作用 |
查询 INFORMATION_SCHEMA.INNODB_TRX | SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; | 查看当前所有活跃事务,包括其执行的SQL语句 (trx_query) |
使用 SHOW ENGINE INNODB STATUS 命令 | SHOW ENGINE INNODB STATUS; | 获取详细的InnoDB状态信息,包含最近的死锁信息和锁信息 |
查询 performance_schema.threads | SELECT * FROM performance_schema.threads WHERE PROCESSLIST_ID = <线程ID>; | 间接查找因事务未提交而无法直接显示SQL的加锁语句 |
操作步骤
1. 查找活跃事务及SQL语句
执行SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; 可查看当前所有活跃事务。重点关注 trx_query 字段,显示了该事务正在执行的SQL语句;trx_state 字段若为 LOCK WAIT,则表示该事务正在等待锁;若为 RUNNING,则可能持有锁。trx_mysql_thread_id 是该事务的连接ID。
2. 分析InnoDB状态
执行SHOW ENGINE INNODB STATUS; 会返回大量InnoDB状态信息。在返回结果中,关注 TRANSACTIONS 部分,它包含了事务和锁的概要信息。特别留意 LATEST DETECTED DEADLOCK 部分,这里记录了最近一次死锁的详细信息,对于分析复杂的锁等待非常有帮助。
3. 获取更详细的锁信息(可选)
为了在SHOW ENGINE INNODB STATUS 的输出中包含更详细的锁信息,你可以先开启锁状态输出:
SET GLOBAL innodb_status_output_locks = ON;
4. 追溯历史SQL语句(当 trx_query 为 NULL 时)
如果INNODB_TRX 表中的 trx_query 字段为 NULL(通常因为事务处于休眠状态,即 Sleep),但该事务仍可能持有锁。这时,可以通过查询 performance_schema.threads 表,并结合 INNODB_TRX 表中的 trx_mysql_thread_id 来查找该连接最近执行的语句(PROCESSLIST_INFO 字段)。
SELECT * FROM performance_schema.threads WHERE PROCESSLIST_ID = <目标线程ID>;
需要注意的是:
权限要求:执行这些查询通常需要具有较高的数据库权限(如PROCESS 权限)。MySQL 8.0 的架构变化:请注意,在 MySQL 8.0 中,INFORMATION_SCHEMA 下的 INNODB_LOCKS 和 INNODB_LOCK_WAITS 表已被移除,不再推荐使用。官方更推荐使用 performance_schema 下的相关表或者 SHOW ENGINE INNODB STATUS 来获取锁信息。
及时处理:发现长时间持有锁或锁等待的事务,可根据实际情况(例如通过SHOW PROCESSLIST 辅助判断)决定是否使用 KILL <连接ID>; 命令终止该事务以解决阻塞。
一些建议
在实际排查数据库锁问题时,建议:
1. 首先查询 INFORMATION_SCHEMA.INNODB_TRX 表,快速定位活跃事务和可能持有锁的SQL。
2. 如果问题复杂或涉及死锁,结合 SHOW ENGINE INNODB STATUS 命令获取更深入的信息。
3. 善用 performance_schema.threads 表来追溯那些 trx_query 为 NULL 但可能持有锁的事务历史SQL。
文章至此。




