今天在执行Kettle脚本同步数据的时候报错,信息如下:
2021/06/30 13:32:44 - 表输出.0 - Error inserting/updating row
2021/06/30 13:32:44 - 表输出.0 - Incorrect string value: '\xF0\x9F\x92\x95' for column 'name' at row 1
其实这个问题网上有很多相关的资料,原因就在于源数据库的表中存储了emoji表情,mysql的utf8编码的一个字符最多3个字节,但是一个emoji表情为4个字节,所以utf8不支持存储emoji表情.
但是问题来了,
当初创建目标库的时候,特意和源库的字符集编码保持一摸一样.就是为了避免这种源和目标数据库字符集不一致而出现的问题。
于是特意去查了一下两个库的相关设置,如下:
show variables like ‘%char%’
源库和目标库的字符集设置确实是一摸一样,而且character_set_connection和character_set_database这两个参数都已经设置为了utf8mb4,那么为什么在源数据中可以存储emoji表情,但是到了目标库存储就报错了呢?
继续想办法定位问题,我们尝试通过SQL手工插入一条测试数据到表中,发现是可以插入成功的.
insert into dw.dw_my_table(id,name) values(‘2’,‘b💕’)
于是将问题定位到Kettle工具上.
Kettle中是通过JDBC驱动连接到Mysql的,驱动的版本为mysql-connector-java-8.0.25.
官方对JDBC驱动的说明如下:
如果JDBC的URL没有指定characterEncoding和connectionCollation参数,则JDBC驱动会自动检测服务器端指定的character_set_server变量,并且与该变量的值保持一致。
原来如此.
修改Mysql数据库配置文件,将character-set-server参数设置为utf8mb4之后,果然Kettle任务运行成功了。
但是有些情况下,我们没有办法修改Mysql数据库的配置文件时,我们也可以通过修改Kettle的配置文件来解决此问题.
Kettle中配置数据库连接,选项中可以增加参数,尝试配置如下:
命名参数:characterEncoding 值:utf8mb4
系统提示:Unsupported character encoding ‘utf8mb4’.
这里的参数值需要使用 Java 风格的形式指定.
于是将参数值改为UTF-8(注:对于Mysql JDBC 8.0.13及以后的版本,如果设置了characterEncoding=UTF-8,会映射到Mysql的utf8mb4字符集).
Kettle任务正常运行,数据插入成功.
至此问题完美解决,学习了.