浅析 TiDB 二阶段提交
作者: tplinux 原文来源:https://tidb.net/blog/06549bb6
关键内容说明:
TiDB 对于每个事务,会涉及改动的所有 key 中,选择出一个作为当前事务的 Primary Key,其他的则为 Secondary keys。
当 Primary Key 提交成功,标识整个事务提交成功,否则失败。
Secondary keys,则是等 Primary Key 提交成功后,异步并行提。
pd 会产生全局唯一递增时间戳 tso
TiDB 二阶段提交简图
(图 1, 底图选用 tidb 官方)
细节描述
在图中④之前还有几部操作:
tidb 开始 prewrite 操作:向所有涉及改动的 region 并发执行 prewrite 请求,如果某个 prewrite 失败了。
如果报错为 keylslook 和 WriteConfict, 都会重新获取 tso,重新启动 2pc。其他错误则会报错。
2. 在 tidb 开始 commit 也就是图⑥的时候会执行,
tidb 向 primay 所在的 region 发起 commit。
如果失败 先执行回滚操作,然后根据错误判断是否重试:
lockNotEXist 重新获取 tso 作为 start_ts 启动 2pc 提交。
这几步操作,我简单描述一下 在 tidb 开始写 key 的操作,如果遇到锁相关的错误,都会进行一个重新获取 tso,重新启动 2pc 的提交。
TiKV 二阶段提交简图
(图 2, 底图选用 tidb 官方,图中的⑦应该是 TiKV 的准备操作)
TiDB 的二阶段提交,还应该包含 TiDB 对 TiKV 的二阶段提交,下面用问答的形式来简单说明一下。
问:那么什么时候 TiDB 会对 TiKV 发起二阶段提交?
答:在图 1 中⑥操作成功之后,TiDB 向客户端返回事务成功之前,TiDB 会对 TiKV 发起二阶段提交。
问: TiKV 在二阶段提交中如何保证 key 的一致性?
答:图 2 中的⑦就是 TiKV 准备的操作,先对被操作的 key 进行锁冲突检测,然后对被操作的 key 进行加锁的一个操作。
在图 2 中的 ③和④其实为了保证,key 已经在 TiKV 的准备工作中,已经被锁住。然后在内存中循环添加 key 的信息 write(key,start_ts,commit_ts) 写入一条,和删除锁住 key 的信息 lock(key,start_ts)。当数据没有问题 在写入底层的 raft-key 中,从而保证了一致性。
从此整个 TiDB 二阶段提交提交大体完成。
总结 ,在二阶段提交中
PD 提供:提供全局唯一递增时间戳 tso 发放。管理 raft-kv 集群
TiKV 提供:分布式 kv 存储引擎,提供了 mvcc 功能。可以读取到历史版本数据。
TiDB 提供:MySQL 协议的解析,相对 TiKV 而已 TiDB 是客户端。
参考文章:
https://andremouche.github.io/tidb/transaction_in_tidb.html
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/6127d6c15511a5e116273865c】。文章转载请联系作者。
评论