TiDB 内核解剖室SECTION 03

跨三个 TiKV 的一次转账,凭什么"要么全成、要么全不成"

1024 TiDB AIGC 黑客松 · 参赛作品 v0.3
CLIENT转账:A → B,100
→
TiDB事务协调者
⇢
PD / TSO分配全局时间戳
TiDB 事务私有内存 —— 写请求缓存(校验通过后先放这里,尚未落到 TiKV)
当前步骤
时间戳与事务状态
START_TS
—
COMMIT_TS
—
PREWRITE 应答
0 / 3
事务状态
未开始
破坏性演示

让另一个事务 T2 抢先提交、改掉同一个 Key,然后看 T1 走到 prewrite 时会发生什么。

口径与参数来源(已核验 · 2026-09-16 · TiDB 官方文档 stable 线 / release-8.5)
· 本台严格按官方《TiDB 乐观事务模型》给出的两阶段提交流程(官方 7 步)呈现,第一阶段为 prewrite、第二阶段为 commit:TiDB 从 PD 取 start_ts(同时作为 MVCC 快照版本)→ 读请求 → 写请求先存入该事务的私有内存 → 选出一个 Key 作为 Primary Key → 并发向所有涉及的 TiKV 发 prewrite(TiKV 检查版本冲突或过期,通过者被加锁)→ 收到全部 prewrite 成功响应 → 向 PD 取 commit_ts → 向 Primary Key 所在 TiKV 发起 commit 并清理 prewrite 留下的锁 → 返回成功,随后异步清理遗留锁信息。
· 冲突检测的位置:官方原文——"TiDB 在内存中的冲突检测是在 TiKV 中进行,主要发生在 prewrite 阶段"。本台"T2 抢先提交"演示正是让冲突在 prewrite 处暴露。
· 关于事务模式的说明:官方明确自 v3.0.8 起 TiDB 集群默认使用悲观事务模式(仅新建集群;从 3.0.7 及之前升级的集群不改变默认模式),悲观事务在执行写语句时即加锁,提交时一般不会出现异常。本台的冲突分支演示的是乐观事务模式下的写写冲突;且官方明确从 v8.0.0 起不再支持乐观事务自动重试,冲突需由应用捕获错误后重试。
· 事务规格:scheduler-concurrency 默认 2048000(scheduler 内置内存锁,防止同时操作同一个 Key);单事务大小上限 100 MB(txn-total-size-limit,最大支持 1 TB);单行上限 6 MB;单事务键值对数量限制自 v4.0 起取消。
· 画面中的 start_ts = 100 / commit_ts = 200 为示意编号,真实环境中是 PD 分配的全局唯一递增 TSO,并非从 1 开始计数。
· 本台只呈现"值 + 锁标记",不呈现底层列族级数据布局——官方事务文档正文未展开该层级,社区博客中的列族命名不作为本作品的表述依据。
· Async Commit 与 1PC 的默认值官方未列明,故本台只写"存在该优化",不写默认值。
· 来源:TiDB 乐观事务模型、TiDB 事务概览(docs.pingcap.com/zh/tidb/stable)。

以上带虚线的条目均可点击,查看官方原文、适用版本与文档链接 —— 琥珀色虚线表示"官方未列明,因此本作品一个字都不写"。