Flink MySQL CDC时区不一致的原因
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在解析binlog数据中的timestamp字段时,cdc会使用到作业里配置的server-time-zone信息,也就是MySQL服务器的时区,如果这个时区没有和MySQL服务器时区保持一致,就会出现时区的问题,vvp默认是utc+8。
使用flink-mysql-cdc读取mysql的binlog,发现mysql中的timestamp类型的字段的值与flink中该字段的值不一致:
在mysql中的值为:2022-08-01 20:56:16,flink-mysql-cdc读取出来的值为:2022-08-01 12:56:16.000,相差了8个小时。
同时,观察到mysql中datetime类型的字段并不会出现这个问题。
flink没有添加这样的配置,所以flink采用了默认的UTC时区,于是导致了这个问题,添加该配置'server-time-zone' = 'Asia/Shanghai'后问题解决。
并且,观察到一个现象,由于我的配置'scan.startup.mode' = 'initial',cdc会有初始化阶段,初始化阶段并不会出现这个问题,原因是cdc的初始化逻辑并不是读binlog,而是直接执行SQL语句读取数据,这时候的时区会由数据库的时区配置决定,因此没有出现问题,而进入增量读取binlog阶段后,时区问题就出现了。
总结 mysql中datetime类型和timestamp类型是有所区别的(参考文档),对于timestamp类型的字段,mysql会从当前时区(根据数据库配置/会话设置等)转换为UTC进行存储,读取的时候会从UTC转换回当前时区,而datetime类型不会发生这种情况。
flink-mysql-cdc在读取binlog的时候与时区配置无关,而是直接读取到了timestamp类型字段在UTC时区的值,如果需要指定时区,则需要添加flink配置。