mysql 5.7迁移到8.0必须前置使用--compatible=mysql57,它自动将utf8mb4_0900_ai_ci替换为utf8mb4_unicode_ci,并屏蔽8.0特有语法,配合--default-character-set=utf8mb4使用,否则后续手动修复风险极高。

导出时就用 --compatible=mysql57,别等报错再补救
直接在 mysqldump 命令里加 --compatible=mysql57 是最省事、最可靠的起点。它不是“锦上添花”,而是必须前置的兼容性开关——不加这个,后续所有手动替换都是在修补漏洞,风险陡增。
-
--compatible=mysql57会自动把utf8mb4_0900_ai_ci替换为utf8mb4_unicode_ci(不是utf8mb4_general_ci,后者在 8.0 已被标记 deprecated) - 同时屏蔽掉 8.0 特有语法:比如
STORED GENERATED COLUMN、ROW_FORMAT=COMPACT、JSON DEFAULT '[]'等 - 必须搭配
--default-character-set=utf8mb4使用,且该参数要放在命令靠前位置,否则可能被忽略 - 别信
--skip-extended-insert或--no-defaults能解决核心兼容问题——它们只影响输出格式或配置加载,对排序规则、默认值、引擎类型无效
导入前检查 SQL 文件里还有没有残留的 8.0 排序规则
即使用了 --compatible=mysql57,某些场景下(比如导出时连的是 8.0 实例但未显式指定 --collation-server),备份文件里仍可能出现 utf8mb4_0900_as_cs、utf8mb4_0900_bin 这类变体。这些不会被 --compatible 自动处理。
- 用
grep -o 'utf8mb4_0900_[^ )]*' backup.sql扫一遍,确认是否还有漏网之鱼 - 批量替换时只动
COLLATE=后面的部分,例如:sed -i "s/utf8mb4_0900_as_cs/utf8mb4_unicode_ci/g" backup.sql - 绝对不要全局替换
utf8mb4→utf8,这会丢失 emoji 和生僻字,属于数据损坏操作 - 检查每张表的
CREATE TABLE语句末尾,确保是DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci,而不是空着或写成utf8mb4_general_ci
别跳过 GTID 和权限语句的清理
ERROR 1236 (HY000): Could not execute Write_rows_v1 event on table mysql.gtid_executed 或 Unknown authentication plugin 'caching_sha2_password' 这类报错,往往不是字符集问题,而是 GTID 元数据和用户认证机制的硬冲突。
- 导出前先关 GTID:
SET GLOBAL gtid_mode = OFF_PERMISSIVE;→RESET MASTER;→SET GLOBAL gtid_mode = OFF;,再执行 dump - 删掉备份文件里所有含
IDENTIFIED WITH mysql_native_password或caching_sha2_password的CREATE USER/ALTER USER行,改用SET PASSWORD FOR 'user'@'host' = PASSWORD('xxx'); - 如果导出时用了
--all-databases,记得单独处理mysql库——5.7 不允许直接导入 8.0 的mysql.user表结构,建议先导出业务库,再用mysqldump --no-create-info --skip-triggers mysql user单独导用户数据
重装 5.7 前必须清干净残留配置和数据目录
宝塔面板点“卸载” MySQL 8.0,只是删了二进制文件,/www/server/mysql 目录、/etc/my.cnf、/etc/systemd/system/mysqld.service 都还在。这些残留会直接导致 5.7 初始化失败或启动后无法连接。
- 手动删掉
/www/server/mysql/data整个目录(5.7 初始化不允许 data 目录非空) - 检查
/etc/my.cnf,删掉 8.0 特有项如default_authentication_plugin=caching_sha2_password、early-plugin-load=keyring_file - 运行
systemctl daemon-reload刷新服务定义,避免 systemd 还在找旧路径下的mysqld - 安装 5.7 后,首次启动前执行:
mysql_install_db --user=mysql --basedir=/www/server/mysql --datadir=/www/server/mysql/data(具体路径以宝塔实际安装路径为准)











