0 背景
我在生产环境使用canal的时候,由于用的是嵌入式模式,所以经常需要发版重启。每次发版的时候,canal监控的数据库是有数据持续写入的,在这个过程中,下游的消费者时常提出数据存在丢失的情况,那么下面通过分析canal的源码寻找数据丢失的原因。
1 Canal 消费流程源码分析
略过一些启动过程,直接找到消费binlog的主流程代码,是AbstractEventParser
类的start
函数中,会启动一个子线程parseThread
,在run函数中,有几个点需要注意:
- 初始化上次消费的Position
EntryPosition position = findStartPosition(erosaConnection);
- 不断dump数据库的binlog并处理:
if (isGTIDMode() && StringUtils.isNotEmpty(startPosition.getGtid())) {
// 判断所属instance是否启用GTID模式,是的话调用ErosaConnection中GTID对应方法dump数据
erosaConnection.dump(MysqlGTIDSet.parse(startPosition.getGtid()), sinkHandler);
}
- binlog的handle函数中,把消费到的消息写入
transactionBuffer
对象中:
if