split index文档写得不清楚,99%的人看不懂,麻烦写详细文档

文档中关于split index key中包含数学和字母的部分,写得不明不白,一笔带过,无人看得懂是怎么计算step的,可以一步一步的写个真实的详细的步骤吗?

问题1:
upperlower 的值会先编码成 byte 数组
请问这里如何将upper和lower值编码成byte数组呢?我们怎么计算出这个数组的呢?
问题2:
lowerupper 各取前 8 字节转成 uint64
请问这里如何取值8字节并转成unit64呢?可以使用一个案例说出详细步骤吗?空有文字我们难以脑补。
问题3:
step = (upper - lower)/num
请问这个num是如何确定的呢?是指kv的数量还是regions个数?
问题4:
计算出 step 后再将 step 编码成 byte 数组
请问这个如何编码成byte数组,该如何计算,请更出详细的计算步骤
问题5:
添加到之前 upperlower 的最长公共前缀后面组成一个 key 后去做切分
请列出详细步骤。

我想问下,这种低级繁琐的计算题,代码为什么不自动实现?为何需要人为的去计算?数据库人性化和智能化可以实现吗?

如果不是因为热点引起一个节点CPU爆掉,导致全业务停摆,我们也不会来看这个看不懂的文档。

均匀切分

索引均匀切分与行数据均匀切分的原理一样,只是计算 step 的值较为复杂,因为 index_value 可能不是整数。

upperlower 的值会先编码成 byte 数组,去掉 lowerupper byte 数组的最长公共前缀后,从 lowerupper 各取前 8 字节转成 uint64,再计算 step = (upper - lower)/num。计算出 step 后再将 step 编码成 byte 数组,添加到之前 upperlower的最长公共前缀后面组成一个 key 后去做切分。示例如下:

如果索引 idx 的列也是整数类型,可以用如下 SQL 语句切分索引数据:

SPLIT TABLE t INDEX idx BETWEEN (-9223372036854775808) AND (9223372036854775807) REGIONS 16;

该语句会把表 t 中 idx 索引数据 Region 从 minInt64maxInt64 之间均匀切割出 16 个 Region。

1 个赞

这里计算 region split 切分后的边界,本来就是自动的啊

问题1:
upperlower 的值会先编码成 byte 数组
请问这里如何将upper和lower值编码成byte数组呢?我们怎么计算出这个数组的呢?

不用算,它是自动的

问题2:
lowerupper 各取前 8 字节转成 uint64
请问这里如何取值8字节并转成unit64呢?可以使用一个案例说出详细步骤吗?空有文字我们难以脑补。

不用算,这是自动的,代码类似 binary.BigEndian.Uint64(b byte)

问题3:
step = (upper - lower)/num
请问这个num是如何确定的呢?是指kv的数量还是regions个数?

就是你语句中写的的 region_num
SPLIT TABLE table_name [INDEX index_name] BETWEEN (lower_value) AND (upper_value) REGIONS region_num

问题4:
计算出 step 后再将 step 编码成 byte 数组
请问这个如何编码成byte数组,该如何计算,请更出详细的计算步骤

不用算,这是自动的

问题5:
添加到之前 upperlower 的最长公共前缀后面组成一个 key 后去做切分
请列出详细步骤。

这步是因为前边去掉了前缀, “ 去掉 lowerupper byte 数组的最长公共前缀后”

总结:
这段描述主要是告诉你,对于索引的 split 是怎么计算的,因为索引可能是字符串

1 ~ 100000 分成成 4 个 region 很简单,均分就行了

1 ~ 25000
25000 ~ 50000
50000 ~ 75000
75000 ~ 100000

那如果数据是 “aa” ~ “ab” 呢,或者是 “你好” ~ “中国” 呢 (PS:这里的数值都是随便写的,只为了举例),就需要用到前边说的算法把他们均分一下

现在说的是手工split index.
你可以自己建一张表,然后创建一个索引,你再把索引split region一下看看,
SPLIT TABLE t INDEX idx

就还是按照正常的流程处理吧。上面给的应该是内部底层的划分。直接按照key值拆分就行。
mysql> select count(1) from INFORMATION_SCHEMA.tikv_region_status d where d.TABLE_NAME=‘ccc’ and d.IS_INDEX=1 and d.INDEX_NAME=‘i_12’;-- table_name
±---------+
| count(1) |
±---------+
| 3 |
±---------+
1 row in set (0.09 sec)

mysql> select min(table_name),max(table_name) from ccc;
±----------------±----------------+
| min(table_name) | max(table_name) |
±----------------±----------------+
| aaa | zzz |
±----------------±----------------+
1 row in set (0.00 sec)

mysql> split table tidbcs.ccc index i_12 between (‘aaa’) and (‘zzz’) regions 3;
±-------------------±---------------------+
| TOTAL_SPLIT_REGION | SCATTER_FINISH_RATIO |
±-------------------±---------------------+
| 3 | 1 |
±-------------------±---------------------+
1 row in set (0.61 sec)

mysql> select count(1) from INFORMATION_SCHEMA.tikv_region_status d where d.TABLE_NAME=‘ccc’ and d.IS_INDEX=1 and d.INDEX_NAME=‘i_12’;-- table_name
±---------+
| count(1) |
±---------+
| 5 |
±---------+
1 row in set (0.17 sec)

SPLIT TABLE t INDEX idx 语句并没有让你填每个 region 的范围啊,只让你填上下界和 region 数,要测试啥?

SPLIT TABLE table_name [INDEX index_name] BETWEEN (lower_value) AND (upper_value) REGIONS region_num

你说的上界和界就是lower_value和upper_values,lower_value和upper_value 如果计算出这两个值的呢?文档就没写清楚。

比如下图,key包含有字母和数字,如何split table呢?
start_key: t_192_5f7280000000000145e9
end_key: 78000000

表中已经有大量数据了,只是想把其中某个regions做split,你这个是一次把整个索引的做split。