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

为什么 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.ID和INNODB_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 > 1000或TRX_WAITING_TRX_ID IS NOT NULL判断是否已阻塞其他事务
常用定位 SQL:
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' 不代表安全,它可能卡在刷盘或网络传输中。










