lazzyfu
(Lazzyfu)
1
TiDB版本
Server version: 5.7.25-TiDB-v4.0.7
多库
问题描述
历史库数据删除
库:yotrace
操作:
我们有一张80亿+的表,需要对历史数据进行删除,删除约50亿
使用工具:
pt-archiver --no-version-check --source xxx --charset utf8 --purge --bulk-delete --progress 1000 --txn-size 100 --limit 10000 --where="id < 6000000000"
当执行pt-archive批量删除tidb历史大表数据时,整个集群的tikv的平均负载在300%左右(每台tikv为8核心)
然后诡异的事情出现了
业务库:stat
业务侧的程序偶尔开始报 Error 1062: Duplicate entry
排查业务侧脚本和代码,并无异常,数据库也确实不存在重复的数据。
TiKV负载
出现问题的是唯一索引,该唯一索引是由三个字段组成
Duplicate entry ‘20211030-yiyun73-04892694’ for key ‘UNIQ_BKR_DLR_D’
测试复现
测试业务逻辑很简单
复现问题
批量删除1000条数据,然后在insert在这1000条数据,多次执行脚本,比如执行3次,就有一次脚本会偶尔报Error 1062: Duplicate entry
关闭删除脚本,将tikv压力降低
当我关闭pt-archive脚本时,再次批量删除1000条数据,然后在insert在这1000条数据,多次执行脚本,不在出现Error 1062: Duplicate entry
疑问?
- 不清楚为什么会发生这种情况,这个并没有涉及到DM同步等。查阅asktug也并没有此类问题的描述。
- tikv是异步提交?还是负载高,导致提交慢了,导致insert时,判断数据存在?
spc_monkey
(carry@pingcap.com)
2
你可以利用 mvcc 或 snapshot 参数,看看这个值,什么时候删除,什么时候 插入的
lazzyfu
(Lazzyfu)
3
您好,我理解您说的,我的测试很简单
代码串行依次执行删除、删除返回ok,在执行insert操作,此时insert报错
首先我不太会定位这些,即使定位底层delete后执行完成,那也就说明insert先于delete提交了。可是正常逻辑不是delete先提交的?我才提交的insert操作。难道tikv底层不是这样的逻辑?
lazzyfu
(Lazzyfu)
4
现在的现象于我而言是insert操作先于delete提交了,触发了Error 1062: Duplicate entry
我代码就是很简单的逻辑,串行执行
_, err = db.Exec(deleteSQL)
if err != nil {
fmt.Println(err.Error())
}
_, err = db.Exec(insertSQL)
if err != nil {
fmt.Println(err.Error())
}
实际结果,给我的映象是insert先提交了。不知道tikv底层是异步提交还是什么机制,会不会真实发生insert先于delete提交呢。谢谢
spc_monkey
(carry@pingcap.com)
5
这个看程序应该是不会的,无论是 乐观模式还是悲观模式,都是先拿 tso 的,建议你看 tidb-server 的日志(或直接开 general)
system
(system)
关闭
6
此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。