上下文 看代码中, PeriodMixedLogPositionManager.getLatestIndexBy 如果从 MemoryLogPositionManager 拿到是空,就直接返回null了,就会导致parser去别的地方(配置文件、mysql master)取上次的点位数据,也就是保存在zookeeper里的点位数据其实是没用的。。
在系统启动的过程中,首次调用这个接口,实际上就是会返回null,后面有了事件处理之后,MemoryLogPositionManager中才有数据,难道这个Manager要搭配其他LogPositionManager组合使用吗?
重现 例如我做了下测试,zk中的parse数据如下:
{"identity":{"slaveId":-1,"sourceAddress":{"address":"localhost","port":3306}},"postion":{"gtid":"","included":false,"journalName":"mysql-bin.000005","position":21704,"serverId":1,"timestamp":1541179545000}}
杀掉进程后,多写几条mysql数据,此时mysql binlog已经滚动到新位置。 重新启动canal后,因为zk这个值没加载到内存,所以读取到的是mysql master最新的数据:
2018-11-03 01:28:27.804 [destination = example , address = localhost/127.0.0.1:3306 , EventParser] WARN c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - find start position : EntryPosition[included=false,journalName=mysql-bin.000005,position=22955,serverId=,gtid=,timestamp=]
解决办法 建议可以参考 FileMixedLogPositionManager 或者 MixedLogPositionManager那种实现
public LogPosition getLatestIndexBy(String destination) { LogPosition logPosition = memoryLogPositionManager.getLatestIndexBy(destination); if (logPosition != null) { return logPosition; } //首次读取不到数据,从zk中捞 logPosition = loadDataFromZookeeper(destination); if (logPosition == null) { return nullPosition; } return logPosition; }
原提问者GitHub用户jiacheo
你可以看下我的一些设计文档, 当时设计的是有parse position和ack position两类, 引入这两个position主要是围了解决多种store的实现.
如果是实现file的store, parse和ack position肯定是不一致的, parser下次重启时读取上一次的parse position. 如果实现的是memory的store, parse和ack position就是一致的, parser下次重启时读取的就是ack position (这也是failback的实现)
目前外部也有团队在实现基于本地文件的store
原回答者GitHub用户agapple
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。