Canal 踩坑记录

 

之前用Canal 处理 mysql blog 日志。 记录了踩坑过程, 躺在笔记本里许久, 整理一下。

 

 

1、第一踩 获取不到binlog,无报错

我先使用本地Canal 链接了本地mysql数据库 , 版本mysql 8.0.13 过程和谐,链接正常,也能正常通信。 并转发kafka ,本地接收通信。

binlog最新日志文件:binlog.000011

后来,在将本地canal复制的数据库转成 dev环境数据库 mysql 5.7.31 后, 启动canal不报错, 但是不能接收到消息。

binlog最新日志文件:mysql-bin.001156

启动后最新日志:

2022-04-07 16:42:44.364 [destination = example , address = /127.0.0.1:3306 , EventParser] WARN c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> begin to find start position, it will be long time for reset or first position 

2022-04-07 16:42:44.365 [destination = example , address = /127.0.0.1:3306 , EventParser] WARN c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - prepare to find start position by switch ::1649314551000

 

调试许久,本以为用户权限问题, 查看过权限没问题。 并且根据用户账号链接数据库可以读取到binlog日志。

之后看到canal全量日志获取过程可能遇到的问题:canal.instance.master.journal.name不起作用问题。

发现这个问题需要消除 canal目前的状态才行,就是将 instance.properties 平级的 meta.dat 文件删除,这样canal才能从指定位置获取日志。

打开meta.dat 文件看了下, 里面记录了本地canal链接本地mysql的binlog同步进度, 导致链接dev环境过不去, 删除后,再次启动canal。可以正常从 dev mysql订阅消息。

 

2、第二踩 修改的库表已删除。

错误日志  

 1 2022-04-07 17:05:41.179 [destination = example , address = /127.0.0.1:3306 , EventParser] ERROR c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - dump address /127.0.0.1:3306 has an error, retrying. caused by
 2 com.alibaba.otter.canal.parse.exception.CanalParseException: com.alibaba.otter.canal.parse.exception.CanalParseException: com.alibaba.otter.canal.parse.exception.CanalParseException: fetch failed by table meta:`cygg`.`data_trace_zijinjiemi_zhuli`
 3 Caused by: com.alibaba.otter.canal.parse.exception.CanalParseException: com.alibaba.otter.canal.parse.exception.CanalParseException: fetch failed by table meta:`cygg`.`data_trace_zijinjiemi_zhuli`
 4 Caused by: com.alibaba.otter.canal.parse.exception.CanalParseException: fetch failed by table meta:`cygg`.`data_trace_zijinjiemi_zhuli`
 5 Caused by: java.io.IOException: ErrorPacket [errorNumber=1142, fieldCount=-1, message=SHOW command denied to user 'binlog'@'127.0.0.1' for table 'data_trace_zijinjiemi_zhuli', sqlState=42000, sqlStateMarker=#]
 6 with command: show create table `cygg`.`data_trace_zijinjiemi_zhuli`
 7   at com.alibaba.otter.canal.parse.driver.mysql.MysqlQueryExecutor.query(MysqlQueryExecutor.java:61) ~[canal.parse.driver-1.1.6-SNAPSHOT.jar:na]
 8   at com.alibaba.otter.canal.parse.inbound.mysql.MysqlConnection.query(MysqlConnection.java:106) ~[canal.parse-1.1.6-SNAPSHOT.jar:na]
 9   at com.alibaba.otter.canal.parse.inbound.mysql.dbsync.TableMetaCache.getTableMeta(TableMetaCache.java:186) ~[canal.parse-1.1.6-SNAPSHOT.jar:na]
10   at com.alibaba.otter.canal.parse.inbound.mysql.dbsync.LogEventConvert.getTableMeta(LogEventConvert.java:975) ~[canal.parse-1.1.6-SNAPSHOT.jar:na]
11   at com.alibaba.otter.canal.parse.inbound.mysql.dbsync.LogEventConvert.parseRowsEventForTableMeta(LogEventConvert.java:496) ~[canal.parse-1.1.6-SNAPSHOT.jar:na]
12   at com.alibaba.otter.canal.parse.inbound.mysql.MysqlMultiStageCoprocessor$SimpleParserStage.onEvent(MysqlMultiStageCoprocessor.java:280) ~[canal.parse-1.1.6-SNAPSHOT.jar:na]
13   at com.alibaba.otter.canal.parse.inbound.mysql.MysqlMultiStageCoprocessor$SimpleParserStage.onEvent(MysqlMultiStageCoprocessor.java:251) ~[canal.parse-1.1.6-SNAPSHOT.jar:na]
14   at com.lmax.disruptor.BatchEventProcessor.processEvents(BatchEventProcessor.java:168) ~[disruptor-3.4.2.jar:na]
15   at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:125) ~[disruptor-3.4.2.jar:na]
16   at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[na:1.8.0_281]
17   at java.util.concurrent.FutureTask.run(Unknown Source) ~[na:1.8.0_281]
18   at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:1.8.0_281]
19   at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[na:1.8.0_281]
20   at java.lang.Thread.run(Unknown Source) [na:1.8.0_281]

 

修改方式:

默认canal订阅了全库全表,

我这里业务只需要关注一个数据库就可以,

修改 instance.properties 配置文件的

1 # canal.instance.filter.regex=.*\\..*
2 # 修改为:
3 canal.instance.filter.regex=thsdb\..*  # 只关注 thsdb 数据库的改动。相当于设置白名单
4 canal.instance.filter.black.regex=mysql\\.slave_.*   # 这里设置黑名单

 

扩展知识:

canal.instance.filter.regex=.*\\..*

全库全表

.*\\..*

.*\\..*

指定库表

库名\..*

thsdb\..*

单表

库名.库表

thsdb.user

多规则组合使用

库名1\..*,库名2.表名1,库名3.表名2 (逗号分隔)

thsdb\..*,mysql.slow_log,sys.sys_config

注意:这里修改后,对应 java 程序 connector.subscribe 配置也要修改

全库全表

.*\\..*

connector.subscribe(".*\\..*")

指定库表

库名\..*

connector.subscribe("thsdb\\..*")

单表

库名.库表

connector.subscribe("thsdb.user")

多规则组合使用

库名1\..*,库名2.表名1,库名3.表名2 (逗号分隔)

connector.subscribe("thsdb\\..*,mysql.slow_log,sys.sys_config")

如果修改了 canal 的 instance文件,不要再客户端调用 connector.subscribe(".*\\..*"),相当于没配置。这里过滤根据 connector.subscribe("表达式")里的正则表达式过滤。

如果想在客户端调用 connector.subscribe(".*\\..*"),可以在 配置中设置 canal.instance.filter.black.regex=mysql\\.slave_.* 设置黑名单进行过滤。

 

3、第三踩 初次运行,表不存在,提示1146错误

不能保存,不能同步,怎么办。

canal 版本 1.1.6 ,

mysql 版本 5.7.4

canal 版本canal.deployer-1.1.6-SNAPSHOT 在本地运行没有这个问题 】

这是最终改版的配置,conf/example/instance.properties 配置

1  # table regex 当前使用,监控 thsdb 库
2 canal.instance.filter.regex=thsdb\\..*
3 # table black regex 数据库解析表的黑名单, 暂时不需要 cygg库
4 canal.instance.filter.black.regex=mysql\\.slave_.*,cygg\\..*

 

但这个配置在最开始canal启动的时候,提示:Table 'thsdb.BASE TABLE' doesn't exist, 这个表确实不存在。

尝试了将配置改成默认的配置,还是不行,依旧是这个错误。

1  # table regex 当前使用,监控 thsdb 库
2 canal.instance.filter.regex=.*\\..*
3 # table black regex 数据库解析表的黑名单, 暂时不需要 cygg库
4 # canal.instance.filter.black.regex=mysql\\.slave_.*,cygg\\..*

 

也尝试了将这个错误跳过去,需要修改的是 canal.properties 配置 。没效果。

1 canal.instance.filter.table.error = true

 

最终尝试到一种方法

conf/example/instance.properties 配置

1 canal.instance.filter.regex=.\..

 

启动, 正常。

启动后生成 meta.bat 文件后。

再把配置修改为最终的

1 canal.instance.filter.regex=thsdb\\..*

 

终于启动成功。

 

posted @ 2022-11-05 14:56  currentTimeMillis  阅读(1344)  评论(0编辑  收藏  举报