最近一个与qq有关的服务迁到腾讯云上,相应的数据库也要从原阿里云RDS迁移到腾讯云CDB上,通过一番摸索,不带任何政治色彩的说,CDB跟RDS相比弱的不止一条街。好比看个错误日志还要提工单,数据库访问没有白名单,数据传输服务竞不支持源库的开启GTID,自带的后台管理是phpMyAdmin,要临时看查询日志也要提工单,固然这些都是能够容忍经过其它方法解决的,可是若是使用上带来了mysql数据库自己的影响,就用的不太爽了。php
最近2个月一直在弄与字符集相关的工做,却仍是在cdb踩到一个大坑。状况是这样的,咱们旧的RDS上的数据库表定义都是utf8,但因为历史缘由,开发一直使用 latin1 去链接的。如今要把这样的一个db迁移到CDB,腾讯云的数据传输服务出了点问题,因而想了办法用阿里云的DTS反向迁。现象是:html
用Navicat客户端latin1链接,旧数据显示都okmysql
但程序端看到历史数据全是乱码,新数据正常web
并且新数据经过navicat去看用 utf8 链接才正常sql
在mysql命令行下手动 set names latin1
读取旧数据ok,但新数据乱码数据库
这明显是新写入的时候就是以 utf8 链接的,读取的时候新旧数据也以 utf8 链接。但应用端已明确设置使用 latin1 链接来读写。为了验证是否CDB的问题,在相同环境下自建了个mysql实例,一切都ok。this
腾讯云工程师先是怀疑迁移有问题,后来讲多是character_set_server设置的问题,我站在2个月来处理字符集的经验看了虽然不太可能,仍是配合截了几个图,在工单、电话了里撕了几个来回:阿里云
由于跟腾讯有合做关系,上头就直接联系到了腾讯云的人,这才找到问题根源:都是--skip-character-set-client-handshake
惹的祸。spa
--character-set-client-handshake Do not ignore character set information sent by the client. To ignore client information and use the default server character set, use --skip-character-set-client-handshake; this makes MySQL behave like MySQL 4.0
<!-- more -->
一看到这个选项就恍然大悟了,官方文档FAQ里有专门介绍:A.11.11(我的感受最后一段贴的结果有问题),大意是说为了兼容 mysql 4.0 的习惯,mysqld启动时加上 --skip-character-set-client-handshake
来忽略客户端字符集的设置,强制使用服务端character-set-server
的设置。命令行
但这个选项默认是没有开启的,当你在web控制台修改了实例字符集时,CDB自做自做主张修改了这个参数并重启 character_set_client_handshake = 0 。而这个参数在 show variables
看不到的,隐藏的比较深。正好我建实例的时候选择了utf8,而后修改成utf8mb4,但应用端要求latin1,便中枪了。
主要是之前没听过这个参数,后来发现老叶也有篇文章讲到它 MySQL字符集的一个坑,实际上是很小的东西,结果排查验证问题先后花了2天。。。