如何在MySQL 8.0中调优事务系统避免锁等待

小丽大大_4445

小丽大大_4445

2026-10-20

304人浏览

原创

根本原因是mysql 8.0中未提交的悬挂事务在空闲连接下仍保持trx_state='running'并持续持有mdl锁和行锁,因wait_timeout默认长达8小时,导致alter table等ddl被长期阻塞;需查innodb_trx中trx_query为空、trx_autocommit=0且trx_state='running'的记录定位持锁者。

如何在mysql 8.0中调优事务系统避免锁等待

为什么锁等待总在凌晨三点爆发

根本原因不是并发高,而是事务没提交就“睡着了”。MySQL 8.0 默认 wait_timeout = 28800(8 小时),连接空闲后不自动断开,但事务状态仍为 RUNNING、trx_query IS NULL,MDL 锁和行锁持续挂着。应用层用连接池复用连接时,这种悬挂事务极易卡住后续 DDL 或大查询。

必须同步调整三处:全局 wait_timeout 和 interactive_timeout 改为 300;应用连接池(如 HikariCP)配 connection-timeout=30000 和 idle-timeout=300000;Python/Java 客户端显式控制 autocommit,避免 ORM(如 SQLAlchemy、MyBatis)隐式开启长事务。

如何快速定位谁在持锁不放

别只看 SHOW PROCESSLIST —— 持锁线程往往显示为 Command = 'Sleep'、State = ''、Time 很大,但实际仍在占用锁资源。

  • 先查 information_schema.INNODB_TRX,筛选:trx_state = 'RUNNING' 且 trx_query IS NULL 且 trx_autocommit = 0
  • 再关联 performance_schema.metadata_locks,确认该 trx_id 是否对目标表持有 LOCK_TYPE = 'SHARED_WRITE' 或 'EXCLUSIVE'
  • 最后用 SELECT * FROM performance_schema.data_lock_waits\G 查等待链,blocking_trx_id 指向的就是那个“睡着的持锁者”

ALTER TABLE 卡住时千万别直接 KILL

ALTER TABLE 需要 MDL_EXCLUSIVE 锁,但它与任何已存在的 MDL 锁(哪怕只是普通 SELECT 带来的 SHARED_READ)都互斥。盲目 KILL 会触发完整回滚,而回滚本身可能持续数分钟,期间继续阻塞其他 DDL。

MySQL
MySQL

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

下载

更稳妥的操作顺序是:

  • 先执行 KILL QUERY <code>thread_id(对 Sleep 连接虽无实际效果,但可排除它正在执行长查询的误判)
  • 等 15 秒,再查 INNODB_TRX 状态是否变化
  • 若仍为 RUNNING 且 trx_query IS NULL,再执行 KILL <code>thread_id
  • 优先尝试 ALGORITHM=INSTANT(仅限 ADD COLUMN、RENAME COLUMN、SET DEFAULT)绕过锁竞争

死锁日志里藏着最真实的执行路径

MySQL 默认不输出死锁详情,必须手动开启:SET GLOBAL innodb_print_all_deadlocks = 1,日志会写入 error log。每次死锁发生后,SHOW ENGINE INNODB STATUS\G 只保留最后一次记录,而配置开启后能长期留存分析依据。

关键要看日志里的三块内容:

  • *** (1) TRANSACTION 和 *** (2) TRANSACTION:两个冲突事务的 trx_id、启动时间、持有锁类型(X/S/GAP)、锁定的索引行
  • *** WE ROLL BACK TRANSACTION (2):InnoDB 主动回滚的是哪个事务,说明它被判定为“代价更低”
  • 每条事务末尾的 mysql tables in use 和 locked tables:确认是否真有表级锁参与,还是纯行锁/间隙锁交叉

真正难调的不是锁本身,而是事务中混入了非数据库操作(比如 RPC 调用、JSON 解析、循环计算),让锁持有时间不可控 —— 这类逻辑必须从事务边界里剥离出去。

相关文章

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

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

下载

相关标签:

mysql mysql 8.0

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系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

4363

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人学习