

根据官方文档的介绍,对比MySQL8.0而言,MySQL8.4有如下新特性:
1. 安全增强
默认禁用mysql_native_password插件:从8.4.0开始,默认不再启用mysql_native_password认证插件。如果需要启用,必须在配置文件([mysqld]部分)设置mysql_native_password=ON或启动时使用--mysql-native-password=ON。
TLS证书强制验证:新增系统变量tls-certificates-enforced-validation,用于在启动或重新加载证书时强制验证。如果启用,发现无效证书将阻止启动或加载,并发出警告。
WebAuthn认证插件:新增基于FIDO/FIDO2标准的WebAuthn认证插件(企业版),支持使用安全密钥、生物识别等设备进行认证
新增权限:
1)FLUSH_PRIVILEGES权限:专门用于执行FLUSH PRIVILEGES命令(之前需要RELOAD权限)。升级时,如果用户已有RELOAD权限,会自动授予FLUSH_PRIVILEGES
2)TRANSACTION_GTID_TAG权限:用于设置GTID标签(见下文GTID标签化)
LDAP认证超时控制:新增LDAP连接和响应超时参数(如authentication_ldap_simple_connect_timeout等),默认30秒(仅Linux)
2. InnoDB存储引擎优化
系统变量默认值变更:
innodb_buffer_pool_in_core_file:默认改为OFF(如果支持MADV_DONTDUMP),否则ON
innodb_parallel_read_threads:默认值改为可用逻辑处理器数/8(最小4)
innodb_read_io_threads:默认值改为可用逻辑处理器数/2(最小4)
temptable_max_ram:默认值改为总内存的3%(在1-4 GiB范围内)
temptable_max_mmap:默认值改为0(禁用)
专用服务器自动配置:当innodb_dedicated_server=ON时,innodb_redo_log_capacity的计算从基于内存改为基于CPU,且不再改变innodb_flush_method的值
3. 复制与Group Replication
GTID标签化(Tagged GTIDs):扩展GTID格式为UUID:TAG:NUMBER,允许为事务组分配标签(如区分数据操作和运维操作)。使用:
SET gtid_next = 'AUTOMATIC:tag_name'(会话级)或SET gtid_next = UUID:tag_name:NUMBER(单事务,需要TRANSACTION_GTID_TAG权限)
多线程复制(MTA)支持SQL_AFTER_GTIDS:之前使用SQL_AFTER_GTIDS会强制切换为单线程,现在支持并行复制,提高性能
Group Replication增强:
1) 默认group_replication_consistency=AFTER(强一致性)
2) 新增group_replication_preemptive_garbage_collection(单主模式预垃圾回收)和group_replication_preemptive_garbage_collection_rows_threshold(触发阈值)
3) 新增性能指标(如MEMBER_FAILURE_SUSPICIONS_COUNT)用于网络诊断
4) Clone插件跨小版本兼容:允许在同一个大版本(如8.4.x)的不同小版本间克隆(例如8.4.0克隆到8.4.14)
4. 功能改进
直方图自动更新:使用ANALYZE TABLE ... UPDATE HISTOGRAM AUTO可启用直方图自动更新(默认手动)。
EXPLAIN增强:
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调整内存。
新增SQL语法:
SHOW PARSE_TREE:显示SELECT语句的解析树(仅调试版)。
TABLESAMPLE子句:支持抽样查询(如SELECT ... FROM table_name TABLESAMPLE BERNOULLI(10))。
5. 企业版增强
对于使用企业版的同学,有如下变更:
数据脱敏(Data Masking):
1)支持自定义脱敏字典存储库(通过component_masking.masking_database变量)。
2)支持定期刷新脱敏字典(component_masking.dictionaries_flush_interval_seconds)。
防火墙(Firewall):
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 expired
3. 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 changedmysql> 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: 0mysql> 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: 0mysql> 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\G
在MySQL 8.4之前,直方图统计信息需要手动更新,使用ANALYZE TABLE ... UPDATE HISTOGRAM命令。而MySQL8.4增加了AUTO UPDATE选项,允许直方图在ANALYZE TABLE执行时自动更新。
收集直方图的语法如下:
ANALYZE TABLE <表名>UPDATE HISTOGRAM ON <列名>WITH <桶数量> BUCKETSAUTO UPDATE; -- MySQL8.4新增选项
关闭自动更新的语法:
ANALYZE TABLE <表名>UPDATE HISTOGRAM ON <列名>WITH <桶数量> BUCKETSMANUAL 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 | |||
query_cache_size、query_cache_type等系统变量 | ||||
Qcache_hits、Qcache_inserts等状态变量 | ||||
| 复制管理 | CHANGE REPLICATION SOURCE TO | |||
SHOW REPLICA STATUS | ||||
SHOW BINARY LOG STATUS | ||||
PURGE MASTER LOGS | PURGE BINARY LOGS | |||
--log_bin_use_v1_events | ||||
--slave-rows-search-algorithms | 固定为HASH_SCAN,INDEX_SCAN | |||
| 用户认证 | mysql_native_password默认启用 | 需显式启用--mysql-native-password=ON;推荐caching_sha2_password | ||
ENCODE()、DECODE()、ENCRYPT()等函数 | AES_ENCRYPT()、AES_DECRYPT()或SHA2() | |||
| InnoDB存储引擎 | innodb_file_format系列参数 | |||
innodb_support_xa | ||||
| 空间函数 | 非ST_前缀函数(如MBR_CONTAINS()) | 统一使用ST_前缀(如ST_CONTAINS()) | ||
| 安装与部署 | mysql_install_db | 改用mysqld --initialize或--initialize-insecure | ||
mysql_plugin | 启动参数--plugin-load或运行时INSTALL PLUGIN | |||
mysql_upgrade | ||||
| 分区与表管理 | ||||
FLOAT/DOUBLE列使用AUTO_INCREMENT | ||||
| 日志与变量 | expire_logs_days | binlog_expire_logs_seconds | ||
GLOBAL_VARIABLES 等系统变量表 | 改用performance_schema中的表 | |||
| 其他 | ||||
SET_USER_ID权限 | SET_ANY_DEFINER(创建对象) +ALLOW_NONEXISTENT_DEFINER(孤儿对象保护) |

之前我概述的写过线上数据库相关主机、软件、架构等升级方案,其中对于数据库升级的总体步骤如下:
• 调研待升级的数据库软件版本、新特性及向下兼容性等,并进行部署、测试
• 将测试结果进行总结并与研发、测试人员进行分享并制定升级计划
• 在开发及测试环境部署新版本数据库,并将新建应用及计划内升级的业务数据库部署在新版本数据库上
• 开发测试环境测试一个月以上(经过回归测试),如测试正常,则进行预发布及线上环境升级
• 线上环境先升级从库,调整相关参数,DBA 进行压力测试及基础的兼容性测试
• 从库测试完毕后,数据库进行主从切换,应用连接切换至新主库,原主库作为从节点加入集群,但原主库暂不升级(用于异常回退)
• 如新主库运行正常2周以上,则进行原主库升级
以上只是总体步骤,因为MySQL8.4毕竟当前才发布到8.4.5版本,还有一段时间的迭代和兼容测试时间,因此在接下来的一段时间里,会根据探索业务实际使用情况及测试结果进行详细的升级步骤及注意点的总结,也欢迎已经使用MySQL8.4版本的同学留言或进交流群沟通心得经验。

MySQL数据库BUG导致查询不到本该查到的数据
MySQL源码学习系列(一)-- 环境准备及常用命令
MySQL源码学习系列(二)--面试高频问题:general log、slowlog记录顺序
MySQL数据库修改小众参数解决大众问题
MySQL8.0 双密码机制:解决应用程序用户不停机修改密码问题
MySQL8.0.40编译安装
DBA面试题:MySQL缓存池LRU算法做了哪些改进?
慢SQL探秘之为什么我的SQL很慢却没记录在慢查询日志里
MySQL数据恢复








