❤️ 友情提示:代码演进较快,请注意文档的时效性哦!
引言
Databend 将存储引擎抽象成一个名为
Table
query/catalog/src/table.rs
Table
read
append
alter
optimize
truncate
recluster
Table trait
pipeline
通过实现
Table
Storage 主要关注
Table
目录
包名 | 作用 |
---|---|
common/cache | 定义与管理缓存,包括磁盘缓存和内存缓存。类型包含表 meta 缓存、查询结果缓存、表数据缓存等。 |
common/index | 定义与使用索引,目前支持 bloom filter index、page index、range index。 |
common/locks | 管理与使用锁,支持表级别的锁。 |
common/pruner | 分区剪裁算法,包括 internal column pruner、limiter pruner、page pruner、topn pruner、range pruner。 |
common/table_meta | 表 meta 的数据结构定义。 |
hive | hive 表的交互 |
iceberg | iceberg 交互 |
information_schema、system | 系统表定义 |
memory、null、random | 用于开发和测试的引擎 |
view | 视图相关 |
stage | stage 数据源的读取 |
parquet | 把 parquet 文件作为数据源 |
fuse | fuse 引擎模块 |
fuse/src/io | table meta、index、block 的读写 IO 交互 |
fuse/src/pruning | fuse 分区裁剪 |
fuse/src/statistics | column statistics 和 cluster statistics 等统计信息 |
fuse/src/table_functions | table function 实现 |
fuse/src/operation | fuse 引擎对 table trait 方法的具体实现。并包含了如 ReadSource、CommitSink 等 processor 算子的定义 |
Read Partitions
以下以 fuse 引擎中 read partitions 的实现流程为例,简要分析 Storage 相关源码。
Partitions 的定义位于
query/catalog/src/plan/partition.rs
pub struct Partitions {
// partitions 的分发类型。
pub kind: PartitionsShuffleKind,
// 一组实现了 PartInfo 接口的 partition,
pub partitions: Vec<PartInfoPtr>,
// partitions 是否为 lazy。
pub is_lazy: bool,
}
Table 接口中的
read_partitions
#[async_trait::async_trait]
impl Table for FuseTable {
#[minitrace::trace]
#[async_backtrace::framed]
async fn read_partitions(
&self,
ctx: Arc<dyn TableContext>,
push_downs: Option<PushDownInfo>,
dry_run: bool,
) -> Result<(PartStatistics, Partitions)> {
self.do_read_partitions(ctx, push_downs, dry_run).await
}
}
Fuse 引擎会以 segment 为单位构建 lazy 类型的
FuseLazyPartInfo
prune_snapshot_blocks
pub struct FuseLazyPartInfo {
// segment 在 snapshot 中的索引位置。
pub segment_index: usize,
pub segment_location: Location,
}
分区剪裁流程的实现位于
query/storages/fuse/src/pruning/fuse_pruner.rs
- 基于 条件构造各类剪裁器(pruner),并实例化
push_downs
。FusePruner
- 调用 中的
FusePruner
方法,创建pruning
个分批剪裁任务。每个批次包括多个 segment 位置,首先根据max_concurrency
筛选出无需的 segments,再读取internal_column_pruner
,并根据 segment 级别的SegmentInfo
MinMax