Canal 增量同步adapter日志正常,但是es中无数据

5n0oy7gb  于 7个月前  发布在  其他
关注(0)|答案(2)|浏览(70)

Question

Canal 增量同步日志正常,但是es中无数据,全量同步是没问题的。
adapter日志:
2022-07-26 11:33:03.986 [pool-2-thread-1] DEBUG c.a.o.canal.client.adapter.es.core.service.ESSyncService - DML: {"data":[{"max_receipted_at":null,"code":"STMT220726134GAD1C","supplier_ent_code":"SCEC210128YJNMT8G"}],"database":"supply-chain","destination":"supply-chain_statement","es":1658806383000,"groupId":"canal-consumer-supply-chain_statement","isDdl":false,"old":null,"pkNames":["code"],"sql":"","table":"statement","ts":1658806383977,"type":"INSERT"}
Affected indexes: supply-chain.base_order

日志中没有任何报错,但是es中没有数据,该从哪个方向去排查问题?

mutmk8jj

mutmk8jj1#

@chenqi4547 以我的举例:

  1. 环境:mysqlA-> canal server -> rocketmq -> canal client adapter ->(es7 + mysqlB)
  2. 现象:mysqlA变更后,mysqlB成功变更、rocketmq消息位点正常,但es7却没变化,无错误日志。
  3. 推测:esAdapter忽略了消息
  4. 原因:es7.yml的sql的from 主表,与binlog中的表名有一点差异(A和B库表名不完全一样),导致esAdapter跳过该消息。
  5. 解决:修改yml的sql的from部分,与binlog的主表一致,问题解决。
  6. 分析过程:下载canal-master代码,放入idea编译,专门debug内部的client-adpater的launcher模块,它就是Adpater运行包的模块,把开发环境的配置文件配置到它下面,运行CanalAdapterApplication入口。给OuterAdapter的sync代码打个断点,看看binlog的消息被如何处理了。

canal的项目代码质量很好,阅读体验不错,可惜就是文档写的太少了,希望能贡献一些,但是没找到入口。
参考下图:如果dml消息与yml配置文件的group、db、destination、table的配置不一致,会导致最下方的if语句不执行,也不打warn log(认为是开发自己的问题)。

lyr7nygr

lyr7nygr2#

@keel2008GitHub 感谢回复,这个问题昨天也通过DEBUG源码定位并解决了。

分析过程:

  1. 专门debug内部的client-adpater的launcher模块,在 com.alibaba.otter.canal.client.adapter.es.core.service.ESSyncService#insert 方法中,调用了 mainTableInsert() 方法。
  2. ESSyncUtil.pkConditionSql() 用于拼接主键条件,会解析es7.yml的sql中的主键,用于设置 where 条件
  3. 通过DEBUG发现,由于主键使用了 concat 函数,导致解析出来的 idColums 有两条记录,其中一条 columName 为 null,导致 condition 的值如图所示。

问题原因:解析主键带有 concat 函数时,出现了 columName 为 null 的数据。

解决方法:

  1. 避免主键使用 concat 函数。
  2. 修改源码,跳过为 null 的 idColums。

目前采用的避免使用函数解决的。

相关问题