mysql 5.7 升级到 8.0 需重点检查 sql_mode 变更、json/gis 兼容性、排序规则切换及 mysql.user 表结构变化,否则将引发数据插入失败、查询异常、权限脚本失效等问题。

升级前必须检查 sql_mode 变更影响
MySQL 5.7 升级到 8.0 时,默认 sql_mode 新增了 STRICT_TRANS_TABLES 和 ONLY_FULL_GROUP_BY,这会让原本能插入的“脏数据”直接报错,比如 INSERT INTO t(a,b) VALUES (1, NULL) 在非严格模式下可能成功,但在 8.0 严格模式下会因字段定义为 NOT NULL 而失败。
实操建议:
- 升级前导出当前
sql_mode:执行SELECT @@sql_mode;,记下结果 - 在测试环境模拟新版本启动,用旧
sql_mode启动(如加配置sql_mode = "NO_ENGINE_SUBSTITUTION"),验证业务 SQL 是否正常 - 避免长期禁用严格模式——应逐表修复隐式默认值、
GROUP BY不完备等逻辑问题,而不是靠降级sql_mode迁就老代码
mysql_upgrade 不再自动修改表结构,需手动评估 JSON 和 GIS 字段兼容性
MySQL 8.0+ 废弃了 mysql_upgrade 的 DDL 自动修正能力,它只更新系统表元数据,不再重写用户表。但部分字段类型在语义或存储格式上有变化,尤其 JSON 和空间类型(如 POINT)。
常见问题:
- MySQL 5.7 的
JSON字段在 8.0 下仍可读,但若含非法 Unicode(如未转义 surrogate pair),查询可能报Invalid JSON text - 使用
MyISAM存储的 GIS 表在 8.0 中无法启动,必须先转为InnoDB并重建空间索引 -
TINYINT(1)作为布尔别名的用法不受影响,但 ORM 若依赖其显示宽度(如getColumnMeta返回length=1),可能误判为 boolean 类型
字符集与排序规则升级后行为不一致:重点盯 utf8mb4_0900_as_cs
MySQL 8.0 默认排序规则从 utf8mb4_general_ci 改为 utf8mb4_0900_as_cs(大小写敏感、口音敏感),这会影响 WHERE、ORDER BY、唯一索引去重等逻辑。
实操建议:
- 检查建表语句是否显式指定了
COLLATE,未指定则继承库级默认值;升级后新建库/表会用新规则,但旧表保持原规则,容易造成跨表 JOIN 结果异常 - 执行
SHOW CREATE TABLE t;确认每张表和关键字段的COLLATE,对需要统一行为的字段,用ALTER TABLE t MODIFY c VARCHAR(255) COLLATE utf8mb4_0900_as_cs;显式调整 - 应用层若做字符串比较(如缓存 key 拼接),需确认是否依赖旧排序规则下的相等判断,否则可能命中失败
系统表结构变更导致权限脚本失效:mysql.user 字段精简是硬伤
MySQL 8.0 彻底移除了 mysql.user 表中的 Password、ssl_cipher、x509_issuer、x509_subject 等字段,改由 authentication_string 统一存储凭证,并将 SSL/X.509 配置移到动态权限控制中。
这意味着:
- 任何直接读取
mysql.user表生成账号报告、同步权限或备份恢复的脚本,在 8.0 下会报Unknown column 'Password' in 'field list' -
GRANT语法本身没变,但SHOW GRANTS FOR 'u'@'h'输出格式变了,旧解析逻辑可能漏掉角色或动态权限 - 升级后首次登录若用
mysql -u root无密码失败,不是 bug,而是默认认证插件变为caching_sha2_password,需用--default-auth=mysql_native_password或重置插件
真正麻烦的是那些把 SELECT * FROM mysql.user 当成事实源的运维工具——它们不会报错,但输出的字段值已失效或为空,静默破坏权限一致性。










