在MySQL 5.7中如何定位导致大量行锁等待的元凶SQL语句?

轻杰酱_8336

轻杰酱_8336

2026-11-01

694人浏览

原创

直接查sys.innodb_lock_waits视图并关联INNODB_TRX,可快速定位阻塞链及持锁事务;若该视图为空,需联合查询INNODB_TRX与PROCESSLIST,重点筛查COMMAND='Sleep'但trx_state='RUNNING'且trx_started超时的悬挂事务。

在mysql 5.7中如何定位导致大量行锁等待的元凶sql语句?

直接结论:别查 SHOW PROCESSLIST,得用 sys.innodb_lock_waits 视图 + INNODB_TRX 关联定位,否则大概率漏掉“Sleep 却持锁”的真凶。

查 sys.innodb_lock_waits 快速拿到阻塞链

这个视图是 MySQL 5.7+ 最省力的入口,它把谁在等、谁在堵、等了多久、SQL 是什么全列出来了。执行:

SELECT * FROM sys.innodb_lock_waits\G

关键字段说明:

  • blocking_pid 是真正持锁的连接 ID(不是“Waiting for …”那个)
  • waiting_query 是被卡住的语句(比如一条简单 UPDATE)
  • sql_kill_blocking_query 直接给你可执行的 KILL 命令,但建议先看语句再决定是否杀
  • 如果返回为空,先确认 performance_schema=ON 且 sys schema 已安装(5.7 默认启用)

为什么 SHOW PROCESSLIST 找不到元凶?

因为大量行锁等待的源头根本不在 “Command = Query” 的活跃线程里,而是在那些:

  • COMMAND = 'Sleep'、STATE = ''(空)、但 INFO 为空的连接
  • 对应事务状态仍是 trx_state = 'RUNNING',且 trx_started 很早(比如 > 300 秒)
  • 这种连接通常来自应用异常断连后事务没自动回滚,或 BEGIN 后只跑了一条 SELECT 就挂起

必须用 JOIN 查才能揪出来:

MySQL8 CRM Schema Design Expert
MySQL8 CRM Schema Design Expert

面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。

下载
SELECT t.trx_id, t.trx_started, t.trx_state, p.ID, p.USER, p.HOST, p.DB, p.COMMAND, p.TIME, p.INFO<br>FROM information_schema.INNODB_TRX t<br>JOIN information_schema.PROCESSLIST p ON t.trx_mysql_thread_id = p.ID<br>WHERE p.COMMAND = 'Sleep' AND t.trx_state = 'RUNNING'<br>ORDER BY t.trx_started;

INNODB_TRX 里哪些字段最该盯住?

光看线程 ID 不够,得结合事务上下文判断风险等级:

  • trx_isolation_level = 'REPEATABLE READ':哪怕只执行过一条 SELECT,事务一启就持 MDL 和可能的间隙锁
  • trx_rows_locked > 10000 或 trx_rows_modified > 0:说明已锁大量行或正在改数据,冲突概率陡增
  • trx_started 时间戳比当前时间早很多(如 > 5 分钟),基本可以判定是悬挂事务
  • trx_weight 值极大(> 100000):代表事务涉及的 undo log 条目极多,通常是大范围 UPDATE/DELETE 未提交

容易被忽略的隐性锁源

除了长事务,还有几类操作会悄悄拉高行锁等待,但不显现在常规锁视图里:

  • 对无索引字段做 UPDATE/DELETE:退化成全表扫描 + 全表加记录锁,EXPLAIN 中 type = ALL 或 key = NULL 就是信号
  • 使用函数或隐式转换的 WHERE 条件:如 WHERE DATE(create_time) = '2026-10-12' 或 WHERE mobile = 13800138000(mobile 是 varchar)
  • information_schema 查询:某些版本中访问 TABLES 或 COLUMNS 会隐式持有 MDL_SHARED_READ,阻塞 DDL 甚至后续查询
  • FLUSH TABLES WITH READ LOCK:虽属全局锁,但会阻塞所有 DML,并让后续 SELECT 等待,表现类似行锁堆积

真正难缠的从来不是正在跑的 SQL,而是那些 Sleep 着却死握着锁不放的连接——它们不会出现在 SHOW PROCESSLIST 的活跃列表里,也不会在 events_statements_current 中露头,只有靠 INNODB_TRX 和 PROCESSLIST 联合扫描才能暴露。

相关专题

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

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

2023.10.12

4663

8

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

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

2023.10.27

971

4

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

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

2024.02.23

1229

5

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

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

2024.03.06

6661

10

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

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

2024.03.06

3403

4

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

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

2024.04.07

6640

11

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

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

2024.04.29

9161

6

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

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

2024.04.29

1230

5

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

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

2024.04.29

1092

5

热门下载

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

精品课程

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

共1课时 | 193人学习