关于1PC的一点疑问

https://pingcap.com/zh/blog/async-commit-principle

在上面这篇介绍Async Commit的文章中,提到1PC时有如下说明:
如果一个事务只更新一条记录的非唯一索引,或是只插入一条没有二级索引的记录,它只会涉及到单个 Region。 这里提到只涉及到一个Region的事务有2种情况。

对于情况1,一般是包含什么SQL的事务会只更新一条记录的非唯一索引?
对于情况2,如果是聚簇表到可以理解,如果是非聚簇表,每行是有2对KV的,那如何保证这2个KV是位于同一个Region中的?
Key: tablePrefix{TableID}_recordPrefixSep{_tidb_rowid}
Value: [col1, col2, col3, col4]
Key: tablePrefix{tableID}_indexPrefixSep{indexID}_indexedColumnsValue
Value: _tidb_rowid

除了文章中提到到这2种情况以外,还有没有其它类型的事务只会涉及到单个Region?

别沉了

1pc 是对异步提交特殊情况的进一步优化:

  • 当更改的 entries(keys)全部落在一个 region 上
  • prewrite 只需要一次 rpc (如果单个 region 上 entries 数量过大,会分为多次 rpc )

总结一下就是只涉及一个 region,prewrite 只需要一个 rpc,不用分布式提交。

所以满足 1pc 提交的事务是:更改的 entries 不要太多,并且这些 entries 只落在一个 region 上。

所以对于你提的问题,博客上的文档以现在的功能特性看,现在看描述的可能不那么准确,毕竟那个时候好像还没有聚簇表的概念。

嗯嗯,那在TiDB中没有聚簇表的概念之前,1行记录是1对还是2对KV呢?

跟表结构有关,有多少个 entry(kv)没必要跟聚簇表的概念分开说,根据表结构定义以及索引数:

假设表中有 N 个索引(包括主键),如果是聚簇表,那么 kv entry 个数是 N;

如果是非聚簇表,kv entry 个数是 N + 1,相对于聚簇表,会多一个。

原来就是如果有非 NULL 的长整形的唯一索引,那么就不再生成 rowId,就用这个列作为 record 记录的 key 编码就行了。

明白你的意思了。以前是根据表是否存在int pk来自动选择是否聚簇的,现在可以在建表的时候指定是否聚簇了
回到这个问题,什么样的事务只会更新一条记录的非唯一索引呢

判断1pc: 总结一下就是只涉及一个 region,prewrite 只需要一个 rpc,不用分布式提交。

关于 ky entry 上面也说了。

至于说 “什么样的事务只会更新一条记录的非唯一索引呢” ,还真是很难想出来这种情况,我觉得用 “更新一条记录的非索引列” 更合适。原文是用这个描述 1pc 的场景,我觉得理解了 1pc 场景,以及行记录的 kv 生成条数就行了,没必要纠结这句话。

感觉是像是写错了

嗯,我也是这么感觉的。

你提到的"更新一条记录的非索引列"也是一种情况,不纠结:+1:

此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。