DM同步中断报错-insert语句Duplicate entry

为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。

  • 【TiDB 版本】:4.0.1
  • 【问题描述】:

DM同步报错
“subTaskStatus”: [
{
“name”: “task_trade”,
“stage”: “Paused”,
“unit”: “Sync”,
“result”: {
“isCanceled”: false,
“errors”: [
{
“Type”: “ExecSQL”,
“msg”: “”,
“error”: {
“ErrCode”: 10006,
“ErrClass”: 1,
“ErrScope”: 0,
“ErrLevel”: 3,
“Message”: “execute statement failed: INSERT INTO 库名.表名(id,op_id,bu_id,order_id,op_no_pay,op_order_id,op_num_sys,out_trade_no,op_time,inuse,pay_type,bulk_pay_type,remark,user_type,order_type,pay_amount,pay_rate_fee,shop_id,create_time,edit_time) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?): Error 1062: Duplicate entry ‘494f9d65df89447d9f426ae3eda87bb0’ for key ‘uk_op_id’”,
“RawCause”: “Error 1062: Duplicate entry ‘494f9d65df89447d9f426ae3eda87bb0’ for key ‘uk_op_id’”
}
},
{
“Type”: “ExecSQL”,
“msg”: “”,
“error”: {
“ErrCode”: 10006,
“ErrClass”: 1,
“ErrScope”: 0,
“ErrLevel”: 3,
“Message”: “execute statement failed: begin: sql: connection is already closed”,
“RawCause”: “sql: connection is already closed”
}
},
{
“Type”: “ExecSQL”,
“msg”: “”,
“error”: {
“ErrCode”: 10006,
“ErrClass”: 1,
“ErrScope”: 0,
“ErrLevel”: 3,
“Message”: “execute statement failed: begin: sql: connection is already closed”,
“RawCause”: “sql: connection is already closed”
}
},

最近出现了好几次,重启后解决

  1. 重启是因为在一段时间内,DM 使用了 sql_mode 为 replace into 模式,可以插入重复值。
  2. 请检查下,这个表对应的值应该是主键,但是要插入重复值,所以报错了,可以检查业务是否有重复数据插入,多谢。

主库用的是 INSERT ignore INTO来插入数据

那这样确实有可能会有重复主键呀,您看下dm文档里的safe_mode 开启后,可以达到replace into 的效果,这样和上游比较一致

replace into 是遇到有重复的 会替换掉,我这个是要ignore,不进行操作

您好,确认了下, ignore 会被忽略,不会记入binlog,所以 DM 不会同步。还是需要检查下上游这两个重复的记录

这边测试使用 inssert ignore into 下游是不会出现报错的。看 query-status 抓到的是 insert into,辛苦在确认下。
replace into 也不会出现上面的报错,看是已经过了 safe mode 阶段,辛苦从上游数据源确认该语句是否合法。


我们上游是阿里云RDS,从sql执行日志确认了,我们昨天对于这个表 这个唯一建的插入操作只有一条。就是这个insert ignore。然后也咨询了研发同学,他们反馈这个插入操作应该不会重复执行。

辛苦确定下上游这条记录是否已经插入成功(不是执行成功),insert ignore into,如果出现冲突将不会真正执行插入操作,反之同步到下游 tidb 将不会出现重复键值的问题。
再确认下是否有其他数据源在 tidb 同步数据

1、直接查询数据库这条记录可以发现,确实是该条sql已经插入成功,里面的插入时间与sql执行日志里的执行时间一致。

2、再确认下是否有其他数据源在 tidb 同步数据
这个tidb是用作多主一从的,所以有其他数据源同步数据,但是 没有合并操作,都是库与库一对一操作的

如果 ignore 插入了,就是正常的 insert 语句,这边还是建议查一下下游数据是否有重复。

可再看下 tidb 中 已存在 sql 是否与上游表记录相同,或者可以针对这个 task 开启 safe mode 同步一段时间在关闭,后续在观察是否会出现重复键值的问题,开启 safe mode 对 insert ignore 没有影响哈。

tidb中的这条记录 与上游表记录是相同的。
那我再观察下吧

尝试进行一下数据校验吧 sync diff,不行就开启safe mode跑一段时间,刷一下数据。