开发者社区> 问答> 正文

当指定的pos刚好是rowdata(TableMap的下一条)数据时,canal server 端会

测试版本:canal 版本 1.0.24

Canal在实现该功能时,通过LogEventConvert.parseRowsEvent 解析event时抛出 TableIdNotFoundException, 但是parseRowsEvent 直接捕获了所有Exception,并重新抛出 CanalParseException,这样AbstractEventParser的parseThread 工作线程获取的一直都是Throwable的异常,无法感知到TableIdNotFoundException,导致陷入死循环;

修改LogEventConvert.parseRowsEvent 使其抛出TableIdNotFoundException后,下次循环线程会感知needTransactionPosition变量已经会true,进入findTransactionBeginPosition方法后,会调用seek方法,但seek方法只解析事务头/尾,那么当前的seek方法中实现的sink的event事件就解析不到(因为rowdata数据被过滤了),故reDump 一直都不会为true,从而也不会进入从头读取binlog的逻辑内,就又进入了主线程的死循环内。

PS: 个人简单分析,不知是否理解有误,抑或是findTransactionBeginPosition不是为了解决这个场景的?

修复建议1:

将LogEventConvert.parseRowsEvent 在catch CanalParseException前加个catch TableIdNotFoundException并将其抛出,让上层继续感知; 将MysqlEventParser.findTransactionBeginPosition方法中的第一个mysqlConnection.seek改为mysqlConnection.dump 即可解决这个BUG 修复建议2:因为MysqlEventParser.findTransactionBeginPosition只在needTransactionPosition为true时调用,故删除MysqlEventParser.findTransactionBeginPosition方法中的第一个mysqlConnection.seek逻辑,直接让其进入reDump逻辑内也可解决这个问题,减少一次dump请求;

原提问者GitHub用户wingerx

展开
收起
绿子直子 2023-05-09 11:58:26 81 0
1 条回答
写回答
取消 提交回答
  • 这个1.0.25我记得有修复过,可以先尝试一下

    原回答者GitHub用户agapple

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

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载