如何在MySQL中查看当前未提交的事务和锁等待?

云磊酱_7936

云磊酱_7936

2026-10-19

445人浏览

原创

可通过查询information_schema.innodb_trx查看未提交事务;执行select trx_id, trx_state, trx_started, trx_mysql_thread_id, trx_query from information_schema.innodb_trx;重点关注trx_state为'lock wait'或长期'active'的事务,trx_mysql_thread_id可关联processlist定位线程。

如何在mysql中查看当前未提交的事务和锁等待?

查未提交事务:直接看 INFORMATION_SCHEMA.INNODB_TRX

MySQL 5.6+ 的 InnoDB 引擎会把活跃事务信息实时写入系统表 INFORMATION_SCHEMA.INNODB_TRX。只要事务没提交(COMMIT)或回滚(ROLLBACK),它就在这里挂着。

执行这条语句就能看到所有未提交事务:

SELECT trx_id, trx_state, trx_started, trx_mysql_thread_id, trx_query FROM INFORMATION_SCHEMA.INNODB_TRX;

注意点:

  • trx_state = 'RUNNING' 不代表一定没提交,要看 trx_started 时间是否异常久;真正关键的是 trx_state = 'LOCK WAIT' 或长期为 'ACTIVE'
  • trx_mysql_thread_id 对应 PROCESSLIST 中的 ID,可用来关联查是谁在跑
  • trx_query 是 NULL,说明事务里当前没执行 SQL(比如刚 BEGIN 就挂住了)

查锁等待关系:连查 INNODB_TRX、INNODB_LOCK_WAITS 和 INNODB_LOCKS

单看 INNODB_TRX 只能知道“谁卡着”,但不知道“卡在谁身上”。得靠 INNODB_LOCK_WAITS 把阻塞者和被阻塞者串起来。

常用诊断 SQL(MySQL 5.7 及以前):

SELECT r.trx_id AS waiting_trx_id,
       r.trx_mysql_thread_id AS waiting_thread,
       r.trx_query AS waiting_query,
       b.trx_id AS blocking_trx_id,
       b.trx_mysql_thread_id AS blocking_thread,
       b.trx_query AS blocking_query
FROM INFORMATION_SCHEMA.INNODB_TRX r
INNER JOIN INFORMATION_SCHEMA.INNODB_LOCK_WAITS w ON r.trx_id = w.requesting_trx_id
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX b ON b.trx_id = w.blocking_trx_id;

注意点:

  • MySQL 8.0+ 中 INNODB_LOCKS 和 INNODB_LOCK_WAITS 已被移除,改用 performance_schema.data_locks 和 data_lock_waits;上面 SQL 在 8.0 会报错
  • 如果查询结果为空,不代表没锁争用——可能只是没有形成“等待链”,比如两个事务各自持锁又申请对方的锁(死锁已被自动检测并回滚掉一个)
  • blocking_query 经常是 NULL,因为阻塞者可能早已执行完 SQL,只留着事务没提交

快速定位源头:结合 SHOW PROCESSLIST 和线程 ID

光有事务 ID 不够,你得知道是哪个客户端、哪条命令、哪个用户干的。用 trx_mysql_thread_id 去匹配 SHOW PROCESSLIST 最直接。

例如,发现某个 waiting_thread = 123,就立刻执行:

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
SHOW PROCESSLIST WHERE ID = 123;

或者一次性关联查出完整上下文:

SELECT p.ID, p.USER, p.HOST, p.DB, p.COMMAND, p.TIME, p.STATE, p.INFO
FROM INFORMATION_SCHEMA.INNODB_TRX t
JOIN INFORMATION_SCHEMA.PROCESSLIST p ON t.trx_mysql_thread_id = p.ID
WHERE t.trx_state = 'LOCK WAIT';

注意点:

  • PROCESSLIST 默认只显示当前用户自己的线程,需有 PROCESS 权限才能看全部
  • STATE 字段值如 'Updating'、'Sending data' 是线索,但不能完全信任——有些状态会滞后更新
  • 如果 INFO 是 NULL,大概率是事务内没执行新语句,或客户端用了预编译(prepared statement)且未启用 log_bin_trust_function_creators 等配置

MySQL 8.0 的替代方案:用 performance_schema 查锁

8.0 彻底废弃了旧的锁视图,必须转向 performance_schema。默认可能没开相关消费者,先确认:

SELECT * FROM performance_schema.setup_consumers WHERE NAME LIKE 'global_instrumentation' OR NAME LIKE 'thread%';

确保这几项是 ENABLED:

  • events_statements_current
  • data_locks
  • data_lock_waits

然后查锁等待:

SELECT ENGINE_TRANSACTION_ID AS trx_id,
       OBJECT_SCHEMA,
       OBJECT_NAME,
       INDEX_NAME,
       LOCK_TYPE,
       LOCK_MODE,
       LOCK_DATA
FROM performance_schema.data_locks
WHERE LOCK_TRX_ID IN (
  SELECT ENGINE_TRANSACTION_ID FROM performance_schema.data_lock_waits
);

注意点:

  • 字段名全变了:ENGINE_TRANSACTION_ID 替代 trx_id,LOCK_MODE 值如 'X'、'S'、'REC_NOT_GAP' 要查文档对应含义
  • data_lock_waits 只存“正在等待”的快照,不记录历史;一旦锁释放,行就消失
  • 这个路径没法直接看出 SQL 内容,得再 join events_statements_current 拿 SQL_TEXT,但前提是采集已开启且没被截断

锁信息分散在多个表、版本差异大、权限控制严——别指望一条命令扫清全场。最稳的路是:先用 INNODB_TRX 找活跃事务,再按 thread_id 追到 PROCESSLIST,最后根据 MySQL 版本决定要不要切到 performance_schema 深挖锁细节。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4383

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

911

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1149

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6301

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3123

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6280

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8521

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1150

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1012

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 188人学习