mysql升级失败主因是新旧版本在字符集、权限表、配置项或启动流程不兼容;须查错误日志、清理废弃参数、修正权限与selinux上下文、用--upgrade=force修复系统表、更新认证插件及jdbc参数,并提前验证路径与兼容性。

MySQL升级失败,八成不是“装错了”,而是新旧版本在字符集、权限表、配置项或启动流程上悄悄对不上号——直接重装或反复启停只会让问题更难定位。
升级后服务起不来?先盯死错误日志里的 MY- 和 InnoDB:
服务启动失败时,/var/log/mysqld.log(Linux)或 data/主机名.err(Windows)是唯一可信信源。别跳过它,也别凭感觉删文件。
- 看到
MY-010020 Data Dictionary initialization failed?这是 5.6→8.0 直升的典型信号,必须经由 5.7 中转,不能硬上 - 出现
Unknown variable 'query_cache_type'或sql_mode contains NO_AUTO_CREATE_USER?说明my.cnf里还留着 5.6 甚至更老的废弃参数,得一条条对照官方文档清理 - 报
Can't open file './mysql/user.frm'?不是数据丢了,而是属主/权限不对:执行chown -R mysql:mysql /var/lib/mysql,再加restorecon -R /var/lib/mysql(SELinux 启用时必做)
mysql_upgrade 报错或干脆找不到?新版已改由 mysqld --upgrade 控制
从 MySQL 8.0.16 起,mysql_upgrade 已被弃用。它不再是个独立工具,而是由服务器启动时自动触发——但这个过程可能静默失败,或卡在中间状态。
- 升级后登录报
Storage engine 'MyISAM' does not support system tables?说明系统表(如mysql.user)仍是 MyISAM 引擎,需强制触发升级:mysqld --user=mysql --datadir=/var/lib/mysql --upgrade=FORCE - 想跳过升级先连进去排查?用
--upgrade=NONE启动,但仅限临时诊断,不可长期运行 - 若升级反复失败,可用
--upgrade=MINIMAL启动,绕过部分校验,手动导出关键数据后再处理
能连上但权限失效、应用报错?重点查三件事:认证插件、字段注释、JDBC 参数
连接成功 ≠ 权限可用。很多“登得进但干不了事”的问题,根源在元数据没对齐或客户端仍按旧规则说话。
- 执行
SELECT User, Host, plugin FROM mysql.user WHERE User = 'root';,若返回caching_sha2_password,而你的 Navicat 或 Java 应用还是老驱动,就必然连不上或权限不生效;临时解法:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'xxx'; FLUSH PRIVILEGES; - 建表语句里带中文注释却升级中断?检查是否含
utf8mb3或 Windows-1252 残留字节(如'\xB1\xB8\xD6'),报错通常是MY-013140;用原版本客户端执行SHOW CREATE TABLE tbl\G定位,再用ALTER TABLE ... COMMENT '纯UTF8MB4文字'替换 - JDBC URL 还写
tx_isolation=REPEATABLE-READ或serverTimezone=中国标准时间?前者要改成transactionIsolation=TRANSACTION_REPEATABLE_READ,后者必须用 IANA 名称,如serverTimezone=Asia/Shanghai
跨大版本升级前最该做的三件事
不是备份,也不是改配置——而是验证路径、扫描兼容、锁定行为。这些动作花不了半小时,但能避开 80% 的线上故障。
- 确认升级路径合规:5.7 → 8.0 是允许的,但 5.6 → 8.0 不被支持;查官方文档 “Upgrading MySQL” 章节,看目标版本是否明确要求中间版本
- 用
mysqlsh --util.checkForServerUpgrade全量扫描,它会揪出 MyISAM 表、废弃 SQL mode、JSON 字段索引缺失等隐藏风险,比人工翻代码靠谱得多 - 提前在旧版本中启用
sql_mode=STRICT_TRANS_TABLES,ONLY_FULL_GROUP_BY并跑通核心业务 SQL,相当于把 8.0 的严格模式“预演”一遍,避免升级后 GROUP BY 或隐式类型转换突然报错
真正麻烦的从来不是升级动作本身,而是那些没报错却悄悄错位的细节:一个注释里的乱码字节、一行配置里被忽略的废弃参数、JDBC URL 中一个时区名的大小写。它们不拦你启动服务,却会在某个凌晨三点让订单写不进库。










