必须执行mysql_upgrade -s升级系统表,否则会导致系统库缺失、字段不全及认证失效;它仅升级mysql等四个系统库,执行后须重启mysqld才能生效。

必须填平的坑有三个:系统表没升级、sql_mode变严格、账户认证失效。不处理就不是“升级完成”,而是“带病上线”。
mysql_upgrade -s 不加就等于没升级
升级后 SELECT VERSION() 显示 5.7,但 mysql.user 还是 42 列,缺 authentication_string、account_locked 字段;sys 库根本不存在;用 root 登录都报 Access denied —— 全是因为漏了 mysql_upgrade -s。
-
-s(即--upgrade-system-tables)只升级mysql、information_schema、performance_schema和sys四个系统库,跳过业务表,安全且快 - 不加
-s会扫描所有库所有表,对 MyISAM 表建临时表,卡在Checking table 'mysql.columns_priv'几小时不动 - 执行完必须重启:
systemctl restart mysqld,否则新字段和视图不加载 - 别加
--force,除非日志明确提示system tables are corrupted
sql_mode 默认变严格,GROUP BY 和 INSERT 直接报错
5.6 默认 sql_mode = NO_ENGINE_SUBSTITUTION,只警告;5.7 默认启用 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,非聚合列进 GROUP BY、超长字符串插入、无效日期都会直接报错。
- 典型错误:
Expression #2 of SELECT list is not in GROUP BY clause,比如SELECT deptno, ename, MAX(sal) FROM emp GROUP BY deptno在 5.6 能跑,在 5.7 报错 - 开发侧必须检查所有 SQL,尤其分组求最值类写法(如子查询 + GROUP BY),5.7 会重写执行计划,结果可能错乱
- 临时兼容方案:启动时加
--sql-mode="NO_ENGINE_SUBSTITUTION",但只是过渡,不能长期依赖 - 线上建议保留严格模式,把问题暴露在测试阶段,而不是上线后炸
旧账号登录失败,不是密码错,是认证插件变了
5.7 默认改用 caching_sha2_password 插件,而 5.6 账号用的是 mysql_native_password。现象是:账号密码完全正确,却报 Access denied for user 'xxx'@'%' (using password: YES)。
- 不是权限问题,是客户端协议不匹配 —— 5.6 客户端无法解析 5.7 新插件的握手流程
- 快速修复:用 root 登录后执行
ALTER USER 'xxx'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx'; - 注意:如果用
mysqldump或旧版 JDBC(--default-auth=mysql_native_password - 长远看要升级客户端驱动,但上线当天优先切回老插件保业务
真正容易被忽略的是:这些坑不会全在启动时报错,而是分散在连接、查询、备份、监控脚本里慢慢冒出来。比如 show status 缺少 Slave_* 指标(因为没开 show_compatibility_56=ON),或者慢日志时间全差 8 小时(因为 log_timestamps=UTC 默认生效)。升级不是“跑通 SELECT VERSION()”就算完,得让所有原有链路——包括定时任务、DBA 脚本、中间件心跳检测——全部验证通过才算落地。


















