关于tidb向pd申请tso和数据写入到region中的相关疑问

请教大家两个问题,在学习302课程中有点不解
1、课程中讲到了为了防止tidb server 申请tso时和Pd频繁的交互,pd会给每个tidb server分配一个3秒的时间段,给tidb server用。那假设server1向pd申请了1-3秒的tso时间,恰好刚申请完,在3秒的时间内,server2 也需要申请tso,pd会返回给server2 一个4-6秒的tso时间。因为两个tidb server的节点事务时间离的很近,但是申请的tso时间确很远,这样事务的时间顺序不就存在问题了么?
2、tidb 聚簇表自增主键使用auto_random来随机生成一个主键数字,已实现数据分布在不同region上,来降低热点分布。但是我理解数据的写入应该是在一个region上,顺序写入,比如一个表的update是在走最后增加一条数据,而不是修改原来的数据,这样的话,我理解数据写入的key有可能会出现无序的情况。那auto_random又是怎么实现数据分布来降低热点的呢,我懵了,可能我update和key顺序上也存在理解上的问题。
请大家帮忙解答解答

5 个赞

MVCC

很多数据库都会实现多版本并发控制 (MVCC),TiKV 也不例外。设想这样的场景:两个客户端同时去修改一个 Key 的 Value,如果没有数据的多版本控制,就需要对数据上锁,在分布式场景下,可能会带来性能以及死锁问题。TiKV 的 MVCC 实现是通过在 Key 后面添加版本号来实现,简单来说,没有 MVCC 之前,可以把 TiKV 看做这样的:

Key1 -> Value
Key2 -> Value
……
KeyN -> Value

有了 MVCC 之后,TiKV 的 Key 排列是这样的:

Key1_Version3 -> Value
Key1_Version2 -> Value
Key1_Version1 -> Value
……
Key2_Version4 -> Value
Key2_Version3 -> Value
Key2_Version2 -> Value
Key2_Version1 -> Value
……
KeyN_Version2 -> Value
KeyN_Version1 -> Value
……

注意,对于同一个 Key 的多个版本,版本号较大的会被放在前面,版本号小的会被放在后面(见 Key-Value 一节,Key 是有序的排列),这样当用户通过一个 Key + Version 来获取 Value 的时候,可以通过 Key 和 Version 构造出 MVCC 的 Key,也就是 Key_Version。这里的Version就是通过TSO构造

2 个赞

题主的问题1疑问就是在这里吧,以tso构造version的话,新的version有可能比老的还小

1 个赞

那是时钟回拨,实际上这个 version 只会越来越大,因为是单调递增,不太可能出现回拨的情况,除非人为。。。

1 个赞

如果题主问题1的描述是正确的,感觉通过tso构造version会有问题,求解惑,谢谢!

1 个赞

哪个啊,有几种优化方案,目前tidb 中已经在用了,
1秒中可以生成 多少亿个TSO ,我忘记了,具体的你可以在asktug上搜索。
这样子的生成效率能满足绝大部分的场景了;

然后处理方式:


最早一种是 batch 来获取 TSO
后面结合 future 的方式,异步来实现获取 TSO

最新的,你可以参考这个图:

最后可以参考下这个描述:

1 个赞

实际上这个 version 只会越来越大

1 个赞

谢谢,大概明白了,之前理解是有点问题,3秒的时间原来是pd提前分配一个时间窗口,来对tlast进行持久化,保存到etcd中的性能小号。
tidb server申请tso也是批量的,但是是更细粒度的。

tidb-server申请tso是批量的

1 个赞

会越来越大,时间越来越大

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