简单笔记. 主要看结构和实现. 操作就不细看了.
计算层
tidb
sql
工作
sql parse
parse –> ast -> logical opt -> logical plan -> physical opt -> physical plan
优化
逻辑优化
列裁剪
分区裁剪
聚合消除
Max/Min优化
max
=> select c from t order by c desc limit 1
外连接消除
外连接转内连接
子查询去关联
谓词下推
聚合下推
TopN / Limit 下推
query plan生成
op
映射到tikv的kv api
逻辑算子(ds, SPJ)
DataSource
S(S)election
P(P)rojection
J(J)oin
分布式sql
核心是最大程度进行本地计算
scan,filter,aggregate下推 - 计算出一个细粒度的结果后通过上层归并
避免通信(rpc),避免计算堆积到上层, 称为瓶颈.
数据映射
table <-> kv
表
TableID
行
RowID
如果表的主键是整数, 不用分配RowID
,直接用这个主键
存储
Key: tablePrefix{TableID}_recordPrefixSep{RowID}
Value: [col1, col2, col3, col4]
索引
无状态
索引
主键/二级索引
元信息/调度
PD(placement driver
)
数据分布
region的分布, 确保大体均匀
调度算法的参考指标?
集群拓扑
dashboard
元信息
上报
tikv节点上报
磁盘/可用磁盘/写入速度/region数/发送接受snapshot数/负载情况/标签
raft group
leader上报
leader位置
follower位置, 掉线
replica数量
读写速度
上报的信息作为调度的依据
调度策略 TODO
弹性调度 (elastic schedule)
分布式存储
tikv
支持接口层面的分布式事务
snapshot isolation
出现写-写冲突, 事务abort
本地存储
rocksdb
raft
几个功能
leader selection
成员管理
log replication
tikv利用这个做节点点数据复制
一次数据变更 -> raft一条日志
sharding
按range划分
Region
概念
连续key及值组成的片段
[start_key, end_key]
默认大小96mb
数据分布的基本单位
raft复制的基本单位
一个region的多个节点, 配置一个raft group
mvcc
结构
基础
key -> value
mvcc
key_v1 -> value
key_v0 -> value
…
版本号大的在前, 利用rocksdb的SeekPrefix
找到最新数据
分布式ACID
tiflash
列式存储引擎(for olap)
CREATE TABLE User {
ID int, Name varchar(20), Role varchar(20), Age int, PRIMARY KEY (ID), Key idxAge (age)
};
-- 三行数据
1, "TiDB", "SQL Layer", 10
2, "TiKV", "KV Engine", 20
3, "PD", "Manager", 30
映射到key-value上, 表数据
t10_r1 -> ["TiDB", "SQL Layer", 10]
t10_r2 -> ["TiKV", "KV Engine", 20]
t10_r3 -> ["PD", "Manager", 30]
索引数据
t10_i1_10_1 --> null
t10_i1_20_2 --> null
t10_i1_30_3 --> null
https://pingcap-incubator.github.io/tidb-in-action/session1/chapter5/mysql-compatibility.html
使用PD
作为TSO
(timestamp oracle), 来分配全局唯一,单调递增的版本号.
特点:
tso
mvcc
2pc
prewrite
commit
过程
客户端开始一个事务。
TiDB向 pd 获取 tso 作为当前事务的 start_ts。
客户端发起读或写请求。
客户端发起 commit。
TiDB开始两阶段提交,保证分布式事务的原子性,让数据真正落盘。
TiDB 从当前要写入的数据中选择一个 Key 作为当前事务的 Primary Key。
TiDB 并发地向所有涉及的 TiKV 发起 prewrite 请求。TiKV 收到 prewrite 数据后,检查数 据版本信息是否存在冲突或已过期。符合条件的数据会被加锁。
TiDB 收到所有 prewrite 响应且所有 prewrite 都成功。
TiDB 向 PD 获取第二个全局唯一递增版本号,定义为本次事务的 commit_ts。
TiDB 向 Primary Key 所在 TiKV 发起第二阶段提交。TiKV 收到 commit 操作后,检查数 据合法性,清理 prewrite 阶段留下的锁。
TiDB 向客户端返回事务提交成功的信息。
TiDB 异步清理本次事务遗留的锁信息。
乐观(OCC)
tx提交阶段检测冲突(进入prewrite后)
悲观(PCC)
tx执行阶段检测冲突(prewrite前, 加入AcquirePessimistic Lock
阶段)