br 迁移 tidb后,写入数据一直报for key 'PRIMARY'

【概述】 场景 + 问题概述
订单数据
br 迁移v5.4.0集群的一个库到 新集群v5.4.1
全量和增量迁移完成,业务流量切换,数据写入大批量报for key ‘PRIMARY’
tidb 后台一直刷for key ‘PRIMARY’
[tikv:1205]Lock wait timeout exceeded; try restarting transaction"]

日志如下:
image

监控


image

表结构:
CREATE TABLE item_trace (
id bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(4) */,
api_type varchar(20) NOT NULL DEFAULT ‘sp’,
asid bigint(20) unsigned NOT NULL DEFAULT ‘0’,
seller_id varchar(100) NOT NULL DEFAULT ‘’,
marketplace_id varchar(50) NOT NULL DEFAULT ‘’,
region char(2) NOT NULL DEFAULT ‘’ COMMENT ‘’,
amazon_order_id varchar(50) NOT NULL DEFAULT ‘’ COMMENT ‘’,
order_last_update_time int(10) NOT NULL DEFAULT ‘0’ COMMENT ‘’,
purchase_date int(10) NOT NULL DEFAULT ‘0’ COMMENT ‘’,
fulfillment_channel varchar(100) NOT NULL DEFAULT ‘’,
sales_channel varchar(100) NOT NULL DEFAULT ‘’,
next_sync_time int(10) NOT NULL DEFAULT ‘0’,
next_token varchar(2500) NOT NULL DEFAULT ‘’,
gmt_modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘数据更新时间’,
gmt_create timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘数据创建时间’,
timezone varchar(20) NOT NULL COMMENT ‘时区’,
PRIMARY KEY (id) /*T![clustered_index] CLUSTERED */,
UNIQUE KEY uk-order-id (seller_id,marketplace_id,amazon_order_id),
KEY idx_update_time (id,order_last_update_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![auto_rand_base] AUTO_RANDOM_BASE=403971164 */
问题点:
业务切换后,流量已经路由到新的集群。
批量写入的时候,所有服务的insert 语句都没有显示指定主键id,但是insert 都报主键id冲突。
是否是v5.4.0 数据迁移到v5.4.1 会出现未显示指定下报主键id错误。

【现象】 业务和数据库现象
业务当时写入流量非常大
后续切换回原来的v5.4.0 没有发生 for key ‘PRIMARY’ 错误。

【业务影响】
数据写入失败 导致大量事务超时。
数据延迟增加

【TiDB 版本】
v5.4.1

主键用的什么方式呢?聚簇索引?

嗯是 clustered_index

直接批量插入,不通过CDC同步,也是 这个错误么?

这个表结构是怎么样的? 能放上来不

cdc 同步太慢延迟几个小时
checkpoint一直不推进

这是另外一个问题了… :joy:

你在另外开个帖子吧,说清楚背景和一些现象,最好把关键日志也贴上

表结构已经更新上去了。

UNIQUE KEY uk-order-id ( seller_id , marketplace_id , amazon_order_id ),

可以看看,是不是这个唯一键有冲突

primary key 如果是 auto_random ,冲突没可能的…

如果是唯一建冲突,报的错误因该是 for key ‘uk-order-id’
br数据导入后,是不是要刷一遍 auto_random的值,以确保后面insert的数据id是大于现在的max id的。

auto_random 是雪花算法的加强版,即使 NTP 出现问题,也不会导致冲突的

我在导入数据后 查了这个表存量数据的max_id 是8646911284956014231
后面手工插入一批数据生成的max_id 是,5764607523438206044
后面写入的数据id 小于之前存量数据的最大id,有没有可能后面生成的id会和存量数据的id造成重复。

我还是建议 NTP 要设定一致,减少这种可能性

高位调换,就是为了打散,解决热点写入的问题

节点之间NTP是一致的

那没啥问题的~ :grinning:

br 迁移v5.4.0集群的一个库到 新集群v5.4.1
全量和增量迁移完成,业务流量切换,数据写入大批量报for key ‘PRIMARY’
tidb 后台一直刷for key ‘PRIMARY’

在全量恢复完成后,增量恢复前,有写过新集群吗?如果写过的话,会导致下游集群的状态改变,不能在它上面进行增量恢复,因为新的写入可能用了和增量中相同的 primary id,导致后续插入出现冲突。

请问下 br 用的是什么版本,看起来像是一个已知的 bug,br 在增量恢复后,没有刷新 auto random base. https://github.com/pingcap/tidb/issues/33596 这个问题在 br v5.4.1 之后修复了

一般都是下游表存在这个key,我这边也会出现,不清楚为什么存在

增量前新集群没有写入过数据的

br版本是v5.4.0
Release Version: v5.4.0
Git Commit Hash: 55f3b24c1c9f506bd652ef1d162283541e428872
Git Branch: heads/refs/tags/v5.4.0
Go Version: go1.16.4
UTC Build Time: 2022-01-25 08:36:34
Race Enabled: false