这个问题是 TiCDC 当前行分发规则是按 pk/uk 值不同分发到不同线程导致的。死锁的易出现原因是:TiCDC 为了实现 exactly one 语义将 update 拆成了 delete + replace into,导致 MySQL 在 RC 和 RR 隔离级别下都极易出现重合的 gap lock,导致了死锁。
临时措施:
(1)https://docs.pingcap.com/zh/tidb/stable/manage-ticdc/#sink-uri-配置-mysqltidb ,将 Mysql Sink 的 worker-count 调整成1;(会影响并发,不过考虑到本来就有比较多的死锁,所以还可以接受)
(2)需要下游 MySQL 临时去掉 uk,减少 gap lock;(不影响并发,但业务要自己评估去掉 uk 对查询的影响)
TiCDC 改进方案(ongoing (1)(2) ):
(1) 将和 MySQL 的连接隔离级别调整 rc;
(2) 支持用户自定义的表级分发规则;
(3) 更长远的是:重构 exactly-one 方案,避免分拆 update