Skip to content

MySQL 8 新特性与 5.7 升级指南

MySQL 8 不是简单增加几个 SQL 函数,而是同时升级了 SQL 表达能力、优化器、索引、InnoDB 数据字典、DDL、安全、JSON、GIS、复制和运维体系。

面试回答“相对 MySQL 5.7,MySQL 8 新增了什么”时,推荐先讲六个主干:

text
窗口函数和 CTE
→ 降序/不可见/函数索引
→ 事务数据字典与原子 DDL
→ utf8mb4 与新认证插件
→ EXPLAIN ANALYZE、直方图和 Hash Join
→ JSON、角色、SET PERSIST 与复制治理增强

本文主要比较 MySQL 5.7 与 MySQL 8.0,并单独说明 MySQL 8.4 LTS。MySQL 8.0 的功能是在多个小版本中逐步加入的,例如函数索引、CHECK 约束执行、EXPLAIN ANALYZE、多值索引和 Clone Plugin 都有具体版本门槛。生产使用时必须以目标小版本为准。

一张表快速看懂

领域MySQL 8 代表能力价值
SQLCTE、递归 CTE、窗口函数复杂查询表达更自然
索引降序索引、不可见索引、函数索引、多值索引覆盖更多访问模式,索引变更更可控
优化器直方图、EXPLAIN ANALYZE、Hash Join估算和真实执行分析能力增强
元数据事务型数据字典替代 .frm,元数据一致性更强
DDL原子 DDL、Instant DDL 能力演进崩溃一致性和在线变更能力提高
字符集默认 utf8mb4支持完整 Unicode
安全角色、caching_sha2_password、密码策略增强权限治理和认证安全提高
JSONJSON_TABLE、部分更新、多值索引半结构化数据查询能力增强
锁与并发NOWAITSKIP LOCKED队列消费和锁等待控制更灵活
运维SET PERSIST、Clone Plugin、资源组配置持久化、实例克隆和资源治理
复制GTID、并行复制、Group Replication 持续增强高可用和复制治理能力提高
移除Query Cache 等旧能力移除减少全局争用和历史包袱

1. 公共表表达式 CTE

MySQL 8 支持 with,可以把复杂子查询拆成命名步骤:

sql
with paid_orders as (
  select user_id, amount
  from orders
  where status = 'PAID'
    and created_at >= '2026-08-01'
)
select user_id, sum(amount) as total_amount
from paid_orders
group by user_id;

CTE 的主要价值是表达和复用查询逻辑,不保证天然更快。优化器可能合并 CTE,也可能将其物化;具体行为受版本、引用次数、查询结构和优化器决策影响,必须查看执行计划。

递归 CTE

适合组织树、分类树、菜单和层级路径:

sql
with recursive category_tree as (
  select id, parent_id, name, 0 as depth
  from category
  where id = 1

  union all

  select c.id, c.parent_id, c.name, t.depth + 1
  from category c
  join category_tree t on c.parent_id = t.id
  where t.depth < 20
)
select *
from category_tree;

生产要考虑:

  • 数据中是否存在环。
  • 最大递归深度。
  • 起点能否使用索引。
  • 每层展开行数。
  • 结果是否需要稳定排序。

2. 窗口函数

MySQL 8 支持排名、前后行、累计值和移动窗口:

sql
select user_id,
       order_id,
       amount,
       row_number() over (
         partition by user_id
         order by amount desc, order_id
       ) as rn,
       sum(amount) over (
         partition by user_id
         order by created_at, order_id
         rows between unbounded preceding and current row
       ) as running_total
from orders;

常见函数:

  • row_number
  • rank
  • dense_rank
  • lag
  • lead
  • first_value
  • last_value
  • nth_value
  • ntile
  • sum/avg/count over

窗口函数保留明细行,group by 则把多行折叠为每组一行。窗口函数通常需要排序,大结果集要关注临时表、排序空间和是否能提前过滤。

完整内容见 MySQL 函数

3. 降序索引

MySQL 8 支持真正的降序索引键:

sql
create index idx_orders_user_created
on orders(user_id asc, created_at desc, order_id desc);

适合:

sql
select order_id, created_at
from orders
where user_id = ?
order by created_at desc, order_id desc
limit 20;

MySQL 5.7 可以反向扫描索引,但对联合索引中混合升降序的支持能力有限。MySQL 8 的真实降序键更容易支持混合方向排序。

仍需注意:

  • 有降序索引不代表一定被选择。
  • 等值过滤、范围条件和排序顺序仍要符合联合索引结构。
  • 新增索引仍会增加写入和空间成本。

4. 不可见索引

不可见索引仍由 InnoDB 维护,但优化器默认不把它作为普通查询候选路径:

sql
alter table orders
  alter index idx_status invisible;

alter table orders
  alter index idx_status visible;

用途是低风险评估“删除这个索引会怎样”:

  1. 先将待删除索引设为不可见。
  2. 观察核心 SQL、慢日志、CPU、IO 和延迟。
  3. 确认没有执行计划退化后再删除。
  4. 出现问题时可以快速重新设为可见,不必重建整个索引。

但不可见索引仍占空间并承担写入维护成本,所以不能作为长期保留无用索引的方案。主键和保证约束所需的索引也有额外限制,不能随意隐藏。

5. 函数索引

MySQL 8.0.13 起支持符合限制的函数/表达式索引:

sql
create index idx_users_lower_email
on users ((lower(email)));

查询:

sql
select id
from users
where lower(email) = lower(?);

它解决“高频查询确实必须按表达式检索”的问题,但不能替代可索引 SQL 改写。例如:

sql
-- 不推荐直接依赖函数索引解决
where date(created_at) = '2026-08-04'

-- 通常优先改为原始范围
where created_at >= '2026-08-04 00:00:00'
  and created_at <  '2026-08-05 00:00:00'

函数索引要求表达式、类型、字符集和 collation 匹配,并会增加写入计算、索引空间和 Buffer Pool 压力。

6. 多值索引

MySQL 8.0.17 起为部分 JSON 数组访问场景提供多值索引能力。它可以为同一行 JSON 数组中的多个标量值建立索引入口。

概念示意:

sql
create table articles (
  id bigint primary key,
  tags json not null
);

多值索引的具体表达式、支持的类型和可使用的 JSON 谓词受小版本限制,不能把普通函数索引语法直接套用。使用前必须核对目标版本,并用真实查询执行计划验证。

适合 JSON 数组成员查询,但稳定且高频关联的标签仍要评估关系表:

text
article_tag(article_id, tag_id)

关系表通常更容易约束、Join、统计和治理。

7. 直方图统计信息

传统索引基数无法完整描述极端数据倾斜。MySQL 8 可以为列创建直方图:

sql
analyze table orders
update histogram on status, tenant_id
with 100 buckets;

查看:

sql
select table_name, column_name, histogram
from information_schema.column_statistics
where schema_name = database()
  and table_name = 'orders';

删除:

sql
analyze table orders
drop histogram on status;

适合:

  • 数据分布严重不均匀。
  • 优化器经常错误估算选择性。
  • 某列没有适合的普通索引,但参与过滤成本估算。

直方图不是索引,不会让查询直接定位数据;它帮助优化器估算。数据分布变化后需要重新评估和更新。

8. EXPLAIN ANALYZE

MySQL 8.0.18 起支持 EXPLAIN ANALYZE,会真实执行查询并输出实际耗时、实际行数和循环次数:

sql
explain analyze
select order_id, amount
from orders
where user_id = ?
order by created_at desc
limit 20;

它可以回答:

  • 优化器估算行数和实际行数差多少。
  • 哪个算子真正耗时。
  • Nested Loop 执行了多少次。
  • 过滤后实际保留多少行。
  • 是否因估算错误选错驱动表或索引。

风险是它会真实执行 SQL。生产使用前要确认:

  • 是只读查询。
  • 不会扫描或返回海量数据。
  • 不会长时间持有锁或消耗资源。
  • 最好先在低风险环境使用真实数据分布验证。

9. Hash Join

MySQL 8.0.18 起逐步引入 Hash Join,适合某些等值连接,尤其是被连接侧缺少合适索引时。

简化过程:

text
读取较小输入 → 建 Hash 表 → 扫描另一输入 → 按 Join Key 匹配

与 Nested Loop 的区别:

对比Nested LoopHash Join
核心方式驱动表每行到另一侧匹配一侧建 Hash,另一侧探测
适合被驱动表 Join Key 有索引、结果较小等值 Join、缺少适合索引、批量匹配
主要成本多次索引查找或扫描构建 Hash、内存和可能的分批处理

不能手工指定“所有 Join 都用 Hash”。最终由优化器结合统计信息、连接条件、索引、数据量和成本选择。范围连接和非等值连接也不能简单使用等值 Hash 匹配理解。

10. 事务型数据字典

MySQL 5.7 时代,表结构等元数据分散在 .frm 文件、InnoDB 内部字典和系统表中,元数据与存储引擎状态可能不一致。

MySQL 8 使用 InnoDB 存储统一的事务型数据字典,主要收益:

  • 元数据更新具备更好的事务一致性。
  • 不再依赖传统 .frm 文件作为表定义来源。
  • 元数据查询和管理更加统一。
  • 为原子 DDL、崩溃恢复和信息模式改进打基础。

运维影响:

  • 不能复制 .frm 文件恢复表结构。
  • 不能把升级后的数据目录直接交给旧版本读取。
  • 不能通过切回旧容器镜像回滚 MySQL 8 数据目录。
  • 备份、恢复、升级和字典校验必须使用受支持流程。

11. 原子 DDL

MySQL 8 的数据字典、存储引擎操作和 binlog 可以更一致地协调部分 DDL,使其在崩溃后表现为完整提交或完整回滚,而不是留下部分元数据和部分文件状态。

需要准确理解:

  • 原子 DDL 主要解决 DDL 自身的崩溃一致性。
  • 不等于应用可以把任意 DDL 和 DML 放入一个普通事务后一起回滚。
  • 不等于 DDL 零锁等待、零 IO、零磁盘空间。
  • 一条原子 DDL 仍可能因 MDL、表扫描和索引重建影响线上业务。

12. Instant DDL

MySQL 8.0.12 起引入 Instant ADD COLUMN,并在后续小版本扩展 Instant DDL 的适用范围。符合条件的操作主要修改元数据,不需要复制或重建整表。

示意:

sql
alter table orders
  add column source varchar(32) null,
  algorithm = instant;

生产必须确认:

  • 目标小版本是否支持该具体操作。
  • 列位置、行格式、表历史变更和操作类型是否满足限制。
  • 指定 algorithm=instant 后不支持时应失败,避免静默退化为高风险算法。
  • 即使 Instant,也可能需要短暂 MDL。
  • 新旧应用版本是否同时兼容字段变化。

详细内容见 分区、归档与在线 DDL

13. CHECK 约束真正执行

MySQL 5.7 能解析部分 check 语法,但通常不真正执行约束。MySQL 8.0.16 起开始执行 CHECK 约束:

sql
create table account (
  id bigint primary key,
  balance decimal(18, 2) not null,
  constraint chk_balance_nonnegative
    check (balance >= 0)
);

约束价值:

  • 不论数据来自哪个应用、脚本或任务,都由数据库守住底线。
  • 比只在 Service 层校验更可靠。
  • 约束名能帮助错误定位和迁移管理。

CHECK 不能表达所有跨行和跨表业务规则。库存扣减等并发业务仍要使用条件更新、锁和正确事务边界。

14. NOWAIT 与 SKIP LOCKED

MySQL 8 为加锁读取提供更灵活的等待策略。

NOWAIT

目标记录已被锁定时立即失败,不等待锁超时:

sql
select *
from jobs
where id = ?
for update nowait;

适合应用能够立即返回冲突或改走其他任务的场景。

SKIP LOCKED

跳过已锁记录:

sql
select id, payload
from jobs
where status = 'PENDING'
order by id
limit 10
for update skip locked;

多个消费者可以并发领取不同任务,但要注意:

  • 跳过锁会使结果不是严格的完整一致视图。
  • 任务状态更新、提交、失败重试和超时回收必须设计。
  • order by 不保证所有任务绝对公平。
  • 长时间失败任务可能饥饿。
  • 它不能替代成熟消息队列的持久化、重试、顺序和消费治理。

15. 默认字符集变为 utf8mb4

MySQL 8 默认字符集采用 utf8mb4,默认 collation 在常见 MySQL 8.0 环境中为 utf8mb4_0900_ai_ci

收益:

  • 支持完整四字节 Unicode。
  • 可以保存 Emoji 和补充平面字符。
  • 基于较新的 Unicode 排序规则。

升级风险:

  • 默认变化不会自动保证旧库、旧表和旧列都转换完成。
  • 新旧 collation 的比较、排序和唯一键结果可能不同。
  • 原本不同的字符串可能在新规则下相等,导致唯一索引迁移失败。
  • 跨库、跨表比较可能出现 collation 冲突。
  • 索引字节长度和存储空间要重新评估。

详细内容见 字符集、排序规则与时区

16. 账号角色 Role

MySQL 8 支持角色,可以把权限集合授予角色,再把角色分配给用户:

sql
create role 'report_reader';
grant select on app_db.* to 'report_reader';
grant 'report_reader' to 'analyst'@'10.%';
set default role 'report_reader' to 'analyst'@'10.%';

优势:

  • 权限按职责管理。
  • 减少大量用户逐个授权。
  • 人员调岗和离职更容易回收。
  • 更适合定期权限审计。

角色仍需最小授权。把一个全局高权限角色授给所有应用账号,只是换了一种过度授权方式。

17. 默认认证插件变化

MySQL 8.0 默认使用更安全的 caching_sha2_password,而很多 MySQL 5.7 客户端和旧驱动主要围绕 mysql_native_password

升级常见问题:

  • 旧 JDBC 驱动无法认证。
  • 客户端工具不支持新插件。
  • 未启用 TLS 时出现公钥获取或安全连接问题。
  • 团队为了兼容直接把所有账号改回旧插件。

正确方向:

  1. 先升级 JDBC 驱动、客户端和连接池。
  2. 启用并验证 TLS。
  3. 在测试环境验证账号创建、密码轮换和连接参数。
  4. 临时兼容旧插件必须限定账号、来源和退出时间。

MySQL 8.4 默认禁用 mysql_native_password,这使得依赖旧插件的应用更容易在升级后直接连接失败。升级到 8.4 前必须先完成客户端兼容治理。

18. SET PERSIST

MySQL 8 支持把部分动态系统变量持久化:

sql
set persist max_connections = 500;

set global 的区别:

  • set global 通常修改运行中全局值,但重启后可能丢失。
  • set persist 修改运行值,并写入持久化配置文件供重启加载。
  • set persist_only 只写持久化值,不一定立即改变当前运行值,适合部分只读或需要重启的配置场景。

风险:

  • 配置来源变成配置文件、启动参数和持久化变量多层叠加。
  • 手工修改后容易与配置管理系统产生漂移。
  • 参数合法不等于容量合理,例如增大连接数可能导致内存耗尽。

生产应保留变更审批、当前值、持久值、回滚命令和配置同步记录。

19. Resource Group

MySQL 8 的资源组可以将线程绑定到资源组,并对 CPU 资源进行一定程度的优先级和处理器范围治理。

适合区分:

  • 在线交易。
  • 低优先级报表。
  • 后台维护任务。

它不是完整的数据库多租户资源隔离,也不能单独限制所有 IO、锁、Buffer Pool 和磁盘空间。云环境、容器和操作系统层的 CPU 可见性也会影响效果,必须在目标部署环境验证。

20. Clone Plugin

MySQL 8.0.17 起提供 Clone Plugin,可以将 InnoDB 实例数据从供体克隆到接收实例,常用于快速部署副本或恢复环境。

需要考虑:

  • 源端与目标端版本兼容。
  • 插件、权限和网络。
  • 克隆期间源端负载。
  • 目标实例原数据处理。
  • 磁盘空间和传输带宽。
  • 克隆完成后复制位点、GTID 和拓扑接入。

Clone 不是长期备份策略,也不能代替异地、不可变、可时间点恢复的备份。

21. JSON 能力增强

MySQL 5.7 已经引入原生 JSON,MySQL 8 在此基础上继续增强:

  • JSON_TABLE:把 JSON 文档展开成关系行。
  • JSON 路径表达和函数持续增强。
  • JSON 部分更新优化,符合条件时减少不必要的完整文档重写成本。
  • JSON 数组多值索引。
  • JSON 聚合和查询能力完善。

示例:

sql
select p.id, jt.sku_id, jt.quantity
from products p
join json_table(
  p.attributes,
  '$.items[*]' columns (
    sku_id bigint path '$.skuId',
    quantity int path '$.quantity'
  )
) as jt;

JSON 增强不代表应该把关系模型整体塞进 JSON。经常过滤、排序、关联、约束和统计的核心字段仍应关系化。

22. GIS 与空间能力增强

MySQL 8 对空间数据提供更完整的 SRID、坐标系、地理函数和空间索引能力。

生产必须明确:

  • Geometry 使用什么 SRID。
  • 经度纬度的轴顺序。
  • 距离单位。
  • 平面计算还是地球表面计算。
  • 空间索引是否可用。

升级旧空间数据前要校验无效几何、缺失 SRID 和函数结果差异,不能只看 SQL 是否执行成功。

23. 信息模式和 Performance Schema 增强

由于统一数据字典,很多 information_schema 元数据查询不再依赖旧式逐文件扫描,元数据管理和缓存能力得到改进。Performance Schema、sys schema 和监控视图也持续增强,可用于:

  • SQL Digest。
  • 锁和元数据锁。
  • 事务、线程和等待事件。
  • 内存与 IO 观察。
  • 复制和错误分析。

监控查询本身也有成本,事故时不要运行无条件的大范围诊断 SQL。

24. 复制与高可用增强

MySQL 8 持续增强:

  • GTID 管理。
  • 基于写集合依赖的并行复制能力。
  • Group Replication。
  • InnoDB Cluster 与 MySQL Router 生态。
  • 复制状态和 Performance Schema 观测。
  • Source/Replica 新术语。
  • 二进制日志过期时间的秒级配置。

并行复制不能让所有事务无限并行。存在相同依赖、超大事务、DDL、从库资源不足或热点表时,复制仍会延迟。

高可用也不等于备份。误删和错误 DDL 会复制到副本,仍要保留独立全量备份和 binlog,并定期恢复演练。

25. Query Cache 被移除

MySQL 8 移除了 Query Cache。

旧 Query Cache 按 SQL 文本缓存完整结果,表数据发生变化时需要失效相关缓存。在高并发写入环境中,维护和全局争用成本较高,而且只要 SQL 文本或会话上下文不同也可能无法复用。

MySQL 8 的缓存重点是 InnoDB Buffer Pool:

  • Buffer Pool 缓存数据页和索引页。
  • 不缓存一条 SQL 的最终完整结果。
  • 业务结果缓存通常由 Redis、本地缓存或应用层承担。

面试不要回答“MySQL 8 没有缓存”,而应回答“移除了 Server 层旧 Query Cache,但 InnoDB Buffer Pool 仍是核心页缓存”。

26. GROUP BY 不再依赖隐式排序

旧项目可能错误依赖 group by 返回结果“看起来按分组列有序”。MySQL 8 不应依赖这种隐式顺序。

如果业务要求顺序,必须显式写:

sql
select status, count(*)
from orders
group by status
order by status;

SQL 没有 order by 就不保证返回顺序,不论测试环境当前结果看起来多稳定。

27. 关键移除项与兼容变化

从 MySQL 5.7 升级时重点检查:

变化风险
Query Cache 移除旧参数无法继续使用,应用误判缓存行为
.frm 被数据字典替代旧文件级恢复和降级思路失效
默认字符集/collation 改变比较、排序、唯一键、索引长度变化
默认认证插件改变旧驱动和工具无法连接
新增保留字表名、列名和 SQL 解析失败
SQL mode 与严格校验非法日期、截断、分组 SQL 暴露问题
CHECK 开始真正执行历史不合规数据和新写入失败
元数据与 DDL 实现变化不能通过回切旧二进制降级
空间数据语义增强SRID、轴顺序和函数结果变化
部分旧语法、参数和插件废弃或移除启动、连接或运维脚本失败

不要只测试应用启动。必须扫描全部 Schema、SQL、驱动、账号、备份、复制、监控和运维脚本。

MySQL 8.0 与 8.4 LTS

MySQL 8.4 是 LTS 版本,重点是长期维护和稳定支持,而不是“另一个完全不同的数据库”。从 8.0 升到 8.4 仍然要当作正式数据库升级处理。

特别关注:

  • mysql_native_password 在 8.4 默认禁用,旧客户端可能无法连接。
  • 8.0 中已经弃用的变量、语法或插件,可能在 8.4 进一步禁用或移除。
  • 复制、Group Replication、监控字段和默认配置可能变化。
  • Connector/J、ORM、备份工具、Proxy 和运维平台必须验证兼容。
  • 升级数据目录后不能把旧版本镜像当作回滚方案。

选择版本时应结合官方支持周期、云厂商支持、驱动兼容、插件和团队运维能力,不是盲目追求最高版本。

从 5.7 升级到 8.x 的完整流程

1. 建立资产清单

记录:

  • MySQL 精确版本和安装方式。
  • 数据库、表、分区、视图、触发器、事件、存储过程和函数。
  • 字符集、collation、时区和 SQL mode。
  • 账号、认证插件、权限和来源地址。
  • 复制拓扑、GTID、binlog 格式和保留时间。
  • 备份工具、恢复步骤和 RPO/RTO。
  • JDBC 驱动、ORM、连接池、CDC 和代理版本。

2. 运行升级检查

使用目标版本支持的升级检查工具,例如 MySQL Shell 的 Upgrade Checker,并人工审查:

  • 新保留字冲突。
  • 废弃或移除的变量和语法。
  • 不兼容数据类型和默认值。
  • 非法日期和损坏元数据。
  • 字符集与 collation。
  • 认证插件。
  • 存储程序和视图定义。

工具通过不等于业务兼容,应用 SQL 仍需回归。

3. 升级客户端和驱动

先让当前 MySQL 5.7 环境运行兼容 MySQL 8 的新驱动和连接配置:

  • Connector/J。
  • MyBatis/JPA/Hibernate。
  • 连接池。
  • 数据库迁移工具。
  • CDC、备份、监控和审计工具。

这样可以把客户端兼容风险和数据库升级风险拆开。

4. 建立生产规模演练环境

用生产备份恢复出隔离实例:

  1. 验证备份真的可恢复。
  2. 按正式步骤升级副本或克隆环境。
  3. 运行 Schema 检查和数据校验。
  4. 回放核心读写流量。
  5. 比较执行计划、P95/P99、CPU、IO、锁和复制。
  6. 测试备份、恢复和故障切换。

空库或少量测试数据无法暴露真实升级风险。

5. SQL 兼容回归

重点测试:

  • group by 非确定写法。
  • 新保留字作为表名、列名或别名。
  • 隐式类型转换。
  • 非法日期和超长截断。
  • JSON、GIS 和全文检索。
  • 存储过程、函数、触发器和事件。
  • 分页顺序是否依赖隐式行为。
  • ORM 生成 SQL。

6. 执行计划回归

统计信息、成本模型、Join 算法和字符集变化可能让同一 SQL 选择不同执行计划。

对 Top SQL 建立基线:

  • 调用次数。
  • 平均与 P95/P99。
  • Rows_examined / Rows_sent。
  • EXPLAIN
  • EXPLAIN ANALYZE 的实际行数和耗时。
  • 临时表和排序。
  • 锁等待。

不要看到新版本整体压测更快就忽略少数核心 SQL 退化。

7. 设计升级和切换

常见路线是先升级副本或建立新版本实例,完成数据同步与验证后再切流。具体能否使用滚动升级、复制兼容方向和直接升级路径,必须按源版本与目标版本官方矩阵确认。

切换前准备:

  • 变更窗口。
  • 停写或增量追平策略。
  • 旧主隔离,防止双写。
  • 应用连接和 DNS/代理刷新。
  • 数据校验。
  • 失败终止条件。
  • 业务补偿方案。

8. 回滚不是切旧镜像

MySQL 8 数据字典和磁盘格式升级后,通常不能把数据目录直接交回 MySQL 5.7 或更旧 8.x 二进制。

真正的回滚方案通常是:

  • 升级前保留经过验证的备份。
  • 切换前保留旧集群且隔离写入。
  • 迁移期间设计反向增量或明确停止点。
  • 新版本写入后若要回旧集群,必须处理这段增量数据。
  • 重大故障时从备份恢复,而不是启动旧镜像读取新数据目录。

9. 升级后验收

  • 核心读写、事务和锁行为正确。
  • 字符集、时区、排序和唯一键正确。
  • 账号、TLS 和认证插件正确。
  • 主从复制、GTID、延迟和故障切换正常。
  • 备份和 PITR 可用。
  • Top SQL 没有计划退化。
  • 监控、慢日志和告警正常。
  • 旧参数、废弃警告和错误日志完成清理。

哪些能力最值得项目立即使用

优先级高

  • utf8mb4 与明确 collation。
  • EXPLAIN ANALYZE 用于低风险环境性能验证。
  • 窗口函数和 CTE 改善复杂查询表达。
  • 角色实现权限分组。
  • CHECK 和数据库约束守住数据底线。
  • 不可见索引用于索引删除评估。
  • SET PERSIST 配合规范的配置治理。

按场景使用

  • 函数索引:表达式查询高频且无法改写。
  • 多值索引:特定 JSON 数组成员检索。
  • Hash Join:由优化器选择,不是业务手动开关万能优化。
  • SKIP LOCKED:数据库任务队列或并发领取。
  • Instant DDL:目标版本和操作确实支持。
  • Clone Plugin:副本部署和恢复辅助。
  • Resource Group:明确的 CPU 资源治理场景。

不要因为“新”就使用

  • 不要把所有查询改成 CTE。
  • 不要给所有表达式建立函数索引。
  • 不要把所有属性塞进 JSON。
  • 不要用 SKIP LOCKED 重新实现一套缺少治理能力的消息队列。
  • 不要认为原子 DDL 等于在线无影响。
  • 不要为使用 Hash Join 故意删除正确索引。

高频面试题

MySQL 8 相比 5.7 有哪些主要变化

text
SQL 层增加了 CTE、递归 CTE 和窗口函数;索引增加了降序索引、不可见索引和函数索引;优化器增加了直方图、EXPLAIN ANALYZE 和 Hash Join;底层使用 InnoDB 事务型数据字典替代 .frm,并增强原子 DDL 和 Instant DDL;默认字符集改为 utf8mb4,默认认证使用 caching_sha2_password;还增加了角色、SET PERSIST、NOWAIT/SKIP LOCKED、JSON_TABLE、多值索引和 Clone Plugin 等能力。同时移除了 Query Cache。升级时要重点检查驱动、认证插件、字符集/collation、保留字、SQL mode、CHECK 约束、执行计划和数据字典,不能通过回切旧镜像降级。

MySQL 8 为什么移除 Query Cache

Query Cache 按 SQL 文本缓存完整结果,表发生写入后需要维护和失效相关缓存,高并发写入下容易产生全局争用,而且 SQL 文本和上下文稍有变化就难以复用。MySQL 8 移除的是旧的结果 Query Cache,InnoDB Buffer Pool 仍然负责缓存数据页和索引页。

不可见索引有什么用

不可见索引仍维护但默认不参与优化器选路,可以在真正删除索引前观察执行计划和线上指标。如果发生退化,可以快速改回可见而不用重建;确认安全后再删除,释放写入和空间成本。

原子 DDL 和事务 DDL 是一回事吗

不是。原子 DDL 主要保证一条 DDL 涉及的数据字典、存储引擎和 binlog 状态在崩溃后完整提交或回滚;它不表示任意 DDL 可以与业务 DML 放在普通事务里一起提交回滚,也不表示 DDL 没有 MDL、IO 和重建成本。

5.7 升 8.0 最容易踩什么坑

旧驱动不支持 caching_sha2_password、默认字符集和 collation 改变、新增保留字、严格 SQL mode 暴露非法数据、CHECK 开始执行、依赖 group by 隐式顺序、执行计划变化,以及数据字典升级后无法回切旧二进制。必须先升级客户端、运行升级检查、用生产规模数据演练并准备基于旧集群或备份的回滚方案。

MySQL 8.4 和 8.0 怎么选

8.4 是 LTS 路线,适合重视长期支持的新部署,但必须确认驱动、认证插件、工具和废弃项兼容;已有 8.0 系统不能只因为 8.4 更新就立即升级,应依据支持周期、正式升级矩阵、演练结果和业务收益决定。特别要处理 8.4 默认禁用 mysql_native_password 的影响。

自测清单

  • 能不用看资料说出 MySQL 8 的六类核心变化。
  • 能写 CTE、窗口函数和 SKIP LOCKED 示例。
  • 能解释降序、不可见、函数和多值索引的区别。
  • 能解释直方图不是索引,EXPLAIN ANALYZE 会真实执行。
  • 能区分原子 DDL、Instant DDL 和普通事务。
  • 能解释事务数据字典为什么让旧镜像回滚失效。
  • 能说明 utf8mb4、collation 与认证插件升级风险。
  • 能给出从 5.7 到 8.x 的升级、验证和回滚流程。
  • 能说明 MySQL 8.0 与 8.4 LTS 的关系。
  • 能结合项目说出哪些新特性值得使用、哪些不应滥用。

关联知识点

本章小结

MySQL 8 的核心升级可以概括为:SQL 更强、优化证据更完整、索引类型更丰富、元数据和 DDL 更可靠、安全默认值更现代、JSON 和运维治理能力更完整。升级价值不仅是使用窗口函数,更重要的是获得事务数据字典、原子 DDL、优化器与安全体系的整体演进。真正上线前仍要锁定小版本,用生产规模数据验证驱动、SQL、执行计划、复制、备份和回滚。