根本原因是备份时未指定--default-character-set导致字符集未对齐;mysql默认用latin1解析sql文件,即使库为utf8mb4,也会因编码不匹配造成中文乱码。

mysqldump 备份时没指定 --default-character-set,还原就容易乱码
根本原因不是还原命令错了,而是备份那一刻字符集就没对齐。MySQL 默认用 latin1 读取 SQL 文件,哪怕你库是 utf8mb4,只要 dump 没声明编码,它就按字节硬塞,中文变问号或 Mojibake 是必然的。
- 检查原库字符集:
SHOW CREATE DATABASE `db_name`;看DEFAULT CHARACTER SET - 检查备份文件开头是否有
SET NAMES utf8mb4;或类似语句;没有?基本可以断定 dump 时没带编码参数 - 别急着改还原命令——先确认备份文件本身是不是 UTF-8 编码(用
file -i backup.sql或 VS Code 底部编码提示看)
mysql 命令行还原时必须显式指定 --default-character-set
还原不是“读进去就行”,而是 MySQL 客户端要先解码 SQL 文本。不指定,它就用编译默认值(通常是 latin1),汉字直接被截断或错解。
- 正确写法:
mysql --default-character-set=utf8mb4 -u root -p db_name - 错误写法:
mysql -u root -p db_name (缺编码参数) - 如果报
Unknown character set: 'utf8mb4',说明客户端版本太老,升级mysql客户端或换用utf8(不推荐,存 emoji 会失败) - Windows 下用 PowerShell 或 Git Bash 执行,别用 cmd——它的默认代码页常是
GBK,会二次污染
备份文件头缺失 SET NAMES 时,手动补一句再还原
有些老脚本 dump 出来只有建表语句,没初始化连接编码。这时光靠 --default-character-set 不够,因为 CREATE TABLE 里的 CHARACTER SET 子句可能被忽略,字段级编码还是错的。
- 用文本编辑器打开
backup.sql,在第一行插入:SET NAMES utf8mb4; - 确保这行在任何
CREATE DATABASE或USE之前 - 如果备份里已有
SET NAMES latin1,必须替换成utf8mb4,否则它会覆盖命令行参数 - 别信“加了
charset=utf8mb4在 URL 里就行”——mysql 命令行不认这个,那是 JDBC 的写法
还原后查数据还是乱码?重点检查三处实际存储层
命令跑成功不代表完事。MySQL 有四层编码:客户端、连接、数据库、表/列。其中任意一层不匹配,SELECT 出来就是乱的。
- 查当前连接编码:
SELECT @@character_set_client, @@character_set_connection, @@character_set_results;三个都应为utf8mb4 - 查表结构:
SHOW CREATE TABLE t1;看ENGINE=InnoDB DEFAULT CHARSET=utf8mb4和字段定义里有没有CHARACTER SET utf8mb4 - 查数据是否真存坏了:用
SELECT HEX(col) FROM t1 LIMIT 1;,如果中文显示成C3A9C2B5C2A0这种,说明存的是 UTF-8 字节被当 Latin1 解了——已不可逆,只能从原始数据源重导











