乱码大概率发生在导出环节,不是导入命令写错,而是mysqldump未带--default-character-set=utf8mb4参数,导致sql文件中emoji等4字节字符已被截断损坏;导入时无论加何参数均无法修复。

直接说结论:乱码大概率发生在导出环节,不是导入命令写错,而是 mysqldump 没带 --default-character-set=utf8mb4,SQL 文件里 Emoji 已被损坏;导入时再怎么加参数也救不回来。
导出时漏掉 --default-character-set=utf8mb4 是最大雷区
MySQL 5.7+ 默认用 latin1 读取表结构和数据,哪怕库、表、字段全是 utf8mb4,只要没显式指定导出编码,mysqldump 就会把 4 字节的 Emoji 当作非法字符截断或错解——此时 SQL 文件已损毁。
- 检查方法:
head -n 5 backup.sql看前几行有没有SET NAMES utf8mb4;;没有就基本可判定导出失败 -
file -i backup.sql显示charset=us-ascii或charset=iso-8859-1,说明文件里已无合法 UTF-8 字节 - 错误导出命令:
mysqldump -u root -p db_name > backup.sql(缺参数) - 正确导出命令:
mysqldump --default-character-set=utf8mb4 -u root -p db_name > backup.sql(--default-character-set必须放在最前面)
导入命令必须匹配导出时的编码逻辑
导入不是“把文件扔进去”,而是 MySQL 客户端要先解码 SQL 文本。如果导出文件是按 utf8mb4 编码写的,客户端就必须用相同编码读它,否则 4 字节 Emoji 会被拆成两个无效 latin1 字符。
- 正确写法:
mysql --default-character-set=utf8mb4 -u root -p db_name - 错误写法:
mysql -u root -p db_name (客户端按默认 <code>latin1解析) - Windows 下别用 cmd,它的代码页是 GBK,可能在读文件时二次污染;改用 Git Bash 或 PowerShell
- 若报
Unknown character set: 'utf8mb4',说明本地mysql客户端太老(utf8(不推荐,Emoji 仍失败)
导出文件已损坏但无法重备?手动补 SET NAMES 不够用
有些老旧脚本导出的 SQL 只含建表语句,无连接初始化,此时单靠 --default-character-set 导入也不行——因为建表后执行 INSERT 时,连接层仍是默认字符集。
- 手动在
backup.sql开头插入一行:SET NAMES utf8mb4; - 但前提是:该文件里的 Emoji 字节本身还是完好的(即导出时其实用了
utf8mb4,只是忘了写SET NAMES) - 如果
hexdump -C backup.sql | head里看不到f0 9f 98 80这类 4 字节序列,说明字节已丢,补SET NAMES毫无意义 - 验证数据是否完好:用
mysql --default-character-set=utf8mb4连上原库,直接SELECT HEX(col) FROM table LIMIT 1;,看到f09f9880才算真存对了
真正麻烦的不是命令记不住,而是你得先判断:乱码是发生在存储层、传输层,还是展示层。很多情况下,SELECT HEX() 显示的是合法 UTF-8 字节,但 Navicat 里显示问号——那问题根本不在备份恢复,而在客户端连接三件套没对齐。











