Oracle ACE

MySQL

MySQL 8.0.28 升级到 8.0.42 的注意事项

按照生产环境每三年铆钉一个稳定版本发布的原则,未来一段时间计划从 MySQL 8.0.28 升级到 8.0.42 版本。

作为前期准备工作的一部分,需要对 MySQL 8.0.28 到 8.0.42 各版本的主要新增特性和重要变更做汇总。

MySQL 版本支持时间线

根据 Oracle 发布计划,MySQL 8.0 各小版本的发布时间如下 :

版本 发布日期
MySQL 8.0.28 2022-01-18
MySQL 8.0.29 2022-04-26
MySQL 8.0.30 2022-07-26
MySQL 8.0.31 2022-10-11
MySQL 8.0.32 2023-01-17
MySQL 8.0.33 2023-04-18
MySQL 8.0.34 2023-07-18
MySQL 8.0.35 2023-10-25
MySQL 8.0.36 2024-01-16
MySQL 8.0.37 2024-04-30
MySQL 8.0.38 2024-07-01
MySQL 8.0.39 2024-07-23
MySQL 8.0.40 2024-10-15
MySQL 8.0.41 2025-01-21
MySQL 8.0.42 2025-04-15

需要注意的是,MySQL 8.0 将于 2026 年 4 月 达到生命周期终止(EOL)。

⚠️ 重要提醒:下面这两个版本已移除。

  • MySQL 8.0.29:已被官方移除下载,因存在严重问题可能导致 InnoDB 表数据解释错误
  • MySQL 8.0.38:已被官方移除下载,因存在严重问题(创建 8001+ 表后服务器无法重启)

重要变更

下面列举了 MySQL 8.0.28 到 8.0.42 的重要变更,在准备升级工作时需要重点关注。

8.0.28 (2022-01)

  • InnoDB 即时 DDL:支持使用 ALGORITHM=INSTANT 执行 ALTER TABLE ... RENAME COLUMN
1
2
3
mysql> alter table t1 rename column id2 to id, ALGORITHM=INSTANT;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0

8.0.29 (2022-04) ⚠️ 已移除

  • InnoDB 即时删除列:支持 ALGORITHM=INSTANT 执行 DROP COLUMN
1
2
3
mysql> alter table t1 drop column id2, ALGORITHM=INSTANT;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
  • 灵活列位置:即时添加的列可插入到表中任意位置(之前仅限末尾)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql> drop table t1;
Query OK, 0 rows affected (0.04 sec)

mysql> create table t1 (id int, id3 int);
Query OK, 0 rows affected (0.06 sec)

mysql> alter table t1 add column id2 int after id, ALGORITHM=INSTANT;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> show create table t1\G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`id` int DEFAULT NULL,
`id2` int DEFAULT NULL,
`id3` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
  • 行版本管理:引入行版本机制(最多 64 个版本),INNODB_TABLES 表新增 TOTAL_ROW_VERSIONS 列追踪版本数
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from information_schema.innodb_tables where name like '%t1%'\G
*************************** 1. row ***************************
TABLE_ID: 1070
NAME: mydb/t1
FLAG: 33
N_COLS: 6
SPACE: 4
ROW_FORMAT: Dynamic
ZIP_PAGE_SIZE: 0
SPACE_TYPE: Single
INSTANT_COLS: 0
TOTAL_ROW_VERSIONS: 1
1 row in set (0.00 sec)

8.0.30 (2022-07)

  • 双写缓冲区优化:innodb_doublewrite 新增 DETECT_ONLY(仅检测不修复)和 DETECT_AND_RECOVER(检测并修复)设置

DETECT_ONLY 适用场景:适用于底层存储(如某些高端存储阵列或文件系统)已经提供了原子写能力,或者你拥有极其可靠的外部备份机制,且极度追求写入性能的场景。

DETECT_AND_RECOVER 适用场景:绝大多数生产环境。它提供了最高级别的数据一致性保障,防止因系统崩溃导致的数据页损坏。

innodb_doublewrite 默认值为 ON,等效于 DETECT_AND_RECOVER。

8.0.31 (2022-10)

  • 审计日志轮转:新增 audit_log_rotate() 函数简化日志轮转,废弃 audit_log_flush 变量
  • 组件服务 API:新增 MySQL 命令服务,允许组件/插件在本地服务器内执行查询(类似 C API)
  • 企业数据脱敏:从插件架构迁移至组件架构,新增支持加拿大社保号、英国国家保险号、IBAN、UUID 等数据类型

8.0.32 (2023-01)

  • 生成不可见主键(GIPK):为无主键表自动生成不可见主键,通过 sql_generate_invisible_primary_key 控制
  • LDAP 认证改进:认证失败时返回专用错误码 LDAP_AUTHENTICATION_ERROR 而非通用错误

关于 GIPK 的使用,有几点需要注意:

  1. 结构变更的“隐形”陷阱

不可见性误导:GIPK 默认是 INVISIBLE 的。如果你运行 SELECT *,主键列 my_row_id 不会显示。这可能导致开发者误以为表没有主键,重复尝试添加主键导致冲突。

隐式列名占用:系统生成的列名固定为 my_row_id。如果你的业务逻辑中恰好需要一个同名的列,或者现有的迁移脚本试图创建该列,将会报错。

  1. 管理与迁移的复杂性

无法部分开启:该特性是通过全局变量 sql_generate_invisible_primary_key 控制的。一旦开启,所有新创建的无主键表都会被强加 GIPK。你无法针对特定表关闭此行为(除非在建表前临时修改会话变量)。

Dump/逻辑备份风险:使用 mysqldump 备份时,如果不带额外参数,导出的 SQL 可能包含 my_row_id。如果将此脚本还原到关闭了 GIPK 的旧版本 MySQL,可能会导致语法错误或逻辑不一致。

  1. 对 DDL 操作的影响

主键转换困难:如果你后期想把 GIPK 转换为真正的显式主键(例如将 id 改为主键),你不能直接 ADD PRIMARY KEY。你必须先将 my_row_id 设为可见,或者彻底删除它后再添加新主键,这增加了维护成本。

算法限制:在某些 DDL 操作中,GIPK 的存在可能限制 INSTANT 算法的使用,迫使 MySQL 使用较慢的 COPY 算法。

  1. 性能与存储开销

无意义的 IO:虽然 GIPK 只有 8 字节(BigInt),但在海量小表或频繁写入的情况下,自动生成的单调递增 ID 依然会占用额外的磁盘空间和内存索引缓存。

自增锁竞争:虽然它不像传统 AUTO_INCREMENT 那样容易产生明显的锁冲突,但在高并发写入无主键表时,内部 ID 分配机制仍存在一定的系统开销。

总之,建议对表增加显式主键。

8.0.33 (2023-04)

  • 审计日志数据库选择:新增 audit_log_database 变量,支持指定非 mysql 数据库存储审计过滤器数据
  • 调度器组件:支持配置定时任务自动刷新审计日志内存缓存

8.0.34 (2023-07)

  • 密码复杂度增强:新增 validate_password.changed_characters_percentage,要求新密码必须更改一定比例(如 50%)的字符
  • 函数默认值:CURRENT_USER()USER() 等可作为列定义时的默认值,便于审计追踪
  • 二进制日志 API:libmysqlclient 新增 mysql_binlog_open()mysql_binlog_fetch()mysql_binlog_close() 函数
  • 废弃项:标记 mysqlpumpsync_relay_log_infobinlog_format 等为废弃

参数 validate_password.changed_characters_percentage 的作用是限制用户修改密码时,新密码相对于旧密码必须有多少比例的字符发生变化。防止用户只是微调密码,比如在旧密码末尾加个数字(如 Password123 改为 Password124),以此来提高安全性。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
-- 安装 validate_password 组件
mysql> INSTALL COMPONENT 'file://component_validate_password';
Query OK, 0 rows affected (3.51 sec)

mysql> SELECT * FROM mysql.component;
+--------------+--------------------+------------------------------------+
| component_id | component_group_id | component_urn |
+--------------+--------------------+------------------------------------+
| 1 | 1 | file://component_validate_password |
+--------------+--------------------+------------------------------------+
1 row in set (0.00 sec)

-- 设置密码安全策略
mysql> SET GLOBAL validate_password.policy = MEDIUM;
Query OK, 0 rows affected (0.00 sec)

-- 设置变化百分比(如要求 50% 的字符必须不同)
mysql> SET GLOBAL validate_password.changed_characters_percentage = 50;
Query OK, 0 rows affected (0.00 sec)

-- 验证当前配置
mysql> SHOW GLOBAL VARIABLES LIKE 'validate_password%';
+-------------------------------------------------+--------+
| Variable_name | Value |
+-------------------------------------------------+--------+
| validate_password.changed_characters_percentage | 50 |
| validate_password.check_user_name | ON |
| validate_password.dictionary_file | |
| validate_password.length | 8 |
| validate_password.mixed_case_count | 1 |
| validate_password.number_count | 1 |
| validate_password.policy | MEDIUM |
| validate_password.special_char_count | 1 |
+-------------------------------------------------+--------+
8 rows in set (0.00 sec)

退出 root 用户,使用 app 用户登陆,并重置密码。

1
2
3
4
5
mysql> ALTER USER USER() IDENTIFIED BY 'Mysql4567890!1';
Query OK, 0 rows affected (0.03 sec)

mysql> ALTER USER USER() IDENTIFIED BY 'Mysql4567890!12' REPLACE 'Mysql4567890!1';
ERROR 4165 (HY000): The new password must have at least '7' characters that are different from the old password. It has only '1' character(s) different. For this comparison, uppercase letters and lowercase letters are considered to be equal.

8.0.35 (2023-10)

  • 字符集变更:系统使用 utf8mb3 替代 utf8 别名输出,utf8_* 排序规则更名为 utf8mb3_*
  • OpenSSL 升级:从 1.1.1 升级至 3.0.10,可能影响 TLS 握手兼容性
  • 动态 Redo 日志:innodb_redo_log_capacity 支持运行时动态调整 Redo 日志容量
  • 认证插件变更:mysql_native_password 重新成为默认认证方式(当服务器不支持插件认证时)

8.0.37 (2024-04)

  • 字符集配置修复:修复 SET PERSISTSET GLOBAL 设置 character_set_server 后对新会话不生效的问题
  • 优化器增强:支持嵌套括号查询表达式与 UNION 组合,最大嵌套层级 63;遵循 SQL 标准,外部 LIMIT 不能覆盖内部 LIMIT
  • 外键引用修复:修复派生表外键引用和 VALUES 子句中派生表引用的有效性检查问题
  • 性能诊断:修复 performance_schema.data_locks 在高负载下导致内存耗尽或死锁的问题,新增内存仪器监控

8.0.39 (2024-07)

  • 修复启动故障:修复 8.0.38 中创建大量表后无法重启的问题
  • 性能优化:提升表空间文件扫描启动性能;InnoDB 目录操作时对父目录执行 fsync

8.0.41 (2025-01)

  • Windows 内存管理:官方二进制包新增 jemalloc 支持,通过 WITH_WIN_JEMALLOC CMake 选项启用
  • 复制通道修复:修复大事务处理时 STOP REPLICA 无法正确停止通道、导致服务器无法正常关闭的问题
  • 克隆延迟:新增 clone_delay_after_data_drop 变量,在远程克隆删除数据后延迟指定时间(最大 3600 秒),等待文件系统异步释放空间

如果旧文件还没清理干净,克隆操作紧接着就开始创建新文件,可能会导致磁盘空间不足、文件创建失败或权限冲突。clone_delay_after_data_drop 就是为了在删除数据后强行等待一段时间,给操作系统留出缓冲时间。

1
2
3
4
5
-- 设置克隆删除数据后等待 10 秒
SET GLOBAL clone_delay_after_data_drop = 10;

-- 验证设置
SHOW VARIABLES LIKE 'clone_delay_after_data_drop';

8.0.42 (2025-04)

  • Bug 修复版本:主要修复稳定性问题,无重大新特性

Have a nice day ~ ☕

🌻 近期内容 ▼

👉 这里有得聊

如果对国产基础软件(操作系统、数据库、中间件)、AI、Vibe Coding、OpenClaw 、Hermes Agent 等感兴趣,可以加群一起聊聊。关注微信公众号:(少安事务所),后台回复[群],即可看到入口。如果这篇文章为你带来了灵感或启发,请帮忙『点赞、推荐、转发』吧,感谢!ღ( ´・ᴗ・` )~