MySQL为何推荐短事务以减少垃圾回收和锁的负面影响?
- 内容介绍
- 文章标签
- 相关推荐
本文共计955个文字,预计阅读时间需要4分钟。
简而言之,事务不是建议,而是MySQL正常运行的底层要求。 长事务会占用 +undo 日志回收、拖死 +purge 线程、让锁一直不放,最终导致 +SELECT 等操作变慢。
长事务为何卡住 undo 日志回收
undo 日志不能被 purge 线程清理,根本原因不是“时间长”,而是它没提交——只要事务还活跃,InnoDB 就得保留它开始前所有数据的旧版本,供其他事务做 MVCC 快照读。这会导致:
-
innodb_undo_tablespaces磁盘空间持续上涨,甚至填满(尤其开启innodb_undo_log_truncate=ON但无活跃事务触发 truncate 时) - 历史版本链变长,
SELECT扫描 undo 链耗时增加,information_schema.INNODB_TRX里trx_started时间越久,影响越明显 - purge 线程忙于跳过这些“钉子事务”对应的记录,实际清理进度停滞,
SHOW ENGINE INNODB STATUS中可见Purge done for trx's n:o < [low watermark]长期不推进
锁为什么迟迟不释放
InnoDB 的行锁、间隙锁(Gap Lock)和 Next-Key Lock 全部绑定在事务生命周期上,不是语句执行完就释放。
本文共计955个文字,预计阅读时间需要4分钟。
简而言之,事务不是建议,而是MySQL正常运行的底层要求。 长事务会占用 +undo 日志回收、拖死 +purge 线程、让锁一直不放,最终导致 +SELECT 等操作变慢。
长事务为何卡住 undo 日志回收
undo 日志不能被 purge 线程清理,根本原因不是“时间长”,而是它没提交——只要事务还活跃,InnoDB 就得保留它开始前所有数据的旧版本,供其他事务做 MVCC 快照读。这会导致:
-
innodb_undo_tablespaces磁盘空间持续上涨,甚至填满(尤其开启innodb_undo_log_truncate=ON但无活跃事务触发 truncate 时) - 历史版本链变长,
SELECT扫描 undo 链耗时增加,information_schema.INNODB_TRX里trx_started时间越久,影响越明显 - purge 线程忙于跳过这些“钉子事务”对应的记录,实际清理进度停滞,
SHOW ENGINE INNODB STATUS中可见Purge done for trx's n:o < [low watermark]长期不推进
锁为什么迟迟不释放
InnoDB 的行锁、间隙锁(Gap Lock)和 Next-Key Lock 全部绑定在事务生命周期上,不是语句执行完就释放。

