cdc同步MySQL数据异常

Bug 反馈
使用cdc增量同步tidb到mysql

  1. 创建一个changefeed同步表tb1
  2. 开启任务后报错:表不存在
  3. 在目标端创建tb1(空表)
  4. 在tidb执行update语句 update tb1 set name=‘a’ where id=2;
  5. 目标端tb1出现 id=2的行记录
  6. 再次在tidb执行update语句 update tb1 set name=‘a’ where id=1; 目标端tb1没有出现id=1的行记录
  7. 在tidb执行insert语句,id=1000,目标端tb1出现id=1000的行记录(说明同步是正常的)

【 TiDB 版本】 v7.1.5

mysql 是什么版本?

TiCDC 工具只负责复制增量数据,需要使用 Dumpling/TiDB Lightning 工具或者 BR 工具进行全量数据的初始化。 经过全量数据的初始化后,需要将 start-ts 指定为上游备份时的 TSO。例如:Dumpling 目录下 metadata 文件中的 pos 值,或者 BR 备份完成后输出日志中的 backupTS

8.0.27

开启同步前目标表是空表,开启后只执行了update语句,为什么第一次被update的行会同步到MySQL,后面的几次update都不会同步行数据

表有主键吗

有自增主键

执行第 6 步的时候 tidb 里是否有 ID=1 的数据,且 name 字段值为 ‘a’

tidb 针对空更新,即数据没有变化,tikv 侧不会产生增量,即 ticdc 无法捕获这个空更新。

可以看看是不是这个问题

执行第 6 步的时候 tidb 里是没有id=1的数据;我不理解的是目标表是个空表为什么第一次update会把这行数据同步到MySQL,感觉是bug

他这个更改不是针对所有update失效,而是针对在你已有但是下游没有的数据行,进行不同步,当你执行update where id = 1000;的时候,这个update应该是可以同步下去的

tidb不是针对空更新吧,tidb侧是有数据的,是mysql侧没数据

可以复现,如果你现在对主键字段进行变更,是可以传下去的,他把update变成了delete+insert的方式。

然后第一次的时候传下去应该也是因为CDC报错重启,自动更改了一下safe-mode=true,然后把update变为了delete+replace,导致传下去一条,然后又转回了默认值,safe-mode=false,默认值下不进行主键变更,update就是传下去update,所以没有进行更新数据。
在sink-uri里面,指定上safe-mode=true后,应该就可以了。

是的 tidb侧是有数据的,是mysql侧没数据

safe-mode=true 设置了这个参数还是会出现,在tidb侧后update在MySQL侧(空表)会出现这条记录

safe-mode=true 会把update变为replace
https://docs.pingcap.com/zh/tidb/stable/ticdc-faq#使用-ticdc-创建同步任务时将-safe-mode-设置为-true-后为什么上游的-insertupdate-语句经-ticdc-同步到下游后变为了-replace-into

对呀,因为safe-mode = true后,传下去的update变成了delete+replace的方式,我意思这样改的话,除了第一条以外,后续的也会传下来了。
而不是像最开始的一样,只传下来首条,后面的update mysql没有的行传不下来

1 个赞

safe-mode = false 为什么第一条会传到目标端,这个是bug吗;应该是都不会传下来才对

我感觉他应该是报错恢复后有一个短时间的自动更改为safe-mode = true,随后又改了回来。
具体这么做是否有自己的考量,不太清楚。