编程 MySQL 8.4.13 与 9.7.4:版本号变四段,InnoDB 变严的行大小校验回退了

2026-10-28 21:03:21

MySQL 8.4.13 与 9.7.4:版本号变四段,InnoDB 变严的行大小校验回退了

发布说明:

  • MySQL 8.4.13:https://dev.mysql.com/doc/relnotes/mysql/8.4/en/news-8-4-13.html
  • MySQL 9.7.4:https://dev.mysql.com/doc/relnotes/mysql/9.7/en/news-9-7-4.html

两个版本同为 2026-10-20 发布。这次改动里有两件事容易被忽略:版本号多了一段;InnoDB 的行大小估算严格校验被部分回退。

一、版本号变成 MAJOR.MINOR.PATCH.UPDATE

MySQL Server 现在支持四段式版本标识,形式为 MAJOR.MINOR.PATCH.UPDATE;update 段为空时记为 0。完整版本号可以通过以下新接口获取:

SELECT VERSION_WITH_UPDATE();
SELECT @@version_with_update;
mysqld --version-with-update

另外还提供了新的客户端库 API。

已有接口保持三段兼容语义,没有改动,包括 VERSION()、version 系统变量、经典握手包、数字版本号,以及现有的 C API。升级判定和依赖三段版本号的代码路径都不会因为新增 update 段而改变。

mysql_upgrade_history 表会记录精确到 update 段的版本变迁,但它只用于记录,不参与升级兼容性判定;判定仍按原来的三段语义进行。

二、9.7.4:行大小估算变严导致的 DDL 兼容问题被回退

起因是之前的一个 InnoDB 死锁修复:它让 B-tree 操作的行大小估算更准确,副作用是 CREATE TABLE 和 ALTER TABLE 的校验变严。结果,部分在更早 MySQL LTS 版本上能正常创建的表被意外拒绝或产生告警,影响了已有应用。

9.7.4 的处理是:多数 DDL 恢复旧的校验行为,只在防止 B-tree 死锁确实需要的地方保留精确估算。ALTER TABLE ... ALGORITHM=INSTANT 是例外,继续使用更严格的算法,以安全处理大的默认值。(Bug #120323, Bug #39249507)

发布说明对这条致谢了 Percona 的 Paweł Olchawa 团队和 Amazon 的 Meng-Hsiu Chiang 团队。

如果实例在中间版本上修改过表结构以绕开限制,这部分 schema 变更需要重新对照一遍;用 ALGORITHM=INSTANT 添加带大默认值的列时,仍会遇到严格校验。

三、顺手看看:优化器与 InnoDB 的修复

优化器侧:

  • 开启 hypergraph optimizer 时,带 ORDER BY 且子查询被转成 hash semijoin 或 antijoin 的单表 UPDATE、DELETE 可能修改错误的行;通过带 CHECK OPTION 的视图更新时,也可能使用错误的行,或者在行标识未被保留时失败。(Bug #121038, Bug #39822725)
  • optimizer_switch 设为 index_merge_union=off 时,析取条件的索引合并计划可能漏掉一个 disjunct,返回不完整的结果。文档给出的示例是:预期返回四行的查询实际返回了 Empty set (0.00 sec)。(Bug #114885, Bug #36584358)
  • 另外三个修复:group index skip scan 的 range 处理(Bug #39867741)、嵌套查询中重复引用外层字段(Bug #39603658)、优化器对 IN 谓词的处理(Bug #39603649)。

InnoDB 侧:

  • 对旧版本导出的镜像执行 IMPORT TABLESPACE 后,Adaptive Hash Index 中会残留过期条目,点查可能返回已丢弃 tablespace 代次的行。(Bug #39661793)
  • ALTER TABLE ... IMPORT TABLESPACE 失败后,残留页可能触发断言:[ERROR] [MY-013183] [InnoDB] Assertion failure: btr0sea.cc:1082:block->page.id.space() == index->space。(Bug #39661792)
  • InnoDB 页重组大小不匹配现在按致命错误处理,不再带着不一致的 redo 继续运行。(Bug #116574)

复制侧修复了 Group Replication 的消息解码上限、sender 校验、插件卸载时的 UDF 生命周期以及恢复状态校验(Bug #39905199, #39851456, #39838541, #39832216)。原子 DDL 侧修复了 mysqlbinlog 在 CREATE TABLE ... START TRANSACTION 后紧跟 # 注释时输出失败、报 ERROR 3977 (HY000): Only BINLOG INSERT, COMMIT and ROLLBACK statements are allowed after CREATE TABLE with START TRANSACTION statement. 的问题(Bug #36313112)。

四、升级前检查清单

  1. 监控与巡检脚本。凡是解析 VERSION() 输出、按 . 分割取段或写死三段正则的地方,都要确认拿到的是三段还是四段。改用 VERSION_WITH_UPDATE() 取完整版本时,解析逻辑要能处理四段格式。
  2. ORM 与连接池。部分驱动会对版本字符串做数值化或前缀比较,用于控制特性开关,需要验证它们在四段格式下仍走对分支;走经典握手包路径的仍是三段,不受影响。
  3. ALGORITHM=INSTANT 的 DDL。9.7.4 上这条路径仍用严格的行大小估算,给大默认值加列时先在测试库上跑一遍。
  4. hypergraph optimizer。9.7 上如果开启了它,重点回归带 ORDER BY 加子查询转 hash semijoin 或 antijoin 的单表 UPDATE、DELETE,以及带 CHECK OPTION 的视图更新。
  5. index_merge_union=off。业务里显式关掉它的话,检查析取条件下是否出现空结果集或行数偏少。
复制全文 生成海报 MySQL InnoDB 版本升级 运维

推荐文章

程序员茄子在线接单