我先写下我的理解,也不知道是否正确,同时对查询部分也有疑问,请大神指教
一,写数据部分,我简单写了三步:
1,构造一组数据如下,大概表示某一个区域一段时间的温度(假设时间是唯一的前提)
CREATE TABLE t1 ( created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP PRIMARY KEY,
area VARCHAR(512),
temperature float,
INDEX(area)
);
±--------------------±-----±------------+
| created_at | area | temperature |
±--------------------±-----±------------+
| 2021-08-13 14:59:52 | A1 | 25 |
| 2021-08-13 15:03:56 | A2 | 26 |
| 2021-08-13 15:04:06 | A1 | 27 |
| 2021-08-13 15:04:20 | A12 | 29 |
| 2021-08-13 15:04:43 | A2 | 30 |
±--------------------±-----±------------+
2, 这组数据在tidb映射到唯一索引key-value是
t_1_2021-08-13-14:59:52 = 25
t_1_2021-08-13-15:03:56 = 26
t_1_2021-08-13-15:04:06 = 27
t_1_2021-08-13-15:04:20 = 29
t_1_2021-08-13-15:04:43 = 30
还有一组非唯一索引key-value
i_area_A1_2021-08-13-14:59:52 = nil
i_area_A2_2021-08-13-15:03:56 = nil
i_area_A1_2021-08-13-15:04:06 = nil
i_area_A12_2021-08-13-15:04:20 = nil
i_area_A2_2021-08-13-15:04:43 = nil
3,tidb通过pd获取路由,tidb调用put接口将这些key-value的值设置到leader的tikv节点,假如第二组key存在 region[i,j), 第一组key存在region[t,y)中,完成了miti-raft操作后最后,将有相关region修改的store存储到RocksDb中。
二, 读取数据
1,假如我想查A1区域的问题信息,那么执行select * from t1 where area=‘A1’;
我主要对这个查询过程有点疑问,我觉得这部分是这么查询的,不知道是否正确?
从逻辑来看,这个语句的查询主要分两部分,
第一步是要查 i_area_A1_xxx的xxx部分
这里查出来是2021-08-13-14:59:52和2021-08-13-15:04:06
第二步是根据这两个值查
t_1_2021-08-13-14:59:52 = 25
t_1_2021-08-13-15:04:06 = 27
这样就可以获取到A1区域的温度了。
2,如果上面部分逻辑是正确的,那么从tidb到tikv的代码逻辑是怎么调用的??
还没仔细看源码,我想可能两种情况:
1)tidb调用条件查询,tikv直接做了刚才说的两步骤(但我没看到相关接口)
2)tidb分开做这两部分,调用批量查询的接口, i_area_A1_,先做一个模糊查询,再获取到后,再批量查询一次
1 个赞
skyzh
(Alex Chi)
5
你的问题相当好。不过 AskTUG 的定位是给 TiDB 用户使用的,但这个问题看起来是一个开发者才会探究的问题。对于这种疑问,我们建议在 Slack 或者 internals.tidb.io 上讨论。那里的开发者更多。
两个方案都不太准确。
TiKV 实现了一个叫 coprocessor 的模块,可以按条件扫描索引和数据。大概的介绍可以看这里 TiKV 源码解析系列文章(十四)Coprocessor 概览 | PingCAP 。我猜 TiDB 会分别调用 coprocessor 接口的 IndexScan + TableScan 得到最终的数据。单个 TiKV 结点不一定能存储一整张表,所以 TiDB 从多个 TiKV coprocessor 拿到数据以后还需要做一些整合。
因此整个步骤应该分为两步:向 TiKV Coprocessor 请求数据,然后在 TiDB 处聚合。
查询过程可能还需要一些 2PC 逻辑,可以参考 https://andremouche.github.io/tidb/coprocessor_in_tikv.html 。
新版 TiDB 应该实现了 clustered index,开启以后具体的流程可能还有一些区别。
具体的执行计划可以在 TiDB 中用 explain 语句查看。
MySQL [test]> CREATE TABLE t1 ( created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP PRIMARY KEY,
-> area VARCHAR(512),
-> temperature float,
-> INDEX(area)
-> );
Query OK, 0 rows affected (0.132 sec)
MySQL [test]> explain select * from t1 where area = "test";
+-------------------------------+---------+-----------+----------------------------+-------------------------------------------------------+
| id | estRows | task | access object | operator info |
+-------------------------------+---------+-----------+----------------------------+-------------------------------------------------------+
| IndexLookUp_10 | 10.00 | root | | |
| ├─IndexRangeScan_8(Build) | 10.00 | cop[tikv] | table:t1, index:area(area) | range:["test","test"], keep order:false, stats:pseudo |
| └─TableRowIDScan_9(Probe) | 10.00 | cop[tikv] | table:t1 | keep order:false, stats:pseudo |
+-------------------------------+---------+-----------+----------------------------+-------------------------------------------------------+
3 rows in set (0.002 sec)
我们最近也在筹备写新版的 TiKV Dev Guide,这一部分的内容应该会涉及到。敬请期待。
1 个赞
system
(system)
关闭
6
此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。