悲观事务模式范围查询加锁的问题

【 TiDB 使用环境】测试
【 TiDB 版本】6.6
【复现路径】使用方式咨询。
【遇到的问题:问题现象及影响】在悲观事务RC级别下使用select * from t1 for update where…不指定主键查询时,是会给每一行查询到的数据加行锁吗。既然没有指定主键,又是如何加行锁的呢?谢谢。
【资源配置】
【附件:截图/日志/监控】

看这儿:https://docs.pingcap.com/zh/tidb/stable/dev-guide-transaction-restraints#自动提交的-select-for-update-语句不会等锁


不指定主键,会依据条件查到相应的主键,然后在进行加锁…
但是 tidb 加锁的处理,对于 select for update 比较特殊,和 mysql 已知的方式有点不同,所以推荐你看文档了…

:+1:我们也用了这种语法,但还真没深入研究过,我也学习学习

在没有指定主键的情况下执行的行锁可能导致性能问题,因为 TiDB 需要额外的开销来确定每一行的位置

意思是TIDB的处理是先找出每一行,然后再对找出来的每一行加锁吗。不指定主键查询是一个一致性快照,这样先查询再加锁好像会有一致性问题?

多语句事务。
先查主键再加锁,查询跟加锁间隙里修改的key就锁不住了。这个细节文档里没找到描述。。。

主要是通过事务来进行锁住的,你可以尝试一下

嗯,不指定主键就没办法先加锁再查询,先查询再加锁就没有锁住查询的结果,导致查询的结果不可靠。所以这里由一些疑问是怎么加锁的 :joy:

那就先拿到主键信息,在加锁不就好了…

不加锁拿到的主键信息不可靠,随时可能被其他事务增删。一般会先加锁拿主键判断条件,但是没有主键也没法加锁,所以这里比较疑惑具体的行为。。。

TIKV是基于rocksdb实现的,所以“增删”都是put追加的方式来实现。

  • 增加一行数据,直接put到文件的末尾
  • 删除一行数据,带上删除标记位,也是直接put到文件末尾,后面等系统按照key来compaction再合并压缩,GC回收空间

TiDB读取数据时永远都是读到最后被提交的数据,所以旧的数据是不会被读到的。

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