客户名字里有个 𠮷,插入时报 Incorrect string value: '\xF0\xA0\xAE\xB7' for column 'name'。同一条数据把字换成 吉 就能存。乍看像缓存或者权限的锅,追下去往往不是。
python3 -c "print('𠮷'.encode('gbk'))"
python3 -c "print('𠮷'.encode('gb18030').hex(), '𠮷'.encode('utf-8').hex())"
追下去是这么回事:GBK 只覆盖两万多个汉字,𠮷 属于扩展 B 区,四字节,GBK 里没有对应码位。GB18030 的四字节区包含它,MySQL 的 gb18030 排序规则也能存。
「GB18030 生僻字」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。
先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。别只看报错的最后一行,往上看几行,真正的起因通常在上面。
同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。
具体做法是,优先把字段和连接都改成 utf8mb4 别退回国标编码;必须用国标时才换 gb18030 并同步客户端配置;迁移前用 iconv 全量试转一遍 找出不可映射字符;前端校验放宽到扩展区汉字。
验收就看一点,同一个名字能正常插入 查询返回的字符和输入完全一致。
