必须先停应用再运行mysql_upgrade,因其直接修改mysql.user等系统表,运行时若有业务连接会导致元数据损坏或锁死;须用升级后版本二进制执行,避免因版本不匹配跳过关键校验;失败后应查日志而非重试,且需验证user表字段是否更新为8.0结构。

必须先停应用再运行 mysql_upgrade,否则权限表可能损坏或锁死——这不是警告,是已验证的故障复现路径。
为什么 mysql_upgrade 必须在停应用后执行
它不是后台工具,而是直接 ALTER mysql.user、mysql.db 等系统表。业务连接未断开时,轻则中断执行,重则让 mysql.user 元数据不一致,后续所有 GRANT 都失效。
- 执行前查活跃连接:
SHOW PROCESSLIST;,重点关注非root或system user的连接 - 临时设只读(仅限 super 用户可用):
SET GLOBAL read_only = ON; - 最稳妥做法:停掉所有应用服务,或切走流量,别信“就几秒”的侥幸
必须用升级后版本的二进制执行 mysql_upgrade
常见错误是 PATH 里残留旧版 mysql_upgrade,结果提示 Unknown table 'performance_schema.session_variables' 或跳过关键步骤——5.7 的工具根本不知道 8.0 的 data_dictionary 表和角色权限模型。
- 明确指定路径调用,例如:
/usr/local/mysql-8.0/bin/mysql_upgrade - 用
which mysql_upgrade和mysql_upgrade --version双重核对 - Docker 场景下,确保容器内执行的是镜像自带二进制,不是宿主机挂载进来的旧版
失败后别重试,先看 upgrade.log 末尾 ERROR
很多人看到报错立刻重跑 mysql_upgrade,结果把半截失败的状态反复叠加,最后连 mysql 库都打不开。真实问题往往藏在日志末尾:
mysql_upgrade --verbose --force > upgrade.log 2>&1- 重点扫最后一段
ERROR行,比如ERROR 1878 (HY000)指向统计信息创建失败,常因存储引擎不兼容或权限不足 - 若卡在
mysql.innodb_index_stats这类表,说明底层表结构或权限未就绪
升级后必须验证 user 表字段是否更新
MySQL 8.0 彻底移除了 Password 字段,改用 authentication_string,且默认 plugin 是 caching_sha2_password。如果 mysql_upgrade 没跑完或中途失败,mysql.user 表还是 5.7 结构,就会导致授权语句执行成功但登录时提示 Access denied。
- 登录后执行:
SELECT User, Host, plugin, authentication_string FROM mysql.user LIMIT 1; - 看字段是否存在、值是否为空;若
authentication_string为空或plugin是空字符串,说明升级未完成或失败 - 别手动补字段——系统表结构必须由官方工具校准
最容易被忽略的是:即使 mysql_upgrade 成功退出,也要确认 root@127.0.0.1 是否有完整 DML + DDL 权限,而不仅是 root@localhost。


















