MySQL 8.0.16+ 已废弃 mysql_upgrade,升级逻辑集成至 mysqld 启动流程;正确做法是停服务、替换二进制后执行 mysqld --datadir=路径 --upgrade=FORCE 强制触发系统表升级,漏掉该参数易导致权限异常、performance_schema 不可用等隐性故障。

mysql_upgrade 已废弃,别再手动调用
升级到 MySQL 8.0.16+ 后执行 mysql_upgrade 会报错 “Command not found” 或 “This command is deprecated”——这不是你装错了,是它真被删了。从 8.0.16 开始,升级逻辑已集成进 mysqld 启动流程,手动跑毫无意义。
正确做法是:停服务后替换二进制,再用 mysqld --datadir=/var/lib/mysql --upgrade=FORCE 启动(路径按实际改)。不加 --upgrade=FORCE 参数,mysqld 可能拒绝启动或跳过系统表升级,导致后续 SHOW GRANTS 返回空、performance_schema 不可用等隐性故障。
- 只对 8.0.16+ 有效;8.0.15 及更早仍需
mysql_upgrade -
--upgrade=FORCE不是可选参数,漏掉大概率卡在初始化阶段 - 若启动日志里没出现类似
Server upgrade from '80032' to '80039'的提示,说明升级没触发
caching_sha2_password 连不上?不是密码错了
升级后应用连不上,错误是 Plugin caching_sha2_password could not be loaded 或 Authentication plugin 'caching_sha2_password' cannot be loaded——这和密码无关,是客户端驱动不支持新默认认证插件。
PHP 7.4 以下、PyMySQL caching_sha2_password。临时解法是建兼容用户,长期必须升级驱动或调整连接参数。
- 临时兼容:运行
ALTER USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd'; FLUSH PRIVILEGES; - Java JDBC 连接串加
?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false - PHP mysqli 要配
mysqli_options($link, MYSQLI_OPT_SSL_MODE, MYSQLI_SSL_DISABLED) - 别改全局
default_authentication_plugin:它只影响新建用户,已有用户哈希方式不变,改了反而让部分用户登不上
my.cnf 里留着 query_cache_type 就起不来
直接覆盖二进制包后启动失败,错误日志只有模糊的 unknown variable 'query_cache_type'——这是 8.0 已移除的参数,但配置文件里还留着,mysqld 解析时直接退出。
8.0 移除了至少 12 个旧参数,常见踩坑项包括:query_cache_type、explicit_defaults_for_timestamp、log_warnings、innodb_file_format、innodb_large_prefix。哪怕只残留一个,服务就起不来。
- 升级前必须人工扫一遍
my.cnf和所有 include 的子配置 - 用
mysqld --defaults-file=/etc/my.cnf --verbose --help | grep -E '^(query|log|explicit)'快速筛出疑似废弃项 - 不确定是否废弃?查官方文档 “Removed Options and Variables” 章节,别靠记忆猜
mysqlcheck --check-upgrade 不只是报错,它决定能不能启
mysqlcheck -u root -p --all-databases --check-upgrade 不是“建议运行”,它是升级前唯一能提前暴露底层不兼容项的工具。它比人工查 INFORMATION_SCHEMA 准得多,能发现 JSON 字段定义冲突、隐藏列缺失、分区表引擎不兼容等 mysqld 启动后才报的深层问题。
但它非常娇气:遇到孤立 .frm 文件、MyISAM 分区表、或系统库下与 8.0 新表同名的自定义表(比如叫 roles),会直接报 ERROR 并中止,不会继续检查其他项。
- 先清空孤立
.frm:找到对应数据库目录,删掉没.ibd匹配的.frm - 查 MyISAM 分区表:
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE = 'MyISAM' AND CREATE_OPTIONS LIKE '%partitioned%';,结果非空就得ALTER TABLE ... ENGINE=InnoDB - 查重名表:
SELECT TABLE_NAME FROM mysql.tables WHERE TABLE_NAME IN ('roles', 'role_edges', 'default_roles');,存在就重命名
Server upgrade from... 和 mysqlcheck 的返回码。


















