mysql_upgrade在5.7及更早版本升级后必须手动运行,8.0.16+由服务自动完成;主从需分别处理,需高权限本地连接、匹配版本工具,并确认mysqld运行及socket路径正确。

mysql_upgrade 命令到底要不要手动跑?
mysql_upgrade 不是“升级 MySQL 服务”的命令,它只负责检查并修复系统库(主要是 mysql 库)的表结构,比如 user、db、procs_priv 这些表。MySQL 官方从 8.0.16 开始默认禁用该命令,升级后由服务自动完成;5.7 及更早版本仍需手动执行。
- 如果你刚从 5.7 升级到 8.0.15 或更早版本,
mysql_upgrade必须运行一次,否则权限系统可能异常(例如Access denied错误频发,但账号密码明明正确) - 8.0.16+ 升级后首次启动 mysqld 时会自动执行等效操作,此时再手动跑
mysql_upgrade会报错:Command not supported in this version of MySQL - 别在主从架构中只在主库跑完就认为万事大吉——从库必须单独升级(或重建),因为系统表变更不走 binlog 同步
运行前必须确认的三件事
mysql_upgrade 需要高权限账号连接本地实例,且依赖当前 MySQL 服务已正常运行。常见失败都卡在这几步:
- 确保
mysqld进程正在运行,且监听的是默认 socket(/var/lib/mysql/mysql.sock)或已用--socket显式指定 - 用
--user指定的账号必须有SELECT和INSERT权限(至少对mysql库),推荐直接用root并配好~/.my.cnf免密登录 - 不要加
--force盲目重试:如果提示Table 'mysql.role_edges' doesn't exist,说明你用的是 5.7 的客户端去连 8.0 实例——换用对应版本的mysql_upgrade二进制(通常在/usr/bin/下按版本分装)
常见错误信息和对应动作
遇到报错别急着搜解决方案,先看错误里暴露的是哪一层问题:
-
Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock':不是权限问题,是 socket 路径不对,加--socket=/path/to/correct.sock -
Unknown table 'column_statistics' in information_schema:这是 8.0 新增表,在 5.7 环境下跑 8.0 的mysql_upgrade会出这个错,换回 5.7 版本工具 -
mysql.user has no <code>password_last_changedcolumn:说明系统表结构比当前 MySQL 版本旧,必须运行mysql_upgrade,不能跳过 - 执行完提示
OK但后续仍报权限错:检查是否漏了--skip-sys-schema(某些定制版 MariaDB 场景需加),或确认没在容器里挂载了旧版mysql数据目录
替代方案:什么情况下可以不用 mysql_upgrade?
如果你没动过系统库,也没升级 MySQL 二进制,只是改业务库结构,mysql_upgrade 完全无关。
- 仅升级客户端(如只更新
mysql命令行工具)不需要跑 - 使用 Docker 官方镜像升级(如
mysql:5.7→mysql:8.0),只要 volume 数据目录是干净迁移的,启动日志里出现Upgrading MySQL system tables.就代表自动完成了 - 在 RDS(如阿里云 RDS、AWS RDS)上,系统表维护由平台托管,用户无权执行
mysql_upgrade,也不需要管
真正容易被忽略的是:升级后第一次连接 MySQL 时,如果用的是老版本客户端(比如 5.7 的 mysql),可能会因协议或字段缺失直接断连——这时候不是 mysql_upgrade 没跑,而是客户端不兼容。










