ALTER TABLE dst_user CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; SHOW CREATE TABLE dst_user;
源库是 utf8mb4,目标库建库时用了 latin1。同步过去的昵称里,带 emoji 的 1362 条全变成问号,纯中文倒还正常。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,latin1 只认单字节,四字节的 emoji 在写入时被替换成问号。连接层字符集设对也没用,落库那一步的列字符集才是最终决定因素。中文能过是因为它落在 latin1 的可表示范围外时被换了一种解释方式,看着正常其实已经不对。
这次卡住的地方就在「同步链路乱码」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。
验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。
处理上按这个顺序:把目标库和表统一改成 utf8mb4 排序规则用 utf8mb4_general_ci;连接串加上 characterEncoding=utf8 并确认 useUnicode 打开;源端读取时按二进制取 避免中途转码;改完重新同步受影响的那批行。
改完只确认一件事:重新同步的昵称里 emoji 正常显示 问号行数为 0。
