马上EOL了,但MySQL 8.0还有个大Bug没修!建议直接上8.4 LTS(我马上就到了用英语怎么说)
前言
如果你的 MySQL 8.0 从库开了 super_read_only,并且 innodb_undo_log_truncate 还是默认的 ON,请立刻检查 Undo 截断状态。
1 月 5 日,MySQL 领域资深大佬 Jean-François Gagné 发了一篇博客,开篇几乎是直接开炮:
“MySQL 8.0 中一个有数据损坏风险的 Undo Log 截断 Bug,竟然只修 8.4 不修 8.0?”
字里行间透着不满和担忧。
我顺着他的线索翻了一遍 Bug 列表,发现事情确实有点严重。
一、问题出在哪?
场景
MySQL 8.0 从库常见配置:
super_read_only=ON + innodb_undo_log_truncate=ON
(前者是从库规范配置,后者是默认值)
触发条件
当自动 undo truncate 被触发时,在 super_read_only 模式下,截断过程可能开始但无法正确结束。
本质原因(一句话讲明白)
这不是“业务写入”导致的,而是系统线程的元数据收尾被只读挡住了。从库开了 super_read_only 后,InnoDB 做自动 undo truncate 时需要更新数据字典(DD)/undo 表空间元数据来完成“收尾”(包括清理 undo_*_trunc.log 这类标记文件)。
但这些 DD 写入在 super_read_only 模式下也会被拦住,于是就出现“截断开始了,但结束不了”,留下 trunc.log,并引发后续一连串连环问题。
(也正因此,根本修复思路其实很直白:对 undo truncate 这类系统线程的 DD 更新路径放行,不要让它被 super_read_only 卡住。)
二、一连串的 Bug 链
这是同一个问题,但引发了一串连环坑:
Bug #112717(2023 年报告)
truncate 过程卡住,残留 undo_*_trunc.log 文件;INFORMATION_SCHEMA 中 FILE_SIZE 可能显示为 0。
汇报点:重启时可能触发 undo 表空间重建,元数据错乱,影响 Clone 备份。
Bug #112262(同年另一个报告)
同场景下,undo truncate 更新数据字典(DD)失败,报错“缺少 tablespace/innodb_undo_002”等,同样残留 trunc.log。
汇报点:元数据不一致,导致 Percona XtraBackup 等工具备份失败。
Bug #119628(Jean-François 今年报告)
这才是最吓人的一环:
truncate 失败残留日志 → 下次启动触发 undo 重建;
如果此时实例曾经崩溃,且有未提交事务,重启后这些事务可能未被回滚,未提交的数据可能被保留下来。
汇报点:数据损坏,而且可能是静默的——没有明显报错,但数据可能已经错了。
三、官方的态度?
这个问题影响数据安全,按理说应该非常敏感。
但截至今天发布的 8.0.45,这条链路相关 Bug 在官方 Bug 系统里仍未显示已解决(尤其是 #119628 仍是 Open / Critical)。
另外,按官方计划,MySQL 8.0 将在 2026 年 4 月 进入 EOL(最后一个 8.0 小版本号为 8.0.46,以官方最终发布为准)。
从 #112262 的官方备注看,修复进入 8.4.0/9.0.0;但是否会 backport 到 8.0,目前看不到明确迹象。
值得一提的是,Percona Server 在 8.0.39 的 release notes 里明确修了同类问题(PS-9322)。
Jean-François 在博客里也直接质问:“这么重要的数据损坏 Bug,你们就只在 8.4 修,不管 8.0 用户了?”
我们该怎么办?
1、立即检查
如果你的 8.0 从库配置了 super_read_only:
- 检查数据目录是否残留 undo_*_trunc.log 文件
- 同时监控 INFORMATION_SCHEMA.INNODB_TABLESPACES 中 undo 表空间状态(例如 FILE_SIZE、状态字段是否异常)
2、短期规避
建议在从库上设置 innodb_undo_log_truncate=OFF,先避免自动截断继续触发风险。
注意:这可能导致 undo 表空间逐步变大,需要配合容量监控/巡检;后续需要在维护窗口“手工收缩/处理”,常见思路两种(二选一):
- 方案 A(维护窗口临时放开只读让它自动截断一次):
临时将 super_read_only=OFF,并将 innodb_undo_log_truncate=ON(必要时配合阈值参数),让 undo truncate 在“可写 DD”的条件下正常跑完并收尾。
- 方案 B(手动引导某个 undo 表空间进入可截断状态):
对目标 undo 表空间执行 ALTER UNDO TABLESPACE innodb_undo_002 SET INACTIVE,让它退出分配;待该表空间变空后由系统完成截断/收缩(适合有明确目标表空间时使用)。
3、处理中间态(很关键)
巡检发现残留 undo_*_trunc.log 时,可以安排一次计划内维护:
设置 innodb_fast_shutdown=0,做一次“慢关机”后再启动
前提是:你已经触发了 trunc.log 遗留,但还没有重启过
如果已经在 trunc.log 遗留的情况下重启过(日志出现过 “Reconstructing undo tablespace …” 这类重建行为),就别把它当“小毛病”:
至少要做一致性校验/抽样对账
在高风险场景(曾 crash + 有未提交事务)更稳妥的做法是:重建从库(重搭副本)
4、根本解决
升级到 MySQL 8.4。
这不是软广,而是严肃建议:8.4 作为 LTS,更符合“生产保平安”的定位;并且这条链路的修复点已经进入 8.4 分支。既然 8.0 即将 EOL,早升级早安心。
总结
这是一个典型的“元数据操作在 read-only 模式下踩坑”的问题,但因为涉及 undo 这种核心恢复机制,最终可能上升到静默数据损坏的风险。
你可以把高风险触发条件理解为:
存在 trunc.log + 异常重启/崩溃 + 有未提交事务(风险显著上升)
在 8.0 生命周期进入倒计时、且 8.0 分支是否回补修复不明朗的背景下,升级到 8.4 不仅是追新,更是数据安全的要求。
>>>>
参考资料
- Bug #112717:https://bugs.mysql.com/bug.php?id=112717
- Bug #112262:https://bugs.mysql.com/bug.php?id=112262
- Bug #119628:https://bugs.mysql.com/bug.php?id=119628
- https://jfg-mysql.blogspot.com/2026/01/undo-log-truncation-bug-in-80-leads-to-data-corruption.html.html
作者丨芬达
来源丨公众号:芬达的学习笔记(ID:database_learning)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn











