MySQL主从复制中如何定位并杀死导致延迟的长事务?

P粉602998670

P粉602998670

2026-07-24

320人浏览

原创

show processlist不可信,因其仅反映连接层状态(如command='sleep'、time=1800),无法体现事务是否持锁;真正关键的是innodb_trx表中的trx_started、trx_state和trx_mysql_thread_id,它们揭示事务真实生命周期与锁持有情况。

mysql主从复制中如何定位并杀死导致延迟的长事务?

为什么 SHOW PROCESSLIST 不能信

它只显示连接层面的状态,比如 Command = 'Sleep'Time = 1800,但完全不反映事务是否还在持锁。一个 BEGIN 后没 COMMIT 的连接,在 PROCESSLIST 里就是“安静”的 Sleep,而实际已锁住行或表长达半小时——这正是从库卡住的根源。

真正关键的是事务级状态:TRX_STARTED(事务真实开始时间)、TRX_STATE(是否 RUNNING 或 LOCK WAIT)、TRX_MYSQL_THREAD_ID(对应线程 ID)。这些只在 INFORMATION_SCHEMA.INNODB_TRX 里有。

  • 云数据库(如阿里云 RDS)常屏蔽 SHOW PROCESSLIST 全量结果,但 INNODB_TRX 一般仍可查(需 CONNECTION_ADMIN 权限)
  • PROCESSLIST.IDINNODB_TRX.TRX_MYSQL_THREAD_ID 不总一致;必须用后者 kill,否则可能杀错连接

怎么算“长事务”:别看 TIME,要看真实持续时间

直接用 TIMESTAMPDIFF(SECOND, TRX_STARTED, NOW()) 算秒数,而不是依赖 PROCESSLIST.Time 字段。阈值要按业务定:

  • OLTP 场景建议预警线设为 5 秒,干预线设为 60 秒
  • TRX_STATE = 'RUNNING'TRX_OPERATION_STATE 停在 'starting index read',哪怕才 3 秒也值得怀疑
  • 配合 TRX_ROWS_LOCKED > 1000TRX_WAITING_TRX_ID IS NOT NULL 判断是否已阻塞其他事务

常用定位 SQL:

MySQL(Linux)
MySQL(Linux)

MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。

下载
SELECT TRX_ID, TRX_MYSQL_THREAD_ID AS thread_id,
       TRX_STARTED,
       TIMESTAMPDIFF(SECOND, TRX_STARTED, NOW()) AS duration_sec,
       TRX_STATE, TRX_QUERY
FROM INFORMATION_SCHEMA.INNODB_TRX
WHERE TIMESTAMPDIFF(SECOND, TRX_STARTED, NOW()) > 60;

KILL 的正确顺序:先 QUERY,再 CONNECTION

直接 KILL CONNECTION 在连接池场景(如 HikariCP)下容易触发重连风暴,尤其当应用没做连接异常兜底时。

  • 第一步:执行 KILL QUERY <code>thread_id —— 对 Sleep 连接虽无效,但能试探该连接是否真空闲;若它其实在执行慢查询,这步就能中断语句、提前释放 MDL 锁
  • 等待 10–20 秒,再查 INNODB_TRX 是否还存在该事务
  • 若仍在,再执行 KILL CONNECTION <code>thread_id

从库上查到长事务,别急着 kill

从库上的长事务往往是主库大事务回放的结果,不是源头。此时 kill 只是治标,还会中断复制流程,导致 Seconds_Behind_Master 跳变甚至报错。

真正该做的是回溯主库:

  • 查主库 INNODB_TRX 找出原始长事务(特别是 TRX_QUERY 包含 INSERT INTO ... SELECT 或无 LIMIT 的 UPDATE/DELETE
  • 确认是否正在执行 DDL(ALTER TABLE),这类操作在从库会卡住整个 SQL Thread
  • 优先考虑用 gh-ost 替换原生命令,或拆分事务逻辑,而不是在从库上硬 kill

最容易被忽略的一点:事务是否已提交,只看 TRX_COMMITTED(8.0+)或是否存在对应 COMMIT binlog 事件——仅靠 TRX_STATE'COMMITTING' 不代表安全,它可能卡在刷盘或网络传输中。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

1118

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

755

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

472

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

1378

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

1905

4

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.08

618

3

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

2246

4

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

2023.08.14

1965

7

mysql事务隔离级别
mysql事务隔离级别

mysql规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。本专题为大家提供mysql事务隔离级别相关的文章内容,大家可以免费体验。

2023.08.16

2397

11

热门下载

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

精品课程

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

共1课时 | 125人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 224人学习

phpEnv手册
phpEnv手册

共0课时 | 0人学习