在EntryEventSink类的sinkData方法中,有对filterEmtryTransactionEntry进行判断的代码段,如下所示:
if (filterEmtryTransactionEntry && !CollectionUtils.isEmpty(events)) { long currentTimestamp = events.get(0).getEntry().getHeader().getExecuteTime(); // 基于一定的策略控制,放过空的事务头和尾,便于及时更新数据库位点,表明工作正常 if (Math.abs(currentTimestamp - lastEmptyTransactionTimestamp) > emptyTransactionInterval || lastEmptyTransactionCount.incrementAndGet() > emptyTransctionThresold) { lastEmptyTransactionCount.set(0L); lastEmptyTransactionTimestamp = currentTimestamp; return doSink(events); } }
请问这里的判断基于什么目的?不太明白。
把canal.instance.transaction.size的大小设置为1024,在mysql上运行一个事务,进行1023次插入,那么canal-server会产生1025个event,按照EventTransactionBuffer的逻辑达到1024的时候会flush一次,随后剩下的一个event(Transactionend类型)会单独进行flush,但是由于上述代码的缘故,该event被忽略了,这应该不尽合理吧????
原提问者GitHub用户lulu2panpan
这段代码的目的是控制空事务的处理,即事务头和尾都没有操作时产生的空事务,避免过多的空事务对性能造成负面影响。如果出现空事务,根据一定的策略控制,只要空事务数量或时间间隔达到阈值,就会放过空事务,便于及时更新数据库位点,表明工作正常。
对于你提到的情况,确实会出现忽略最后一个TransactionEnd类型的event的问题。这可能是因为该event没有被判断为非空事务,而被过滤掉了。这个问题需要进一步探究和修复。
事务头和尾主要是用来区分事务边界,本身数据没啥意义. 1025的transaction end事件的确可能被忽略了。 在canal+otter产品配合实施中,otter对于过滤后的空事务事件不是强需求,反而占用了过多的canal eventStore的ringBuffer空间,导致整体业务的处理速度变慢,所以当时设计默认值为true,待考虑和优化
原回答者GitHub用户agapple
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。