开发者社区> 问答> 正文

使用Canal指定Position同步,同步位置点提前,重复记录导致Canal-Adapter-RD

环境信息

canal version: 1.1.3 canal adapter rdb: 1.1.3 mysql version:5.7.23

问题描述

使用Canal指定Position同步,由于Canal会将同步位置点提前(看之前的讨论提到是提前60秒、未来得及从代码端确认),会产生重复记录,进而导致Canal-Adapter-RDB报主键唯一错,阻塞复制过程

步骤重现

1.向两张表中分别插入一条数据:

insert into busi1 values (1, 'in', 'asdf', now()); insert into busi2 values (1, 'in', 'asdf', curdate());

2.使用mysqldump全量导出至目标Oracle数据库

3.根据show master status记录位置点,在canal的instance配置文件中设置对应position,本次测试position为1057

4.向一张表中插入一条数据:

insert into busi1 values (2, 'out', 'qwer', now());

5.启动canal

6.启动canal-adapter

7.检查canal-adapter日志,发现报错:

2019-05-23 15:50:22.157 [pool-8-thread-1] ERROR c.a.o.canal.adapter.launcher.loader.CanalAdapterWorker - java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.RuntimeException: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (TEST.PK_BUSI2) violated

java.lang.RuntimeException: java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.RuntimeException: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (TEST.PK_BUSI2) violated

at com.alibaba.otter.canal.client.adapter.rdb.RdbAdapter.sync(RdbAdapter.java:169)
at com.alibaba.otter.canal.adapter.launcher.loader.AbstractCanalAdapterWorker.batchSync(AbstractCanalAdapterWorker.java:198)
at com.alibaba.otter.canal.adapter.launcher.loader.AbstractCanalAdapterWorker.lambda$null$1(AbstractCanalAdapterWorker.java:62)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at com.alibaba.otter.canal.adapter.launcher.loader.AbstractCanalAdapterWorker.lambda$null$2(AbstractCanalAdapterWorker.java:58)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

8.该主键冲突会阻塞之后的busi1的第2条记录入Oracle库

9.如果去掉Oracle数据库上busi2的主键PK_BUSI2,会发现id为1的记录重复插入了两条

10.查看Canal日志:

2019-05-23 15:49:26.689 [destination = example , address = /192.168.100.25:3306 , EventParser] WARN c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> find start position successfully, EntryPosition[included=false,journalName=binlog.000009,position=961,serverId=11,gtid=,timestamp=1558596932000] cost : 2919ms , the next step is binlog dump 可见,起始点提前到961,比配置文件中的位置靠前

11.分析原因疑似Canal提前位置点,导致重复记录

期待结果

1.Canal复制的起始点按照配置文件中实际制定的position执行

2.Canal复制的起始点还采用提前的方式不变,目标数据库端通过主键限制重复记录,Canal-Adapter对主键冲突错误跳过不处理,或采用类似于数据库Merge语句的功能,如存在记录则按新记录更新

现执行情况

1.Canal复制的起始点比配置文件提前,导致数据重复

原提问者GitHub用户power225

展开
收起
云上静思 2023-05-04 13:16:33 162 0
1 条回答
写回答
取消 提交回答
  • 可以在RDB同步时忽略一下ORA-00001约束冲突报错,最新代码已修改

    原回答者GitHub用户agapple

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

相关电子书

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