架构情况:
3 tidb + 3 tikv + 3 pd +1 ticdc
上游 tidb v5.0.2
下游 mysql 5.7.25
cdc 任务创建语句:
tiup ctl:v5.0.2 cdc changefeed update --pd=http://XXX:2379 --sink-uri="mysql://user:password@172.26.55.21:3306/?time-zone=&safe-mode=false" --changefeed-id="dev-task6"
cdc 同步报错:
日志报错:
找到 region_id 信息:
上游 tidb 查询这条数据:
下游 mysql 查询这条数据:
下游 MySQL 其实没有数据,为什么还有报重复键的错。
这个情况已经出现几次了,这次把相关信息都贴上来了,如果还需要其他信息,我这边再提供下。麻烦大佬帮忙看下,谢谢!
2 个赞
不懂就问
(zhouyueyue)
2
请问下 这里使用 safe-mode=false 是基于什么需求?当前不建议设置 safe-mode=false
1 个赞
主要是因为我们有很多应用在用canal,需要去下游 mysql 取 binlog。不指定 safe_mode=false 会导致 sql 逻辑发生变化,这样 canal 取到的 binlog 会和上游不一致。
liuzix
(Liuzix (PingCAP))
4
TiCDC 现在有 experimental feature 可以直接输出 canal 格式到 kafka, 您可以评估一下能否解决您的问题。
1 个赞
不行,下游 mysql 除了让 canal 取 binlog 外,还需要承担刷数据的任务。
是这样的,我们 canal 取完 binlog 后,会投递到 rocketmq ,然后处理后存入其他异构数据库,有时候异构数据库的数据需要重新加载,我们会去下游 mysql 里刷新数据,这样数据通过 canal 重新流入异构数据库,而且不会影响到上游 tidb。
spc_monkey
(carry@pingcap.com)
6
咱们是想知道 报主键冲突错误的原因是吧,麻烦把 cdc 版本及配置告诉一下
spc_monkey
(carry@pingcap.com)
8
1、cdc 中断这么久,估计只能重新搭建了
2、能否提供一下下游 mysql 这个表的表结构
之前同步了好多次,每次报重复键的表都不一样的。
我重新 dumpling + myloader 搭下数据库,再开个新的 cdc 任务,这次把情况同步给你们把。
spc_monkey
(carry@pingcap.com)
10
可以先给我一下 表结构(可以脱敏,我主要想看索引情况),其实排查咱们这个问题,主要从 1、具体执行的 SQL 语句(批量/或不同语句类型,都是关注的因素)2、锁相关。所以我想看表结构(如果可以的话,可以通过 下游 mysql 日志,找一下相关SQL语句)
HHHHHHULK
(好好学习,天天向上)
11
1. 表结构:
CREATE TABLE gw_trans_content
(
id
int(11) unsigned NOT NULL AUTO_INCREMENT,
order_id
varchar(32) COLLATE utf8_bin DEFAULT NULL ,
channel_system_id
varchar(32) COLLATE utf8_bin NOT NULL,
exchange_type_id
varchar(10) COLLATE utf8_bin NOT NULL,
msg_type
varchar(10) COLLATE utf8_bin DEFAULT NULL ,
extend_id
varchar(32) COLLATE utf8_bin NOT NULL,
class_name
varchar(200) COLLATE utf8_bin DEFAULT NULL ,
trans_content
mediumtext COLLATE utf8_bin ,
trans_content1
mediumtext COLLATE utf8_bin ,
latest_status
varchar(6) COLLATE utf8_bin DEFAULT NULL ,
return_content
varchar(4000) COLLATE utf8_bin DEFAULT NULL
return_content1
varchar(4000) COLLATE utf8_bin DEFAULT NULL ,
rsp_code
varchar(12) COLLATE utf8_bin DEFAULT NULL,
rsp_msg
varchar(200) COLLATE utf8_bin DEFAULT NULL,
memo
varchar(500) COLLATE utf8_bin DEFAULT NULL ,
create_time
datetime NOT NULL ,
modified_time
datetime DEFAULT NULL,
query_time
datetime DEFAULT NULL,
PRIMARY KEY (id
),
UNIQUE KEY uniq_gw_trans_content_1
(extend_id
,channel_system_id
,exchange_type_id
),
KEY idx_gw_trans_content_1
(create_time
),
KEY idx_gw_trans_content_2
(order_id
),
KEY idx_gw_trans_status_create_time
(create_time
),
KEY idx_gw_trans_status_oidsn
(order_id
)
) ENGINE=InnoDB AUTO_INCREMENT=12540448 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
2. 相关 sql
因为下游mysql,没有同步到这条数据,所以没有相关的 binlog。但是在查看下游 mysql binlog 的时候,发现了比较奇怪的现象。
上游 tidb 我们业务代码实现的是:
begin -> insert into t (id) value (1) -> commit
begin -> update t set where id =1 -> commit
下游 binlog 输出的是:
begin -> insert into t (id) value (1) -> update t set where id =1 -> commit
检查过代码,没有把 insert 和 update 放在一个事务里的逻辑。
spc_monkey
(carry@pingcap.com)
12
2 的问题,可以忽略,cdc 是最终一致性(不会影响数据准确性的)
spc_monkey
(carry@pingcap.com)
13
问一下,下游 mysql 方便开启 general log 吗(可以在报错时,开启一小段时间,想看看具体的 SQL 语句,不然不太好排查)
HHHHHHULK
(好好学习,天天向上)
14
general log 打开了,刚刚报重复键错误了,这边排查的话需要哪些信息,我一起发给你
spc_monkey
(carry@pingcap.com)
15
1、下游表无此主键对应的数据
2、mysql 报错时的日志(general log 会有记录)
HHHHHHULK
(好好学习,天天向上)
16
我确认下这个数据怎么定位的,是去 cdc log 找到这条报错,然后网上找最近的一个 region_id ,然后通过命令 curl http://172.26.xxx.xxx:10080/regions/$region_id
,去定位吗?
spc_monkey
(carry@pingcap.com)
17
看mysql 的,不是tidb 的(主键冲突发生在下游 mysql 吧)
spc_monkey
(carry@pingcap.com)
18
@HHHHHHULK 我看你给的 日志中,并没有报错啊(开启完 mysql general log 之后,需要再启动一下 cdc,让他报主键冲突报错)(其实我想抓到 下游报错的 具体 SQL,所以需要在报主键冲突错误之前,就开启 general log)
HHHHHHULK
(好好学习,天天向上)
19
general log 昨天就开了,文件太大,我把前面没用的都截掉了
spc_monkey
(carry@pingcap.com)
20
,奇怪的是我没有找到报错相关的信息啊(grep -i error log 没有发现有报错啊,1062 错误代码也没有啊)