DM同步,在源端Update数据时,在TiDB端会有两条数据

【 TiDB 使用环境】
TiDB: V5.0.3
DM:V2.0.4

【概述】 场景 + 问题概述
迁移共1类分表,在MySQL中,共100张,表名:table_name_000–099,同步数据从MySQL到TiDB,数据量:10万条左右,同步正常

【问题】 当前遇到的问题
当在MySQL端执行一条update操作时,在TiDB端会重新再插入一条数据,而不是更新原来的数据

task配置:
# 任务名
name: “xxx-xx”
#全量+增量(all)迁移模式.
task-mode: “all”
#如果为分库分表合并,则需要此配置项
shard-mode: “pessimistic”
ignore-checking-items: [“auto_increment_ID”]
#下游 TiDB配置信息.
target-database:
host: “xxxx”
port: xxxx
user: “xxxx”
password: “xxxxx”
session:
tidb_skip_utf8_check: 1
tidb_constraint_check_in_place: 0
# 当前数据迁移任务需要的全部上游MySQL的实例配置.
mysql-instances:
-
#上游实例或者复制组ID,
source-id: “bfas_beta_repl01”
#需要迁移的库名或表名的黑白名单的配置项名称
block-allow-list: “global”
route-rules: [“route-1”]
mydumper-config-name: “global”
syncer-config-name: “global”
mydumper-thread: 4
loader-thread: 16
syncer-thread: 16
#黑白名单全局配置,各实例通过配置项名引用.
block-allow-list:
global:
do-dbs: [“bfas_common_trial”] #需要迁移的上游表的白名单
do-tables: #需要迁移的上游表的白名单
- db-name: “bfas_common_trial”
tbl-name: “t_act_relation_detail_[0-9][0-9][0-9]”
#dump处理单元全局配置,各实例通过配置项名引用.
mydumpers:
global:
threads: 4
chunk-filesize: 64
skip-tz-utc: true
routes:
route-1:
schema-pattern: “bfas_common_trial”
table-pattern: “t_act_relation_detail_[0-9][0-9][0-9]”
target-schema: “bfas_common_trial”
target-table: “t_act_relation_detail”
syncers:
global:
worker-count: 16
safe-mode: false

这个场景是发生在全量阶段还是增量sync阶段?

sync

这条数据在MySQL的100张分表中是唯一的,通过其中一个字段查询可以确认是唯一,同步完成后在TiDB的合并后的表中查询也是唯一,只有一条数据,此时再在MySQL端update此条数据,MySQL中还是只有一条,但TiDB中有两条了,一条原来的数据,一条这次update的数据
但是,再多update这条数据时,TiDB中还是只有两条,后续的update操作都直接更新TiDB中刚才插入的那条了。

Hi,可以传一下日志、或者给一下操作步骤以及表结构方便我们复现吗

总数据量:82000左右

update t_m_merchant_info_000 set mrchnt_shrt_nm = ‘xxx’, update_time = now() where mrchnt_id = ‘xxxxxxxx’
mrchnt_id:值为唯一

PRIMARY KEY (‘id’),UNIQUE KEY ‘uniq_mrchnt_id’ (‘mrchnt_id’) 在TiDB的表中都改为普通 KEY。

看描述 mrchnt_id 在mysql是分布式ID,全局唯一,但是在tidb中只是普通的key,应该在tidb的表结构定义中为UK或者PK,并且id要为普通字段。

可否贴下tidb中的表结构定义吗

KEY

其它字段都一样,就KEY部分,有修改

你这个明显有问题啊, 下游如何做到幂等呢 ? 下游tidb必须有PK或者UK,如果有多个UK,则以第一个UK为准。

下游tidb必须有PK或者UK ,这个会不会导致同步报错呢?之前我配置另一个DM任务时,保留了UK,去掉了PK,结果报错了,把update时Duplicate entry的错

DM同步报错Duplicate entry 这个帖子,当时配置了safe-mode:true,但导致有数据被清理了,所以后面就把safe-mode设置为false,去掉UK,解决的问题

把safe-mode改为false,不能去掉UK,如果去掉UK,那怎么在tidb中保证数据的唯一性呢

了解了,我再试试吧

我的理解,把safe-mode改为false,那所有SQL,都不做修改,insert,update等,都是从MySQL原样同步过来,那没有UK,PK,应该也是和MySQL端的数据是一样的,不会有影响,是不是我的理解有误呢?

已验证,已正常update了,谢谢

safe-mode=true,为将来自上游的 INSERT 改写为 REPLACE ,将 UPDATE 改写为 DELETE 与 REPLACE 后再向下游执行。tidb中没有UK或者PK,不管safe-mode是true或者false,那上游mysql中一条数据,可能在tidb中存在多条。另外建议比对下上游mysql和下游tidb的表数据或者重新全量同步一遍,有可能已经不一致了。

了解了,谢谢解答。