dm2.0.1同步mysql数据,偶尔会报错Duplicate entry,DM1.0.6不报错,但是查询会有异常

为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:

【TiDB 版本】

新TIDB版本:4.0.11(tiup安装)
老TIDB版本:3.0.3(ansible安装)

新的DM版本:2.0.1(tiup安装)
老的DM版本:1.0.6(ansible安装)

【环境描述】

4.0.11版本的TIDB通过DM2.0.1同步线上mysql数据
3.0.3版本的TIDB通过DM1.0.6同步线上mysql数据

数据源为同一套mysql

【问题描述】

现在新版本的DM在同步mysql数据时,偶尔会报Error 1062: Duplicate entry

报错内容如下:

[2021/05/14 15:38:32.750 +08:00] [ERROR] [db.go:274] [“execute statements failed after retry”] [task=online_auth_center] [unit=“binlog replication”] [queries=“[INSERT INTO auth_centerdb.biz_user (id,global_id,biz_id,biz_user_id,status,ctime,mtime,creator,modifier) VALUES (?,?,?,?,?,?,?,?,?) DELETE FROM auth_centerdb.biz_user WHERE id = ? LIMIT 1 INSERT INTO auth_centerdb.user_update_record (id,global_id,old_value,new_value,type,client_id,ctime,creator,creator_str) VALUES (?,?,?,?,?,?,?,?,?)]”] [arguments=“[[133390683 7352147 6 57044843 0 1620969358041 1620977912711 0 0] [133370755] [2892313 7000000000008357128 7000000000008357128_6_57044843 7352147_6_57044843 12 iss_company 1620977912714 0 用户]]”] [error=“[code=10006:class=database:scope=not-set:level=high], Message: execute statement failed: commit, RawCause: Error 1062: Duplicate entry ‘57044843’ for key ‘uniq_biz_user_id’”]

这三条sql与研发沟通后,确认为包含在一个事务中,先delete掉一条数据,再insert两条数据。每天都会有执行,

DM2.0.1偶尔会报错:

“RawCause”: “Error 1062: Duplicate entry ‘57044843’ for key ‘uniq_biz_user_id’”

需要手动删除掉tidb中的duplicate数据,再resume才可以。

但是DM1.0.6却可以正常同步,dm-worker日志也没有任何ERROR和报警

奇怪的是在通过加了唯一索引的biz_user_id字段查询时,查不到该数据,通过id却可以查到。

如下:

(root@172.xx.xx.xx:)[xxxdb]> select * from biz_user where biz_user_id=57044843;
Empty set (0.00 sec)

(root@172.xx.xx.xx:)[xxxdb]> select * from biz_user where id=133390683;
±----------±----------±-------±------------±-------±--------------±--------------±--------±---------+
| id | global_id | biz_id | biz_user_id | status | ctime | mtime | creator | modifier |
±----------±----------±-------±------------±-------±--------------±--------------±--------±---------+
| 133390683 | 7352147 | 6 | 57044843 | 0 | 1620969358041 | 1620977912711 | 0 | 0 |
±----------±----------±-------±------------±-------±--------------±--------------±--------±---------+
1 row in set (0.00 sec)

表结构如下

CREATE TABLE biz_user (
id bigint(20) NOT NULL,
global_id bigint(20) NOT NULL,
biz_id bigint(20) NOT NULL ,
biz_user_id bigint(20) NOT NULL DEFAULT ‘0’ ,
status tinyint(2) NOT NULL DEFAULT ‘0’,
ctime bigint(20) NOT NULL DEFAULT ‘0’ ,
mtime bigint(20) NOT NULL DEFAULT ‘0’ ,
creator bigint(20) NOT NULL DEFAULT ‘0’ ,
modifier bigint(20) NOT NULL DEFAULT ‘0’ ,
PRIMARY KEY (id),
UNIQUE KEY uniq_biz_user_id (biz_user_id),
KEY gid_biz (global_id,biz_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出的打印结果,请务必全选并复制粘贴上传。

需要看一下具体的同步的 SQL 是显示提交自增 ID。DM同步中断报错-insert语句Duplicate entry - #10,来自 pangyana 参考一下类似的问答帖子。

但是1.0.6版本的DM就不会出现问题,新的2.0.1的DM就会报错。所以很纳闷

你这边同步工具版本以及下游 TiDB 版本均不一样,所以不能断定是 DM 同步过程中出现的问题,DM 2.0 和 1.0 以及 TiDB 3.0 和 4.0 都有比较大的变更,另外 3.0.3 版本默认是乐观事务,4.0 新集群默认是悲观事务。

如果方便的话是否可以在 4.0 TiDB 版本上开启 general log,另外确认下是什么阶段有主键冲突的。如果是 sync 阶段,直接恢复即可。

这个问题可以 admin check table 检查表上的数据与表上每一个索引是否一致

这张表有将近6000万,执行起来好慢

上面的问题怀疑是数据和索引不一致了,所以需要你这边确认下,方便的话重新开个帖子吧
主要排查方式

  • 1.确认两个 SQL 查询的执行计划
  • 2.通过 admin check table 再次确认下表数据和索引是否 一致

如果表的数据量比较大,可以 check 指定索引,可以认为是 admin check table 的子集:
admin check index ,详细参考下面的官网使用
https://docs.pingcap.com/zh/tidb/stable/sql-statement-admin-check-table-index#admin-check-tableindex

好的,我重新发一个帖子,非常感谢

:ok_hand: 辛苦~