TiDB的分布式事务原理探究

事务开启


获取全局授时作为startTS构建一个tikvTxn对象(包括snapshot)。

事务写


txn.Set方法本质上将kv值写入了一个内存缓存(即kv/memdb_buffer.go中的memDbBuffer)中。该内存kv数据库利用的是golevel提供的功能。

事务回滚


直接将tikvTxn的valid字段置为false,之后如果用户再执行提交或者回滚操作,会检查valid,如果为false则直接返回错误。

事务提交


操作映射

遍历kv数据库中所有的key,并将每个key和其操作组装到一起成为一个mutationEx对象,并且将其放到一个map中(map由key映射到mutationEx),最后将这个map放入twoPhaseCommitter的mutations字段。

操作也是通过key的内容推断出来的,推断逻辑如下:

  • key的长度为0,则操作为删除(Op_Del)
  • 如果key的长度大于0,且不需要延迟检查或者延迟检查不通过(value的当前长度大于0),则操作为Op_Put(即新增key或者更新key)
  • 如果key的长度大于0,且延迟检查(value的当前长度等于0)通过,则操作为Op_Insert(即新增key,不允许更新key)
  • 对于tikvTxn中的lockKeys字段中的key,如果他在kv数据库中不存在的话,则给予Op_Lock(即单纯的作为锁,事务结束就将这个key删除)

Prewrite

Percolator事务模型有primary和secondaries的概念,TiDB的实现中直接将第一个key作为Primary,剩下的Key全部作为secondaries

TiDB上的操作:

  • 将所有的key按照Region进行分组(从Region缓存或者PD中获取key所处的Region)
  • 将每组的key再拆分成Batch(每个Batch在16k作为,主要目的是为了缩小RPC packet的大小),并发地对每个batch进行处理(即给TiKV发送Prewrite指令)

注意:其实在Prewrite阶段的实现并不太能看出primary和secondaries的区别,他们都被一起打成batch并发处理了。

Tikv接收到指令之后对每个Batch分别进行Prewrite:

遍历batch中每个元素的mutationEx(之前操作映射时组装的),然后分别进行如下操作:

  • 如果操作是Op_Insert的话,则以事务开始时间startTs进行快照读检查key是否重复,如果重复则标记错误,看batch中下一个元素
  • 编码出一把锁(所谓“锁”就是指key的version为全0的64位bit,正常情况下是时间戳,所以锁永远排在第一个)
  • 检查是否有其他事务给该key上锁(即查看是否有version为全0的key),如果有则事务冲突
  • 上面的检查通过了的话,则查看Rocksdb上紧接着锁的下一个key(即最新的key),查看其时间戳是否大于等于startTs,如果这样的话,说明有其他事务先提交了,事务冲突。
  • 上面的检查也通过了的话则将自己的锁("锁"的信息包括startTs,primary,value以及操作码等等,详见store/mockstore/mocktikv/mvcc.go中的mvccLock结构)插入进去

Commit

TiDB中的逻辑:

  • 重新获得一个全局授时作为提交时间戳commitTs
  • Region分组,Batch拆分和上面是一样的
  • 先提交Primary
  • 然后在后台提交secondaries

TiKV中的逻辑:

新建一个Rocksdb的Batch进行批量的增删,然后对于每个key

  • 除了Op_Lock操作的Key,都以CommitTS作为Key的版本号插入进去,组装Value的时候将TiKV的操作码转成底层mvcc store的操作码(将Op_put转成typePut,剩下的除了不可能出现的Op_Lock,都转换成typeDelete),然后删除锁
  • 对于Op_Lock操作的Key则直接删除锁即可

End


作者:元青

微信公众号 「技乐书香」

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值