隔离性:为什么使用乐观协议的分布式数据库越来越少

98 阅读2分钟

并发控制技术的分类

分为悲观协议和乐观协议。

乐观锁:TiDB

运行过程:

  1. 选择 Primary Row

收集所有参与修改的行,从中随机选择一行,作为这个事务的 Primary Row,这一行是拥有锁的,称为 Primary Lock,而且这个锁会负责标记整个事务的完成状态。所有其他修改行也有锁,称为 Secondary Lock,都会保留指向 Primary Row 的指针。

  1. 写入阶段

按照两阶段提交的顺序,执行第一阶段。每个修改行都会执行上锁并执行“prewrite”,prewrite 就是将数据写入私有版本,其他事务不可见。注意这时候,每个修改行都可能碰到锁冲突的情况,如果冲突了,就终止事务,返回给 TiDB,那么整个事务也就终止了。如果所有修改行都顺利上锁,完成 prewrite,第一阶段结束。

  1. 提交阶段

这是两阶段提交的第二阶段,提交 Primary Row,也就是写入新版本的提交记录并清除 Primary Lock,如果顺利完成,那么这个事务整体也就完成了,反之就是失败。而 Secondary Rows 上的锁,则会交给异步线程根据 Primary Lock 的状态去清理

乐观协议的挑战

为啥乐观要改成悲观呢?主要是两方面的挑战,一是事务冲突少是使用乐观协议的前提,但这个前提是否普遍成立,二是现有应用系统使用的单体数据库多是悲观协议,兼容性上的挑战。

乐观协议的改变

TiDB 悲观锁的理论基础很简单,就是在原有的局部有效性确认前,增加一轮全局有效性确认。具体采用的方式就是增加了悲观锁,这个锁是实际存在的,表现为一个占位符,随着 SQL 的执行即时向存储系统(TiKV)发出,这样事务就可以在第一时间发现是否有其他事务与自己冲突。

image.png

因为增加了悲观锁的加锁动作,变回了一个可交互事务,TiDB 还要增加一个死锁检测机制。


此文章为6月Day14学习笔记,内容来源于极客时间《分布式数据库30讲》