0

0

mysql如何避免长事务_mysql优化实践说明

P粉602998670

P粉602998670

发布时间:2026-01-14 09:28:05

|

761人浏览过

|

来源于php中文网

原创

长事务导致主从延迟和锁表,因其持续持锁、阻塞purge线程、延迟binlog刷盘,使从库回放卡在行锁等待;需通过INNODB_TRX定位超30秒事务,应用层设事务超时而非依赖lock_wait_timeout。

mysql如何避免长事务_mysql优化实践说明

长事务为什么会导致主从延迟和锁表

MySQL 的长事务会持续持有锁、不释放 undo log、阻塞 purge 线程,还会让主库 binlog 无法及时刷盘。从库 replay 时若遇到被长事务占用的行级锁(尤其在 READ-COMMITTEDREPEATABLE-READ 隔离级别下),就会卡住,表现为 Seconds_Behind_Master 持续增长。

更隐蔽的问题是:即使事务没显式加锁,只要它执行了 SELECT ... FOR UPDATE 或更新了大量数据,就可能让 innodb_row_lock_time_avg 显著升高,拖慢其他并发请求。

  • 避免在事务中做 HTTP 调用、文件读写、sleep() 等外部耗时操作
  • 禁止在事务内调用 time.sleep()(Python)或 Thread.sleep()(Java)
  • 应用层开启事务后,必须确保所有分支都执行 COMMITROLLBACK,不能依赖连接池自动关闭来“清理”

如何快速定位正在运行的长事务

直接查 information_schema.INNODB_TRX 是最准的方式,配合 PROCESSLIST 可定位到具体连接和 SQL:

SELECT 
  trx_id,
  trx_started,
  TIMEDIFF(NOW(), trx_started) AS duration,
  trx_state,
  trx_query,
  trx_mysql_thread_id
FROM information_schema.INNODB_TRX 
WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 60
ORDER BY trx_started;

注意:trx_state = 'RUNNING' 不代表事务活跃,只是未提交;真正危险的是 trx_state = 'LOCK WAIT' 或持续超过 30 秒的 'ACTIVE' 状态。

  • 搭配 SHOW PROCESSLIST 查看 Time 列是否远大于 trx_started 的差值(说明线程挂起)
  • 如果 trx_queryNULL,说明事务处于空闲状态(比如应用拿到连接后没发 SQL 就卡住了)
  • 监控脚本建议每 10 秒扫一次,阈值设为 30 秒而非 60 秒——很多业务超 30 秒就开始影响用户体验

SET SESSION innodb_lock_wait_timeout=5 有用吗

没用。这个参数只控制「等待锁」的超时,不控制「事务本身存活时间」。一个事务可以不争锁、纯计算、或者只读查询,照样能跑几小时,innodb_lock_wait_timeout 完全不生效。

GPT Detector
GPT Detector

在线检查文本是否由GPT-3或ChatGPT生成

下载

真正有效的控制手段是数据库层的硬限制:

  • MySQL 5.7+ 支持 max_execution_time:对单条语句生效,但对事务内的多条语句需每条都加 Hint,例如 SELECT /*+ MAX_EXECUTION_TIME(3000) */ * FROM t1
  • 更可靠的是在应用层设置事务超时:Spring 的 @Transactional(timeout = 30)、Djangotransaction.atomic(..., timeout=30)
  • Proxy 层拦截(如 ProxySQL)可配置 mysql-query_rules 对匹配 BEGIN 的连接自动注入 SET SESSION wait_timeout = 30,但要注意 wait_timeout 是连接空闲超时,不是事务超时

binlog_format=ROW 下长事务对磁盘和网络的影响

ROW 格式下,长事务期间产生的所有 DML 都不会写入 binlog,直到 COMMIT 才一次性刷出全部变更事件。这意味着:

  • 主库 binlog 文件体积突增,可能瞬间写满磁盘(尤其批量更新百万行)
  • 主从之间产生“脉冲式”流量,从库 IO 线程在 COMMIT 时刻集中解析大量 event,容易触发 Slave_SQL_Running_State: Reading event from the relay log 卡顿
  • binlog_cache_size 默认仅 32KB,大事务会频繁使用磁盘临时文件(binlog_cache_usebinlog_cache_disk_use 计数器飙升)

解决方案不是调大缓存,而是拆事务:用 LIMIT 分批提交,例如每次更新 5000 行后 COMMIT,并确保 WHERE 条件能命中索引,避免全表扫描拖慢每一批。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

751

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

636

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

758

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

618

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1262

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

577

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

706

2023.08.11

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

2

2026.01.14

热门下载

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

精品课程

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

共48课时 | 1.7万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 791人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号