项目中使用 canal 来同步数据到 Elasticsearch, 遇到很多问题,做一下记录:
版本问题:
1. 解析binlog出错 ,表现为 limit excceed:xx
目前使用 mariadb 10.9.7/10.10.6 + canal 1.1.6 hotfix ,在这个版本组合中只要binlog中出现对表结构操作的SQL语句就会出错并卡住。
解决办法:
(1)每次在对表结构操作后重启数据库服务,这样会新建一个binlog 文件 。
(2)升级到1.1.7, release说明中说支持mariadb 10.10.x的binlog, 但目前1.1.7是alpha版,从isuse上看此版本的问题还是挺多的,我也简单的试了一下1.1.7-alpha-2版本,在配置没有任何更改的情况下无法同步,查看adapter日志能发现DML#4796,但就是不同步到es, 这种情况可能是配置问题,但由于不想使用alpha版本没有更详细的测试,等到正式版出了再说。
2.日志能发现DML,但不能同步到ES。
这种错误出现的最多,引起的原因也五花八门,目前发现以下原因:
(1)filter配置的问题,这种情况从日志能够看出来,首先deployer在启动时会在日志中打印出转意后的正则,可查看和自己设置的是否一致。另外如果filter通过了在DML日志后会根一条带有data 的日志。
(2)filter的正则问题,filter正则过滤真是让我挠头。
a. canal会自动为正则加"^"和“$",所以配置时不能再加了,多个正则用逗号分隔。
b. 正则写的时候需要按Java字符串转义后再按正则转义,例如想配置"."那么要写成 "\\.",其中"\\"是java字符串转义,转成"\.", "\"是按正则转义,对"."转义
c. 官方说明过滤内容是 "库名.表名" ,但我设置 :
canal.instance.filter.regex=record_.+\\..*
是想仅同步数据库名以"record_"开头的所有表。但是设置后所有的同步都失效了,目前没有解决,使用了默认的 ".*\\..*"。
(3) sql错误
canal 对sql写法是有要求的,并不是能执行的就行,目前已知的要求有:
a. 只支持 left join
b. 第一个表必须是主表
c. 主表的主键字段名必须是_id
d. left join on 中使用的条件字段必须包含在select 选择列中
e. 不支持多级嵌套查询
对SQL的检查最好是先启动canal,然后再把写好yml文件拷到配置目录中,这时查看日志,会看到动态加载的日志,如果成功就说明sql没问题,否则会出现加载出错信息。