MySQL 5.6 到 5.7 到 8.0 关键差异速查
导学
MySQL 5.7 是承上启下的版本——它修复了 5.6 的诸多痛点,又为 8.0 的变革埋下伏笔。理解三个版本的关键差异,能帮助你在迁移、面试和日常运维中做出正确决策。本节不罗列所有变更,只聚焦影响日常开发和运维的核心差异。
版本发布时间线
一、SQL_MODE 与严格模式
| 版本 | 默认 SQL_MODE | 对开发的影响 |
|---|---|---|
| 5.6 | NO_ENGINE_SUBSTITUTION | 非常宽松。INSERT 超出字段长度自动截断并警告;NOT NULL 列插入 NULL 自动转为默认值;日期非法值转为 0000-00-00。 |
| 5.7 | ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION | 严格模式默认开启。超出长度报错;NOT NULL 插入 NULL 报错;0000-00-00 日期报错。这是 5.6→5.7 迁移最常见的坑。 |
| 8.0 | 与 5.7 基本相同,增加 NO_AUTO_CREATE_USER 等 | 更严格。GROUP BY 行为进一步收紧;NO_ZERO_DATE 默认开启。 |
迁移注意:5.6 升级到 5.7 后,如果应用依赖了 5.6 的宽松行为(如截断、零日期),会直接报错。升级前应在测试环境用 5.7 的默认 SQL_MODE 跑一遍全量测试。
验证当前 SQL_MODE:
SELECT @@sql_mode;
| @@sql_mode |
|---|
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
二、默认存储引擎
| 版本 | 默认引擎 | 说明 |
|---|---|---|
| 5.6 | InnoDB | 5.5 开始 InnoDB 已是默认,5.6 继续。但部分旧系统可能仍有 MyISAM 表。 |
| 5.7 | InnoDB | 全面 InnoDB 化。临时表也默认使用 InnoDB(internal_tmp_disk_storage_engine = InnoDB)。 |
| 8.0 | InnoDB | 彻底移除 MyISAM 系统表,全部元数据存入 InnoDB。MyISAM 仅作为可选引擎保留。 |
迁移注意:5.6 升级到 5.7 时,建议将残余的 MyISAM 表转为 InnoDB:ALTER TABLE xxx ENGINE=InnoDB;。MyISAM 不支持事务、崩溃恢复、行级锁,不应再用于生产。
三、binlog 格式与 GTID
| 版本 | 默认 binlog_format | GTID | 说明 |
|---|---|---|---|
| 5.6 | STATEMENT | 支持但默认关闭 | STATEMENT 格式在某些函数(UUID()、RAND())下主从不一致。 |
| 5.7 | ROW | 支持,默认关闭但强烈推荐开启 | ROW 格式成为默认,数据一致性最好。GTID 简化主从切换,故障恢复不再需要找 binlog 位置。 |
| 8.0 | ROW | 默认开启 | GTID 成为默认配置,主从架构更健壮。 |
迁移注意:
- 5.6 的
STATEMENT格式升级到 5.7 后变为ROW,binlog 体积会增大(ROW 记录每行变更前后镜像)。需预留更多磁盘空间。 - 开启 GTID 后,
CREATE TABLE ... SELECT等语句会受限(GTID 一致性要求),需改用CREATE TABLE+INSERT SELECT分步执行。
验证:
SELECT @@binlog_format, @@gtid_mode;
| @@binlog_format | @@gtid_mode |
|---|---|
| ROW | ON |
四、密码验证插件
| 版本 | 默认密码插件 | 特点 |
|---|---|---|
| 5.6 | mysql_native_password | 使用 SHA-1 哈希,兼容性好。 |
| 5.7 | mysql_native_password | 与 5.6 相同。但 5.7.6+ 引入 validate_password 插件(默认安装),强制密码复杂度。 |
| 8.0 | caching_sha2_password | 使用 SHA-256 哈希,安全性更高。但旧客户端(如老版本 JDBC、Navicat)可能无法连接,需升级驱动或改回 mysql_native_password。 |
迁移注意:5.7 升级到 8.0 时,如果应用使用旧版连接驱动,可能报 Authentication plugin 'caching_sha2_password' cannot be loaded。解决:1. 升级客户端驱动;2. 或创建用户时显式指定 mysql_native_password:
CREATE USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'Password123!';
五、JSON 支持
| 版本 | JSON 支持 | 说明 |
|---|---|---|
| 5.6 | ❌ 无原生 JSON | 只能用 TEXT/VARCHAR 存 JSON 字符串,无法高效查询和索引。 |
| 5.7 | ✅ 原生 JSON 类型 | 引入 JSON 数据类型,支持 JSON_EXTRACT、JSON_SET 等函数,支持虚拟列 + 索引(GENERATED ALWAYS AS)。 |
| 8.0 | ✅ 增强 JSON | 增加 JSON_TABLE(将 JSON 转为关系表)、JSON_OVERLAPS、JSON_VALUE 等函数,性能进一步优化。 |
迁移注意:5.6 升级到 5.7 时,如果原有 TEXT 列存 JSON,可以逐步迁移为 JSON 类型以获得校验和高效查询能力。但 JSON 类型有存储限制(最大 1GB),且不支持直接作为分区键。
六、InnoDB 增强
| 特性 | 5.6 | 5.7 | 8.0 |
|---|---|---|---|
| 全文索引(InnoDB) | ❌ 仅 MyISAM | ✅ InnoDB 支持 | 增强,支持 ngram 分词 |
| 空间索引(GIS) | 有限支持 | 增强 | 完整支持,支持空间数据类型和函数 |
| 临时表优化 | 内存临时表用 MEMORY 引擎 | 默认 InnoDB,支持独立临时表空间 | 进一步优化 |
| Buffer Pool 动态调整 | 支持 | 支持,更稳定 | 支持 |
| Undo Tablespace 独立 | ❌ undo 在 ibdata1 中 | ✅ 支持独立 undo 表空间 | 默认独立,支持在线收缩 |
| Tablespace 传输 | 支持 | 支持,更完善 | 支持 |
迁移注意:5.6 升级到 5.7 后,InnoDB 全文索引可用于替代 MyISAM 的全文场景。5.7 支持独立 undo 表空间,建议升级后将 undo 从 ibdata1 中分离,避免系统表空间无限膨胀。
七、查询优化器变化
| 版本 | 关键变化 |
|---|---|
| 5.6 | 基础优化器,子查询优化较弱(常转为笛卡尔积)。 |
| 5.7 | 引入Derived Condition Pushdown(派生表条件下推)、Cost Model 改进(基于成本的优化更精确)、EXPLAIN FORMAT=JSON 更详细。 |
| 8.0 | Cost Model 可配置(mysql.server_cost、mysql.engine_cost)、Common Table Expressions (CTE)、Window Functions(窗口函数)。 |
迁移注意:5.6 升级到 5.7 后,某些查询的执行计划可能变化(成本模型调整)。升级后应使用 EXPLAIN 对比关键查询的执行计划,确认索引使用无退化。
八、字符集默认变化
| 版本 | 默认字符集 | 说明 |
|---|---|---|
| 5.6 | latin1 | 不支持完整中文和 emoji,需手动改为 utf8mb4。 |
| 5.7 | latin1(未变) | 但 utf8mb4 支持已完善,强烈建议显式设置。 |
| 8.0 | utf8mb4 | 默认字符集终于改为 utf8mb4,排序规则默认 utf8mb4_0900_ai_ci(基于 Unicode 9.0)。 |
迁移注意:5.7 升级到 8.0 时,如果原有表是 utf8mb4_unicode_ci(5.7),8.0 默认使用 utf8mb4_0900_ai_ci,两者排序结果可能不同。升级时需统一排序规则或显式指定原排序规则。
九、关键参数默认值变化
| 参数 | 5.6 默认值 | 5.7 默认值 | 8.0 默认值 | 影响 |
|---|---|---|---|---|
innodb_buffer_pool_size | 128M | 128M | 128M | 均需手动调优 |
innodb_buffer_pool_instances | 1(<1GB)或 8 | 1 或 8 | 1 或 8 | 大内存时建议调大 |
innodb_log_file_size | 48M | 48M | 48M | 大事务场景需调大 |
innodb_flush_log_at_trx_commit | 1 | 1 | 1 | 核心交易保持 1 |
max_connections | 151 | 151 | 151 | 高并发需调大 |
explicit_defaults_for_timestamp | OFF | ON | ON | 5.7 起 TIMESTAMP 列行为变化,不再自动赋默认值 |
log_timestamps | — | UTC | UTC | 日志时间戳统一为 UTC |
迁移注意:explicit_defaults_for_timestamp = ON 是 5.7 的重要变化。5.6 中第一个 TIMESTAMP 列会自动设为 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,5.7 起不再自动赋予。升级后需显式声明 DEFAULT 和 ON UPDATE,否则 INSERT 不指定该列时会报错。
十、移除和废弃特性
| 特性 | 5.6 | 5.7 | 8.0 |
|---|---|---|---|
PASSWORD() 函数 | ✅ 可用 | ⚠️ 废弃 | ❌ 移除 |
OLD_PASSWORD() 函数 | ✅ 可用 | ⚠️ 废弃 | ❌ 移除 |
NO_AUTO_CREATE_USER | 无 | SQL_MODE 默认包含 | 默认包含,且 GRANT 自动创建用户被移除 |
Query Cache | ✅ 默认开启 | ⚠️ 默认关闭,建议禁用 | ❌ 彻底移除 |
mysql_install_db | ✅ 可用 | ⚠️ 废弃 | ❌ 移除,用 mysqld --initialize |
myisam_repair_threads | ✅ | ⚠️ | ❌ |
迁移注意:
PASSWORD()在 5.7 已废弃,8.0 移除。应用层密码哈希应改用SHA2()或应用层库(如 bcrypt)。- Query Cache 在 5.7 默认关闭(
query_cache_type = OFF),高并发下锁竞争严重。8.0 彻底移除,应改用应用层缓存(Redis)或 ProxySQL 缓存。
常见误区
| 误区 | 正解 |
|---|---|
| "5.7 是 5.6 的小版本升级" | 不是。5.7 有大量不兼容变更(SQL_MODE、密码插件行为、timestamp 默认值),必须做充分测试。 |
| "8.0 可以直接平滑升级" | 可以,但需注意 caching_sha2_password、默认排序规则变化、移除 Query Cache 等。建议先用逻辑备份(mysqldump)重建,再验证。 |
| "5.7 的 utf8 就是 utf8mb4" | 不是。5.7 默认仍是 latin1,必须显式设置 utf8mb4。utf8 在 MySQL 中仍是阉割版 3 字节实现。 |
| "GTID 开启后没有任何限制" | 有。CREATE TABLE ... SELECT、TEMPORARY TABLE 在 GTID 模式下受限,某些运维操作(如 sql_slave_skip_counter)不可用。 |
面试考点
Q:MySQL 5.6 升级到 5.7 最常见的坑是什么?
默认 SQL_MODE 变严格。5.6 的宽松模式允许截断、零日期、
NULL自动转默认值,5.7 默认STRICT_TRANS_TABLES+NO_ZERO_DATE+ONLY_FULL_GROUP_BY,这些在 5.6 能跑的应用在 5.7 会直接报错。升级前必须全量测试。
Q:5.7 升级到 8.0 连接报错 caching_sha2_password 怎么办?
8.0 默认密码插件从
mysql_native_password(SHA-1)改为caching_sha2_password(SHA-256)。旧客户端驱动不支持新插件。解决:1. 升级 JDBC/驱动到支持 8.0 的版本;2. 或创建用户时显式指定IDENTIFIED WITH mysql_native_password。
Q:5.7 的 explicit_defaults_for_timestamp = ON 有什么影响?
5.6 中第一个
TIMESTAMP列会自动获得DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。5.7 起这个行为消失,必须显式写DEFAULT和ON UPDATE,否则INSERT不指定该列时报错。这是 5.6→5.7 迁移中 timestamp 列报错的常见原因。
Q:Query Cache 为什么被移除?
Query Cache 在表有任何写入时就会清空该表相关的所有缓存,且高并发下
QC锁竞争严重(成为瓶颈)。5.7 默认关闭,8.0 彻底移除。替代方案:应用层缓存(Redis)、数据库代理缓存(ProxySQL)。
小结
- 5.7 相比 5.6:SQL_MODE 严格化、默认 ROW binlog、InnoDB 全文索引、独立 undo 表空间、JSON 原生支持
- 8.0 相比 5.7:默认
utf8mb4、默认caching_sha2_password、CTE 和窗口函数、Query Cache 移除、GTID 默认开启 - 5.6→5.7 迁移核心测试点:SQL_MODE 严格性、
TIMESTAMP默认值、GROUP BY行为 - 5.7→8.0 迁移核心测试点:密码插件兼容性、排序规则变化、客户端驱动版本
下一章引子:版本差异决定了升级路径,而日常运维中更直接的问题是——主从复制延迟了怎么办?半同步复制是降低延迟风险的重要手段。