auto_random如何保证全集唯一性呢

mysql> CREATE TABLE t (a bigint AUTO_RANDOM, b varchar(255), PRIMARY KEY (a))
-> ;
Query OK, 0 rows affected, 1 warning (1.02 sec)

mysql> insert into t (b) values(‘1’);
Query OK, 1 row affected (0.02 sec)

mysql> insert into t (b) values(‘2’);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t (b) values(‘3’);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t (b) values(‘4’);
Query OK, 1 row affected (0.01 sec)

mysql> insert into t (b) values(‘5’);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
±--------------------±-----+
| a | b |
±--------------------±-----+
| 2305843009213693957 | 5 |
| 2882303761517117442 | 2 |
| 5188146770730811393 | 1 |
| 5188146770730811396 | 4 |
| 7493989779944505347 | 3 |
±--------------------±-----+
5 rows in set (0.00 sec)

mysql> insert into t (b) values(‘6’);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t (b) values(‘7’);
Query OK, 1 row affected (0.01 sec)

mysql> insert into t (b) values(‘8’);
Query OK, 1 row affected (0.01 sec)

mysql> select * from t;
±--------------------±-----+
| a | b |
±--------------------±-----+
| 2017612633061982216 | 8 |
| 2305843009213693957 | 5 |
| 2882303761517117442 | 2 |
| 3458764513820540935 | 7 |
| 5188146770730811393 | 1 |
| 5188146770730811396 | 4 |
| 5188146770730811398 | 6 |
| 7493989779944505347 | 3 |
±--------------------±-----+
8 rows in set (0.00 sec)

请问,auto_random是如何保证唯一性呢


若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出的打印结果,请务必全选并复制粘贴上传。

可以参考官方文档

  • 隐式分配:如果该 INSERT 语句没有指定整型主键列( a 列)的值,或者指定为 NULL ,TiDB 会为该列自动分配值。该值不保证自增,不保证连续,只保证唯一,避免了连续的行 ID 带来的热点问题。
  • 显式插入:如果该 INSERT 语句显式指定了整型主键列的值,和 AUTO_INCREMENT 属性类似,TiDB 会保存该值。注意,如果未在系统变量 @@sql_mode 中设置 NO_AUTO_VALUE_ON_ZERO , 即使显式指定整型主键列的值为 0 ,TiDB 也会为该列自动分配值。

https://docs.pingcap.com/zh/tidb/stable/auto-random

这里简单解释一下就是,auto_random 的生成还是以 8 字节整形为基础。留出高位几个 bit 作 shard,在高位作随机,低位依然保持自增。所以能保证唯一。

可是参照文档,是不保证自增,不保证连续,只保证唯一。
我以为是和自增id一样,每个节点分配固定区间的id,在节点内自增连续。

谢谢,请问高位是几个bit 位?因为这个这个bit 确定了 shard的区间数,从而对应的有多少个region可以并行写。这个跟shard_row_id_bits有关系吗?或者类似原理

文档里面有写, AUTO_RANDOM | PingCAP Docs

该行值在二进制形式下,除去符号位的最高五位(称为 shard bits)由当前事务的开始时间决定,剩下的位数按照自增的顺序分配。

若要使用一个不同的 shard bits 的数量,可以在 AUTO_RANDOM 后面加一对括号,并在括号中指定想要的 shard bits 数量。示例如下:

CREATE TABLE t (a bigint PRIMARY KEY AUTO_RANDOM(3), b varchar(255))

以上建表语句中,shard bits 的数量为 3 。shard bits 的数量的取值范围是 [1, field_max_bits) ,其中 field_max_bits 为整型主键列类型占用的位长度。

shard bits 为最高5位,那岂不是最多可以有31个 shard,最多有 region可以并行写入? 可以这样理解吗

  1. max allowed auto_random shard bits is 15,最大可以设置值为 15.
  2. 多少 region 可以并行写入,我不大理解是什么意思? region 并没有限制并发写入.

可以调整到最多 shard bits 15 位,这个的 shard region 数量足够了,但是调整了这个之后就不能调小,所以还是根据具体的场景慎重设置。通常默认 5 个 bits,2^^5 -1 = 31 个 shard 也足以分散写入了。

意思一个shard 的id 在一个区间内 连续递增,那写入基本是路由到一个region上,所以 我通俗认为有多少个shard,就可以有多个region在并非写入。不知这样理解是否有问题?

明白,多谢。

:call_me_hand::call_me_hand: