v5.3.0中使用ticdc同步执行replace语句的差异

【 TiDB 使用环境】生产
【 TiDB 版本】v5.3.0
【复现路径】使用ticdc同步数据到kafka,当执行replace语句时,如果对应的数据不存在会同步出去insert事件的数据,如果对应的数据存在则先同步delete事件数据再同步insert事件数据。
但是使用v4.0.16和v6.5.0则不是该策略,使用这两个版本时,执行replace语句,如果对应数据不存在同步出去insert事件的数据,如果对应的数据存在则同步update事件的语句。
协议都是使用的TiCDC Open Protocol
请问:造成该差异的原因是v5.3.0的bug么?还是该版本专有的策略,需要修改相关配置么?经过测试v5.4.3也有相关问题。
【遇到的问题:问题现象及影响】
【资源配置】
【附件:截图/日志/监控】

没环境,不好测试,感觉像彩蛋

嗯嗯,还有更大的彩蛋,我们测试部部署的v6.5.0使用的是单机版的部署方式,我现在测试是部署的一个简单的集群。使用相同库名,相同表结构,相同kafka版本,创建changefeed使用相同的toml配置文件结果出来的结果不一样。 :sweat_smile:结果如下:
单机版:执行replace语句数据不存在会同步出去insert事件的数据,如果对应的数据存在则同步update事件数据。
简单集群:执行replace语句数据不存在会同步出去insert事件的数据,如果对应的数据存在则先同步delete事件数据再同步insert事件数据。
找了好多遍没找到啥原因。

4.0.16和6.5.0是更新的版本,做法也更好。

老版本,先delete再insert 高并发的情况下会有死锁的。

https://github.com/pingcap/tiflow/issues/3589

注意上面的连接中有如下表述:

* Run sql statements in two transactions:
T1: begin;
T2: begin;
T1: delete from test.order_line where ol_o_id=7220 and ol_d_id=4 and ol_w_id=68 and ol_number = 7;
T2: delete from test.order_line where ol_o_id=7221 and ol_d_id=2 and ol_w_id=58 and ol_number = 4;
T1: REPLACE INTO test.order_line(ol_o_id,ol_d_id,ol_w_id,ol_number,ol_i_id,ol_supply_w_id,ol_delivery_d,ol_quantity,ol_amount,ol_dist_info) VALUES (7219,2,58,4,52661,58,'2021-11-13 02:38:33',5,'185.65',_binary'ZFQZYPNYPLZHNNBWPEIWTSPS');
T2: REPLACE INTO test.order_line(ol_o_id,ol_d_id,ol_w_id,ol_number,ol_i_id,ol_supply_w_id,ol_delivery_d,ol_quantity,ol_amount,ol_dist_info) VALUES (7218,4,58,1,23862,58,'2021-11-13 02:38:33',7,'408.94',_binary'QTCLICHWFMNOODRLLIBOOTUQ');
* At this time, we get error from T2:
Deadlock found when trying to get lock; try restarting transaction

2. Why does this happen?

* In RR isolation level, a gap lock is taken when we delete a nonexistent record. Because two gap locks in two transactions on the same gap don't block each other, so the two delete statements can successfully executed. (Reference [gap lock](https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-gap-locks))
* `REPLACE INTO` statement in T1 tries to insert a record and it tries to take an insert intention lock. And because a gap lock is taken by T2, this `REPLACE INTO` statement is blocked.
* `REPLACE INTO` statement in T2 also tries to insert a record into the same gap as T1, and it also waits to obtain an insert intention lock.
* Circular waiting happens and dead lock occurs.

用新不用旧就好了。

嗯嗯,现在是集群环境下的v6.5.0还是包括delete的语句,单机环境部不包含delete语句。 :rofl:请看我得回复说明。

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。