测试描述:canalserver1.0.22基于mariadb10.1.14的HA功能不好用,部署两台canaserver当其中一台server挂掉后,zookeeper已经切换到新的canalserver,但新的canalserver获取的binlogname不正确导致读取mariadb的binlog错误。 mariadb中binlog名字:
(canal@127.0.0.1) [canal_test]> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 25487 | | mysql-bin.000002 | 358 | | mysql-bin.000003 | 1518 | | mysql-bin.000004 | 29137967 | +------------------+-----------+ canalserver获取的binlogname:【binlog[mysql-bin.000004$^Nk<U+0081>:29138083]】中后半段有乱码
解决方法: 修改canalserver1.0.22源码com.alibaba.otter.canal.protocol.CanalEntry中对获取到的binlogname进行过滤,添加如下代码: 【public String filterLogFileName(String logfileName) { System.out.println("开始过滤logfileName:"+logfileName); Pattern p = Pattern.compile("(mysql-bin.[0-9])."); Matcher m = p.matcher(logfileName); while(m.find()){ if(m.groupCount() >= 1) { System.out.println("过滤logfileName为:"+m.group(1)); return m.group(1); } } return logfileName; } 】
修改代码: 【public String getLogfileName() { java.lang.Object ref = logfileName_; if (ref instanceof String) { return filterLogFileName((String) ref); } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; String s = bs.toStringUtf8(); if (com.google.protobuf.Internal.isValidUtf8(bs)) { logfileName_ = s; } return filterLogFileName(s); } } 】
重新打包测试验证HA功能可以自动切换,但是存在canalserver切换时client消费端重复消费的问题。 但是在mysql5.6中测试未出现此问题
现在有测试mariadb10.1.14的验证版本吗,看源码好像是从protocolbuffer读取的时候binglogname就存在问题了,对binlog协议格式不是很了解,这个是protocolbuffer定义的协议格式问题吗?
实际代码分析:出现在【com.alibaba.otter.canal.parse.inbound.mysql.dbsync】中,int netlen = getUint24(PACKET_LEN_OFFSET);代码获取的包长度不一致造成的,maraidb和mysql获取的长度为:47和43,mariadb多获取4字节导致后续处理logfilename读取多4个字节;您好问下作者什么情况导致netlen获取的不一致?
原提问者GitHub用户linwenxue
最后4位可能是checksum,你试着找一下mariadb关闭一下mariadb的binlog checksum机制看看. ps. 之前有支持过mysql5.6的checksum,可能mariadb协议上有点不一样,没完全兼容,先帮忙验证一下是否为checksum问题
if (FormatDescriptionLogEvent.versionProduct(versionSplit) >= FormatDescriptionLogEvent.checksumVersionProduct) {
之前canal代码是限制了>=5.6.1版本号才会开启checksum检查,这是以前mysql5.6的机制,mariadb估计有不一样的行为
原回答者GitHub用户agapple
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。