Tidb percolator事务模型
percolator事务模型是一个乐观锁事务模式,可执行并发修改,事务提交commit时检测写写冲突,提交采用二阶段提交:
TiDB 对于每个事务,会从涉及到改动的所有 Key 中选中一个作为当前事务的 Primary Key。 在最终提交时,以 Primary 提交是否成功作为整个事务是否执行成功的标识,从而保证了分布式事务的原子性。
有了Primary key后,事务两阶段提交过程如下:
- 从当前事务涉及改动的keys选中一个作为
primary key,剩余的则为secondary keys - 并行
prewrite所有keys。这个过程中,所有的key会在系统中留下指向primary key的锁 - 第二阶段提交时,首先
commit提交primary key,若此步成功,则说明当前事务提交成功 - 异步并行
commit secondary keys
一个读取过程如下:
- 读取 key 时,若发现没有冲突的锁,则返回对应值,结束。
- 若发现了锁,且当前锁对应的 key 为
primary: 若锁尚未超时,等待。若锁已超时,Rollback 它并获取上一版本信息返回,结束。 - 若发现了锁,且当前锁对应的
key为secondary, 则根据其锁里指定的primary找到primary所在信息,根据primary的状态决定当前事务是否提交成功,返回对应具体值
TIDB 事务处理流程

注意:所有涉及重新获取 tso 重启事务的两阶段提交的地方,会先检查当前事务是否可以满足重试条件:只有单条语句组成的事务才可以重新获取tso作为start_ts。
- client 向 tidb 发起开启事务 begin
- tidb 向 pd 获取 tso 作为当前事务的 start_ts
- client 向 tidb 执行以下请求:
读操作,从 tikv 读取版本 start_ts 对应具体数据.
写操作,写入 memory 中。 - client 向 tidb 发起 commit 提交事务请求
- tidb 开始两阶段提交。
- tidb 按照 region 对需要写的数据进行分组。
- tidb 开始 prewrite 操作:向所有涉及改动的 region 并发执行 prewrite 请求。若其中某个prewrite 失败,根据错误类型决定处理方式:
KeyIsLock:尝试 Resolve Lock 后,若成功,则重试当前 region 的 prewrite[步骤7]。否则,重新获取 tso 作为 start_ts 启动 2pc 提交(步骤5)。
WriteConfict 有其它事务在写当前 key, 重新获取 tso 作为 start_ts 启动 2pc 提交(步骤5)。
其它错误,向 client 返回失败。 - tidb 向 pd 获取 tso 作为当前事务的 commit_ts。
- tidb 开始 commit:tidb 向 primary 所在 region 发起 commit。 若 commit primary 失败,则先执行 rollback keys,然后根据错误判断是否重试:
LockNotExist 重新获取 tso 作为 start_ts 启动 2pc 提交(步骤5)。
其它错误,向 client 返回失败。 - tidb 向 tikv 异步并发向剩余 region 发起 commit。
- tidb 向 client 返回事务提交成功信息。
版权声明:本文为博主原创文章,未经博主允许不得转载。
- 上一篇:TiSpark 混合部署以及使用
- 下一篇:TiDB异步在线DDL变更流程原理简概



