很多同学可能刚因MySQL5.7 EOL后将MySQL5.7升级到了MySQL8.0。但是再一看MySQL8.0的生命周期,彻底绷不住了。又要升级到MySQL8.4了,开发同学也要配合进行兼容性验证及调整了。
从上面官方公布的声明周期表中可以看到MySQL 8.0 版本的 “保质期” 要到了!预计在2026年4月,它就将迎来EOL(End of Life,生命周期终止),届时官方不再提供安全更新、漏洞修复,使用风险直线上升!这个时候,2024 年 4 月 30 日发布的 MySQL 8.4 LTS 版本,就成了咱们升级的首选!今天就来给大家盘一盘,MySQL8.4 版本到底有哪些超实用的新特性及变更点。
新特性
根据官方文档的介绍,对比MySQL8.0而言,MySQL8.4有如下新特性:
1. 安全增强
1)FLUSH_PRIVILEGES权限:专门用于执行FLUSH PRIVILEGES命令(之前需要RELOAD权限)。升级时,如果用户已有RELOAD权限,会自动授予FLUSH_PRIVILEGES
2)TRANSACTION_GTID_TAG权限:用于设置GTID标签(见下文GTID标签化)
2. InnoDB存储引擎优化
系统变量默认值变更:
3. 复制与Group Replication
4. 功能改进
1) EXPLAIN FOR SCHEMA schema_name ...:在指定schema中解释查询。
2) EXPLAIN FORMAT=JSON INTO @var:将JSON格式结果存入变量。
新增explain_json_format_version系统变量(1:传统线性格式;2:新的访问路径格式)。
3)集合操作优化:EXCEPT和INTERSECT默认使用Hash算法(通过hash_set_operations控制),可通过set_operations_buffer_size调整内存。
SHOW PARSE_TREE:显示SELECT语句的解析树(仅调试版)。
TABLESAMPLE子句:支持抽样查询(如SELECT ... FROM table_name TABLESAMPLE BERNOULLI(10))。
5. 企业版增强
对于使用企业版的同学,有如下变更:
1)支持自定义脱敏字典存储库(通过component_masking.masking_database变量)。
2)支持定期刷新脱敏字典(component_masking.dictionaries_flush_interval_seconds)。
1)存储过程改为事务性操作(错误时回滚)。
2)新增mysql_firewall_reload_interval_seconds变量定期重载规则。
3) 支持自定义防火墙数据库(mysql_firewall_database)。
4) 弃用用户级防火墙存储过程(改用组策略)。
6. 弃用和移除
1)变量:group_replication_allow_local_lower_version_join
2)通配符授权:GRANT ... ON db%.*(未来%和_将视为普通字符)
3)非标准外键:引用非唯一键或部分键的外键(需设置restrict_fk_on_non_standard_key=OFF启用)
1)插件:keyring_file、keyring_encrypted_file、keyring_oci(改用对应的Component)。
2)语句:FLUSH HOSTS(改用TRUNCATE performance_schema.host_cache)。
3) 复制语法:CHANGE MASTER TO → 改用CHANGE REPLICATION SOURCE TO。
3)系统变量:default_authentication_plugin(改用authentication_policy)。
变更列表如下图所示:
新特性举例
1. 加密插件
mysql_native_password加密插件默认已经禁用,如果需要兼容低版本客户端,需要显式启动后才能使用。例如想直接创建一个mysql_native_password加密方式的用户时会报错。
# 默认方式创建用户
mysql> create user u1 identified by 'U1@2025.com';
Query OK, 0 rows affected (0.04 sec)
mysql> SELECT plugin FROM mysql.user WHERE user='u1';
+-----------------------+
| plugin |
+-----------------------+
| caching_sha2_password |
+-----------------------+
1 row in set (0.00 sec)
# 实用mysql_native_password插件创建用户
mysql> CREATE USER u2 IDENTIFIED WITH 'mysql_native_password' BY 'U2_Passwd';
ERROR 1524 (HY000): Plugin 'mysql_native_password' is not loaded查看插件load状态为OFF
如需使用,则在配置文件里开启插件
# my.cnf
[mysqld]
mysql_native_password=ON开启后再次重试即可成功。
2. TLS 证书强制验证 (tls-certificates-enforced-validation)
启动时校验证书链完整性,无效证书阻止启动
错误示例:
[ERROR] [MY-010068] [Server] CA certificate is expired3. WebAuthn 硬件认证
企业版支持 FIDO2 硬件密钥(Yubikey 等)
配置流程:
INSTALL PLUGIN authentication_webauthn SONAME 'authentication_webauthn.so';
CREATE USER 'secure_user' IDENTIFIED WITH authentication_webauthn;4. GTID增强
4.1 标签化
默认情况下生成的gtid是无标签的,例如
mysql> use testdb;
Database changed
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> create table t1(id int,c1 varchar(10));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t1 select 1,'a';
Query OK, 1 row affected (0.05 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW BINARY LOG STATUS;
+------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000005 | 650 | | | 2ff13fa5-4fd7-11f0-9147-525400b0e20f:1-2 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT @@GLOBAL.gtid_executed;
+------------------------------------------+
| @@GLOBAL.gtid_executed |
+------------------------------------------+
| 2ff13fa5-4fd7-11f0-9147-525400b0e20f:1-2 |
+------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM mysql.gtid_executed;
+--------------------------------------+----------------+--------------+----------+
| source_uuid | interval_start | interval_end | gtid_tag |
+--------------------------------------+----------------+--------------+----------+
| 2ff13fa5-4fd7-11f0-9147-525400b0e20f | 1 | 1 | |
| 2ff13fa5-4fd7-11f0-9147-525400b0e20f | 2 | 2 | |
+--------------------------------------+----------------+--------------+----------+
2 rows in set (0.00 sec)而MySQL8.4中添加标签属性,格式为:UUID:TAG:NUMBER(如标记事务类型,需 TRANSACTION_GTID_TAG 权限)
mysql> SET gtid_next = 'AUTOMATIC:maintenance';
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t1 select 2,'b';
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM mysql.gtid_executed;
+--------------------------------------+----------------+--------------+-------------+
| source_uuid | interval_start | interval_end | gtid_tag |
+--------------------------------------+----------------+--------------+-------------+
| 2ff13fa5-4fd7-11f0-9147-525400b0e20f | 1 | 1 | |
| 2ff13fa5-4fd7-11f0-9147-525400b0e20f | 2 | 2 | |
| 2ff13fa5-4fd7-11f0-9147-525400b0e20f | 1 | 1 | maintenance |
+--------------------------------------+----------------+--------------+-------------+
3 rows in set (0.00 sec)
mysql> SELECT @@GLOBAL.gtid_executed;
+--------------------------------------------------------+
| @@GLOBAL.gtid_executed |
+--------------------------------------------------------+
| 2ff13fa5-4fd7-11f0-9147-525400b0e20f:1-2:maintenance:1 |
+--------------------------------------------------------+
1 row in set (0.00 sec)4.2 MTA支持SQL_AFTER_GTIDS
在 MySQL 8.0 及早期版本中,若启用多线程复制(replica_parallel_workers > 0)并尝试通过 START REPLICA SQL_AFTER_GTIDS = 'gtid_set' 指定从特定 GTID 位置开始复制,会触发以下问题:
1)出现警告ER_MTS_FEATURE_IS_NOT_SUPPORTED:提示SQL_AFTER_GTIDS 与 MTA 不兼容;
2)强制降级为单线程模式:复制线程自动切换为单线程(replica_parallel_workers = 0),导致性能显著下降。
而MySQL8.4中通过优化了并行复制的内部逻辑,完全兼容了MTA SQL_AFTER_GTIDS,主要做了如下优化及提升:
1)并行处理机制增强
使用 ankerl::unordered_dense::map 替代 std::map 管理事务依赖关系,提升高并发下 GTID 定位效率。
事务分发逻辑优化,确保从指定 GTID 位置启动时,多线程仍能正确分配和执行事务。
2)无降级行为
执行 START REPLICA SQL_AFTER_GTIDS 后,复制线程保持多线程模式,不再触发警告或切换单线程。
例如:
-- 停止复制
STOP REPLICA;
-- 指定从 GTID 位置启动(旧版本会触发警告并降级单线程)
START REPLICA SQL_AFTER_GTIDS = 'aaa-bbb-ccc:100';
-- 检查线程状态(MySQL 8.4)
SHOW REPLICA STATUS\G5. 直方图自动更新
在MySQL 8.4之前,直方图统计信息需要手动更新,使用ANALYZE TABLE ... UPDATE HISTOGRAM命令。而MySQL8.4增加了AUTO UPDATE选项,允许直方图在ANALYZE TABLE执行时自动更新。
ANALYZE TABLE <表名>
UPDATE HISTOGRAM ON <列名>
WITH <桶数量> BUCKETS
AUTO UPDATE; -- MySQL8.4新增选项ANALYZE TABLE <表名>
UPDATE HISTOGRAM ON <列名>
WITH <桶数量> BUCKETS
MANUAL UPDATE;mysql> select * FROM information_schema.column_statistics WHERE table_name = 't1';
Empty set (0.00 sec)
mysql> ANALYZE TABLE t1 UPDATE HISTOGRAM ON id WITH 2 BUCKETS AUTO UPDATE;
+-----------+-----------+----------+-----------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+-----------+-----------+----------+-----------------------------------------------+
| testdb.t1 | histogram | status | Histogram statistics created for column 'id'. |
+-----------+-----------+----------+-----------------------------------------------+
1 row in set (0.06 sec)
mysql> select * FROM information_schema.column_statistics WHERE table_name = 't1';
+-------------+------------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| SCHEMA_NAME | TABLE_NAME | COLUMN_NAME | HISTOGRAM |
+-------------+------------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| testdb | t1 | id | {"buckets": [[1, 0.5], [2, 1.0]], "data-type": "int", "auto-update": true, "null-values": 0.0, "collation-id": 8, "last-updated": "2025-06-23 13:03:06.972625", "sampling-rate": 1.0, "histogram-type": "singleton", "number-of-buckets-specified": 2} |
+-------------+------------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> ANALYZE TABLE t1 UPDATE HISTOGRAM ON id WITH 2 BUCKETS MANUAL UPDATE;
+-----------+-----------+----------+-----------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+-----------+-----------+----------+-----------------------------------------------+
| testdb.t1 | histogram | status | Histogram statistics created for column 'id'. |
+-----------+-----------+----------+-----------------------------------------------+
1 row in set (0.05 sec)
mysql> select * FROM information_schema.column_statistics WHERE table_name = 't1';
+-------------+------------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| SCHEMA_NAME | TABLE_NAME | COLUMN_NAME | HISTOGRAM |
+-------------+------------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| testdb | t1 | id | {"buckets": [[1, 0.5], [2, 1.0]], "data-type": "int", "auto-update": false, "null-values": 0.0, "collation-id": 8, "last-updated": "2025-06-23 13:04:24.142857", "sampling-rate": 1.0, "histogram-type": "singleton", "number-of-buckets-specified": 2} |
+-------------+------------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)6. explain增强
MySQL 8.4在EXPLAIN方面的一个重要增强是提供了更多的详细信息和格式选项,特别是对JSON格式输出的增强,包括更好的索引使用信息、更清晰的成本估算显示等。
简单举例如下:
mysql> EXPLAIN FORMAT=JSON INTO @plan SELECT * FROM t1 WHERE id IN (SELECT id FROM t1 where c1='b');
Query OK, 0 rows affected (0.00 sec)生成的json内容如下:
还可以用json函数来获取想要的内容:
mysql> SELECT JSON_EXTRACT(@plan, '$.query_block.cost_info');
+------------------------------------------------+
| JSON_EXTRACT(@plan, '$.query_block.cost_info') |
+------------------------------------------------+
| {"query_cost": "1.00"} |
+------------------------------------------------+
1 row in set (0.00 sec)7. 其他
MySQL8.4中还有其他的一些特性,后续遇到比较实用的案例时再继续总结。
弃用|的参数及命令
在MySQL8.4中部分参数及命令彻底弃用,因此,如果使用MySQL5.7的同学在使用MySQL8.4时需要进行变更。下面总结几个比较常见的已弃用参数及命令。
分类 | 弃用/移除项 | 影响版本 | 移除状态 | 替代方案/说明 |
|---|---|---|---|---|
查询缓存 | FLUSH QUERY CACHE、RESET QUERY CACHE | 8.0+ | 完全移除 | 依赖应用层缓存(如Redis)或优化索引 |
query_cache_size、query_cache_type等系统变量 | 8.0+ | 完全移除 | 无替代 | |
Qcache_hits、Qcache_inserts等状态变量 | 8.0+ | 完全移除 | 无替代 | |
复制管理 | change master to | 8.4+ | 完全移除 | CHANGE REPLICATION SOURCE TO |
show slave status | 8.4+ | 完全移除 | SHOW REPLICA STATUS | |
show master status | 8.4+ | 完全移除 | SHOW BINARY LOG STATUS | |
PURGE MASTER LOGS | 8.4+ | 完全移除 | PURGE BINARY LOGS | |
--log_bin_use_v1_events | 8.4+ | 完全移除 | 默认使用Binlog v4事件格式 | |
--slave-rows-search-algorithms | 8.4+ | 完全移除 | 固定为HASH_SCAN,INDEX_SCAN | |
用户认证 | mysql_native_password默认启用 | 8.4+ | 默认禁用 | 需显式启用--mysql-native-password=ON;推荐caching_sha2_password |
ENCODE()、DECODE()、ENCRYPT()等函数 | 8.0+ | 完全移除 | AES_ENCRYPT()、AES_DECRYPT()或SHA2() | |
InnoDB存储引擎 | innodb_file_format系列参数 | 8.0+ | 完全移除 | 默认使用Barracuda文件格式 |
innodb_support_xa | 8.0+ | 完全移除 | XA事务强制启用 | |
空间函数 | 非ST_前缀函数(如MBR_CONTAINS()) | 8.0+ | 完全移除 | 统一使用ST_前缀(如ST_CONTAINS()) |
安装与部署 | mysql_install_db | 8.0+ | 完全移除 | 改用mysqld --initialize或--initialize-insecure |
mysql_plugin | 8.0+ | 完全移除 | 启动参数--plugin-load或运行时INSTALL PLUGIN | |
mysql_upgrade | 8.4+ | 完全移除 | 改用mysql --upgrade=FORCE或自动升级机制 | |
分区与表管理 | 通用分区引擎 | 8.0+ | 完全移除 | 仅InnoDB支持分区 |
FLOAT/DOUBLE列使用AUTO_INCREMENT | 8.4+ | 完全移除 | 改用整数类型 | |
日志与变量 | expire_logs_days | 8.0+ | 完全弃用 | binlog_expire_logs_seconds(秒级控制) |
GLOBAL_VARIABLES等系统变量表 | 8.0+ | 完全移除 | 改用performance_schema中的表 | |
其他 | \N 表示NULL | 8.0+ | 语法禁用 | 显式使用NULL |
SET_USER_ID权限 | 8.4+ | 完全移除 | SET_ANY_DEFINER(创建对象) +ALLOW_NONEXISTENT_DEFINER(孤儿对象保护) |
升级步骤
之前我概述的写过线上数据库相关主机、软件、架构等升级方案,其中对于数据库升级的总体步骤如下:
• 调研待升级的数据库软件版本、新特性及向下兼容性等,并进行部署、测试
• 将测试结果进行总结并与研发、测试人员进行分享并制定升级计划
• 在开发及测试环境部署新版本数据库,并将新建应用及计划内升级的业务数据库部署在新版本数据库上
• 开发测试环境测试一个月以上(经过回归测试),如测试正常,则进行预发布及线上环境升级
• 线上环境先升级从库,调整相关参数,DBA 进行压力测试及基础的兼容性测试
• 从库测试完毕后,数据库进行主从切换,应用连接切换至新主库,原主库作为从节点加入集群,但原主库暂不升级(用于异常回退)
• 如新主库运行正常2周以上,则进行原主库升级
以上只是总体步骤,因为MySQL8.4毕竟当前才发布到8.4.5版本,还有一段时间的迭代和兼容测试时间,因此在接下来的一段时间里,会根据探索业务实际使用情况及测试结果进行详细的升级步骤及注意点的总结,也欢迎已经使用MySQL8.4版本的同学留言或进交流群沟通心得经验。