不是必须但跳过mysql_upgrade大概率导致查询报错或权限失效;它同步系统表结构变更,如user表字段调整、proc表编码更新,漏执行会导致密码错误、SHOW GRANTS为空、performance_schema为空等隐性故障。

能平滑,但“平滑”不等于“无感”——跳过 mysqlcheck --check-upgrade 或硬替二进制包,大概率启动失败或半夜告警。
执行 mysqlcheck --check-upgrade 前必须清理的三类问题
这个命令不是只报错,它会明确告诉你哪些表/用户/结构“requires upgrade”,但前提是环境干净。常见卡点:
- 存在孤立的
.frm文件(比如手动删过.ibd但没用DROP TABLE):mysqlcheck会直接报 ERROR 并中止,必须先修复或删掉对应表 - 分区表用了 MyISAM 引擎:运行
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE = 'MyISAM' AND CREATE_OPTIONS LIKE '%partitioned%',结果非空就得先ALTER TABLE ... ENGINE=InnoDB - 系统库
mysql下有自定义表名和 8.0 新系统表重名(比如叫roles、role_edges):这类表必须重命名或删掉,否则mysqld启动时初始化系统表会失败
替换二进制包时软链接与配置文件的坑
直接覆盖 /usr/local/mysql 目录是高危操作。正确做法是保留旧路径,用软链接切换:
- 解压新包到独立目录(如
/usr/local/mysql-8.0.42),别动旧的/usr/local/mysql - 确认新包里没有硬编码引用旧路径:检查
bin/mysqld的 rpath(readelf -d bin/mysqld | grep RUNPATH),若含/usr/local/mysql/lib这类路径,得用patchelf改或换官方预编译包 -
my.cnf必须删掉已废弃参数:query_cache_type、explicit_defaults_for_timestamp、log_warnings—— 任何残留都会导致mysqld启动失败,错误日志里只有 “unknown variable” 这种模糊提示
启动 8.0 后第一件事不是连应用,而是验证升级状态
服务进程起来 ≠ 数据库就绪。以下命令缺一不可:
-
SELECT VERSION(), @@sql_mode;—— 确认版本是8.0.x且ONLY_FULL_GROUP_BY在列表中 -
SELECT * FROM performance_schema.replication_applier_status_by_coordinator;—— 如果开了复制,这里必须显示APPLYING状态,否则 GTID 或 relay log 没自动续上 -
SHOW VARIABLES LIKE 'default_authentication_plugin';—— 如果返回caching_sha2_password,但你的 Python 应用还在用PyMySQL ,连接会直接断,得立刻建兼容用户:CREATE USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx';
最常被跳过的动作是验证系统表升级是否完成:哪怕 mysqld 启动成功,如果 mysql.user 表还残留 Password 字段(应为 authentication_string),说明 mysql_upgrade 没跑完或失败了——这种状态下的权限变更、角色创建全不可靠。











