MySQL 8.0升级应优先采用mysqldump逻辑迁移而非in-place升级,因后者存在启动失败、权限崩溃、字符集乱码等高风险;须提前检查兼容性、修正DEFINER、统一utf8mb4、调整认证插件与sql_mode,并严格保持lower_case_table_names一致。

mysqldump 逻辑迁移比 in-place 升级更可控
生产环境不建议直接替换二进制升级。5.7 → 8.0 的数据字典结构、权限模型、字符集默认值都变了,in-place 升级看似快,但启动失败、连接中断、查询崩溃的风险极高。初学者最容易踩的坑是:以为改完 my.cnf、换掉 basedir 就能跑起来。实际上,MySQL 8.0 启动时会自动执行系统表升级,一旦遇到旧版本遗留的无效定义(比如含 NO_AUTO_CREATE_USER 的视图或存储过程),就会卡在初始化阶段,日志里只显示 Failed to initialize DD 或 Aborting,根本看不到具体哪张表坏了。
- 先用
mysqlsh -u root -p -S /tmp/mysql.sock -e "util.checkForServerUpgrade()"扫一遍 5.7 实例,把 ERROR 级别问题全解决掉 - 备份必须用
mysqldump --skip-definer --set-gtid-purged=OFF --routines --triggers --events,漏掉--skip-definer导致导入时报ERROR 1227 (42501)是新手最高频错误 - 导出后立刻
grep -n "DEFINER|NO_AUTO_CREATE_USER" backup.sql,有就删,别信“应该没问题”
caching_sha2_password 认证插件导致连不上
8.0 新建用户默认用 caching_sha2_password,但 PHP 7.3 以下、Python 2.7 的 MySQLdb、甚至部分 JDBC 驱动根本不认这个插件,报错是 Authentication plugin 'caching_sha2_password' cannot be loaded,不是密码错,是协议不兼容。
- 登录 8.0 后第一件事:执行
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_pwd'; - 再查
SELECT user, host, plugin FROM mysql.user;,对所有plugin = 'caching_sha2_password'的用户逐个改回mysql_native_password - 配置文件加一行
default_authentication_plugin=mysql_native_password,否则下次CREATE USER又踩坑
utf8mb4 字符集和 collation 不一致引发乱码
5.7 默认 latin1 + latin1_swedish_ci,8.0 默认 utf8mb4 + utf8mb4_0900_ai_ci。如果表/列没显式指定字符集,升级后 SHOW CREATE TABLE 会显示新默认值,但老数据仍按旧规则存,排序、比较、索引可能出错,中文变问号或 ORDER BY 结果错乱。
- 升级前确认所有库、表、列都显式设为
utf8mb4:ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; - 表级执行:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 别依赖配置文件里的
character_set_server=utf8mb4,它只影响新建对象,不影响已有数据存储格式
sql_mode 收紧让旧 SQL 报错
8.0 移除了 NO_AUTO_CREATE_USER,且默认启用 STRICT_TRANS_TABLES。以前能插入的空字符串、超长字段、隐式类型转换,现在直接 ERROR 1364 或 ERROR 1265。
- 检查应用 SQL,避免
INSERT INTO t VALUES ()这类无显式字段列表的写法 - 不要全局关 strict mode,而是针对性调整:比如某张日志表允许
INSERT IGNORE,就单独设sql_mode为宽松子集 - 导入前在 8.0 临时执行
SET sql_mode='';测试,但上线前必须还原并修复业务 SQL
最常被忽略的是:升级后 lower_case_table_names 值不能改。5.7 初始化时设了 1,8.0 必须保持一致,否则启动失败报 Cannot change lower_case_table_names。这个值在 my.cnf 里写死,且必须在第一次启动前定好——不是升级时才配,是初始化 5.7 时就得规划好。


















