开发者社区> 问答> 正文

关于PeriodMixedLogPositionManager可能存在点位数据读取不及时导致日志丢失

上下文 看代码中, 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

展开
收起
Java工程师 2023-05-08 17:55:28 82 0
1 条回答
写回答
取消 提交回答
  • 你可以看下我的一些设计文档, 当时设计的是有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

    2023-05-09 18:49:25
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
PostgresChina2018_赖思超_PostgreSQL10_hash索引的WAL日志修改版final 立即下载
Kubernetes下日志实时采集、存储与计算实践 立即下载
日志数据采集与分析对接 立即下载