MySQL乱码本质是服务端、连接层、表结构、DataX配置四层字符集不一致导致的“翻译链断裂”,必须统一为utf8mb4;需检查character_set_client/connection/results是否全为utf8mb4,修改my.cnf并重启,DataX jdbcUrl须显式添加?useUnicode=true&characterEncoding=utf8mb4,建表及字段须显式声明utf8mb4。

乱码不是DataX本身的问题,而是MySQL服务端、连接层、表结构、DataX配置四者字符集不一致导致的“翻译链断裂”。只要其中一环是latin1或没显式声明utf8mb4,中文就会变成???。
检查MySQL服务端与连接层字符集是否统一为utf8mb4
乱码常发生在插入/读取阶段,根源往往在character_set_client、character_set_connection、character_set_results这三项不一致。不能只看character_set_server。
- 执行
SHOW VARIABLES LIKE 'character_set%';,确认这三项值均为utf8mb4;若其中任一项是latin1或utf8(注意:不是utf8mb4),说明连接层已断链 -
utf8是MySQL的伪UTF-8,最多支持3字节字符,无法存emoji和部分生僻汉字;必须用utf8mb4 - 临时修复可用
SET NAMES utf8mb4;,但仅对当前会话有效;生产环境必须改配置文件 - 在
my.cnf的[mysqld]段加:character-set-server = utf8mb4、collation-server = utf8mb4_unicode_ci;在[client]段加:default-character-set = utf8mb4;改完务必重启MySQL服务
DataX的MySQL Writer必须显式带字符集参数
即使MySQL服务端已设为utf8mb4,DataX默认连接不带字符集声明,仍会走驱动默认(通常是latin1),导致写入即乱码。
- 在Writer的
jdbcUrl中必须拼上参数:?useUnicode=true&characterEncoding=utf8mb4 - 错误写法:
"jdbcUrl": "jdbc:mysql://192.168.1.100:3306/mydb"→ 没声明编码,大概率乱码 - 正确写法:
"jdbcUrl": "jdbc:mysql://192.168.1.100:3306/mydb?useUnicode=true&characterEncoding=utf8mb4" - 如果URL里用了
&(XML/JSON转义),确保DataX能正常解析;若报错,可尝试用&(非转义)或检查JSON格式是否合法
目标表字段必须显式定义utf8mb4字符集
建表时没写CHARACTER SET utf8mb4,哪怕数据库默认是utf8mb4,字段也可能继承latin1(尤其旧库迁移场景)。
- 执行
SHOW CREATE TABLE your_table;,检查CREATE TABLE语句中字段是否有CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci - 没有的话,不能只改数据库:用
ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;重建表结构 - 若表数据量大,
CONVERT TO会锁表;更安全的做法是逐字段修改:ALTER TABLE your_table MODIFY COLUMN name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - ⚠️ 执行前务必备份;若原数据已是乱码(比如以
latin1编码存的中文bytes),转换后仍是乱码,需先做编码修复再转
导出导入环节也要保持utf8mb4一致
DataX同步前若用mysqldump导出过中间文件,或同步后用客户端查结果,这些环节同样可能引入乱码。
- 导出时加参数:
mysqldump --default-character-set=utf8mb4 -u user -p db_name > data.sql - 导入时也加:
mysql --default-character-set=utf8mb4 -u user -p db_name - Navicat等GUI工具需单独设置连接编码为
utf8mb4,不能依赖服务器默认 - Linux终端执行
mysql命令前,建议先运行export MYSQL_PWD="xxx"并确认终端locale为zh_CN.UTF-8,否则输入中文可能被截断
最容易被忽略的是:字段级字符集可以覆盖表级,表级可以覆盖库级,库级可以覆盖服务端——所以SHOW CREATE TABLE看到的才是真实生效的字符集,别信“我库已经设成utf8mb4了”这种直觉判断。


















