插入重复key,出现的日志打印

[2021/01/29 17:00:47.510 +08:00] [INFO] [2pc.go:807] [“prewrite encounters lock”] [lock=“key: []byte{0x62, 0x65, 0x66, 0x33, 0x33, 0x36, 0x66, 0x66, 0x2d, 0x65, 0x36, 0x38, 0x38, 0x2d, 0x66, 0x37, 0x35, 0x37, 0x2d, 0x36, 0x38, 0x35, 0x34, 0x2d, 0x31, 0x30, 0x61, 0x39, 0x61, 0x66, 0x65, 0x35, 0x37, 0x32, 0x35, 0x61}, primary: []byte{0x36, 0x64, 0x38, 0x31, 0x61, 0x35, 0x33, 0x30, 0x2d, 0x32, 0x35, 0x38, 0x63, 0x2d, 0x31, 0x35, 0x34, 0x65, 0x2d, 0x34, 0x38, 0x63, 0x30, 0x2d, 0x32, 0x31, 0x34, 0x61, 0x31, 0x63, 0x37, 0x37, 0x66, 0x62, 0x36, 0x31, 0x32}, txnStartTS: 422552757195243886, lockForUpdateTS:0, ttl: 3004, type: Put”]

如果不停的对一个key进行插入操作,就会有这个日志打印,但是看代码prewrite是同步的,为什么会出现这种现象呢?

如果不停的对一个key进行插入操作

能不能详细说下是怎么操作的呢?

就是不断地开启事务,在事务中set一个固定的key/value,然后commit

能否详细的描述下变更数据的逻辑?如果允许,可否提供相关的 sql 语句,以及表结构 ~~

不是用的sql语句,就是调用的tidb内嵌的go client,我会生成一个uuid作为key,value是固定的一个值,不断的去写入这个key

_key1 := uuid.New()
err := txn.Set(_key1, _val1)
_ = txn.Commit(context.Background())

tidb内嵌的 go client 并不适合当一个 KV 使用,里面有些特定的优化。如果需要使用 KV 接口,请使用 tikv 的 https://github.com/tikv/client-go。

关于锁的处理,可以看下这篇文章 https://andremouche.github.io/tidb/transaction_in_tidb.html, commit 后,锁不会立即清除。后续的写入会尝试去清锁。

之前用go client 出现过类似内存泄漏的问题,后来这边有人跟我说用tidb 的内嵌client。。。。

是否有可能某个事务失败了但是没有发现 (漏写 if err != nil)

这个看起来没有,可能就是类似于上面说的commit不会立即清除锁

大概插入多少个key会出现锁呢?

对一个key的下一次插入操作就会出现这个锁

可能commit失败了,有判断commit结果吗

看代码来说,应该没有失败,
msBeforeExpired, err := c.store.lockResolver.resolveLocksForWrite(bo, c.startTS, locks)
看起来这里会释放锁,然后继续执行,只是不明白,为什么上一次提交后没有释放锁

方便上传一下复现demo吗?