悲观事务&&RC 隔离级别下,快照读 select 请求,可能会调用 TIKV 哪些接口?

为了更好的理解 TIDB 的悲观锁,我在本地启动了一个 TIDB 的服务,TIKV 是我特意打了日志的程序。

使用 Mysql 客户端对 tidb 调整事务隔离级别为 RC,

并且开启悲观事务,执行 Select 请求。

请求的同时观察 TIVK 的日志请求,发现一个比较奇怪的地方:

  • select 快照读请求后,完全无法看到 tikv 的 RC 或者 RcCheckTs 隔离级别参数的请求
  • 甚至 select 请求并不会调用到 TIKV 接口即可返回数据

目前猜测是否是 TIDB 有一些优化,可以减少与 TIKV 的交互,但是可以达到 RC 的隔离级别。

或者还是我的日志打印位置有误,导致没有看到相应日志?
有没有什么手段可以调整日志级别,可以直接看到 TIKV 的请求日志?

这个和 kv 的 api 有关系,我觉得你最好去整体的学习下课程…
https://learn.pingcap.com/learner/home

kv 获取数据的 api 有两种:

  1. 点查,pointGet and batchPointGet
  2. 条件查询 DistSQL (支持下推和不支持下推)…

可能你找的地方不对,因为数据结构的映射,会导致取数采用不同的方式来调度执行…
https://docs.pingcap.com/zh/tidb/stable/tidb-best-practices#sql-on-kv

你应该学习过课程,能否请教一下,tidb 是否可能有一层缓存数据,可以直接处理 RC 级别的 select 快照读请求,而不需要发送 rpc 给 tikv 呢?

当然,会有缓存了,Mysql 也是如此…

tidb 级别的缓存,tikv 级别的缓存,缓存的模式和处理方式也不一样…

时候缓存内容导致的看不到

确认下应用缓存;另外可以看下tidb层的coprocessor缓存是否被读取。

通过 debug TIDB 和 TIKV 的代码发现:

  • select * from managers where first_name=‘brad8’; 语句未能命中索引,因此没有使用 tidb 的 pointget 而是 coprocessor。因此调用的 tikv 接口不是 batchget 而是 coprocessor

  • TIDB 即使对于 RC 级别的快照读,也会对 TIKV 使用 SI 隔离级别的 get/coprocessor 请求。对此, TIKV 的代码特意针对 SI 级别的快照读进行特殊判断,不检测悲观锁的锁冲突,用于防止 select 快照读请求被其他悲观事务阻塞 (例如有其他事务在执行 select for update/update/delete):

  • 即使 RC 级别的事务,TIKV 也是会去 LOCK CF 获取锁信息的,虽然读出来悲观锁后,会跳过,这样做应该是为了保障悲观锁乐观锁同时存在的场景,防止 RC 级别的事务读取不到乐观锁新提交的事务。如果 RC 级别的快照读遇到乐观锁,那么也会返回锁冲突然后进行等锁、重试。

@gcworkerishungry @lemonade010
多谢大家的回复

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