Files_in_Clickhouse

物理结构图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
primary.idx
├─ entry 0 -> granule 0
├─ entry 1 -> granule 1
└─ ...

column.mrk4 (per column)
├─ mark 0 -> (compressed_offset, decompressed_offset) of granule 0
├─ mark 1 -> (compressed_offset, decompressed_offset) of granule 1
└─ ...

data.bin
├─ compressed block A
│ ├─ granule 0
│ └─ granule 1
├─ compressed block B
│ └─ granule 2
└─ ...

primary.idx / primary.cidx(主键稀疏索引)

主键索引文件,用于按 granule 粒度 进行范围裁剪(range pruning)。

索引项(entry)生成规则

  • 每当形成一个新的 granule,就会在 primary 索引中生成一个 entry

  • granule 的边界由以下两个条件之一触发(OR 关系):

    • 行数达到 index_granularity(默认 8192 行)
    • ranule 内累计的 解压后数据大小 达到 index_granularity_bytes(通常约 10MB)

    重要说明

    • granule 的行数是 上限约束,并非固定值
    • 当 10MB 条件先触发时,一个 granule 的行数可能 明显小于 8192
    • primary 索引是 稀疏索引,只定位到 granule,而非单行

column.mrk / column.mrk4(列级定位信息)

对于 每一列,都有一个对应的 mark 文件,用于描述 每个 granule 在该列数据文件中的物理位置。

mark 的数量关系
每个 data part 中:primary.idx 中有多少个 entry,每个列的 .mrk / .mrk4 文件中就有多少个 mark。二者在 granule 维度上 一一对应

每个 mark 的内容
每个 mark 是一对偏移量:
compressed_offset :granule 所在压缩块在 .bin 文件中的起始字节偏移
decompressed_offset:压缩块解压到内存后,该 granule 在解压后内存块中的起始字节偏移

补充说明
decompressed_offset 是 内存语义,不是磁盘语义。当一个压缩块只包含一个 granule 时,该值通常为 0;当一个压缩块包含多个 granule 时:第一个 granule 的 decompressed_offset = 0;后续 granule 的 decompressed_offset 为其在解压后内存块中的字节偏移

data.bin(列数据文件)

物理结构

data.bin 由多个 压缩块(compressed blocks) 顺序组成

每个压缩块包含:
1 个或多个完整 granule;任何一个 granule 都不会跨越压缩块边界

关系约束
一个 granule:必然完全位于某一个压缩块中;一个压缩块:可以包含多个 granule(取决于 granule 大小与压缩策略)

其他文件

  1. columns.txt:描述本 part 中:列名、列类型、列顺序

  2. columns_substreams.txt:
    描述每个列的 子流(substream)布局。特别是:

    • Nullable
    • Array
    • LowCardinality
    • Map

    决定:一个逻辑列拆成几个 .bin / .mrk

  3. checksums.txt:记录本 part 中 每个文件的校验和与大小

  4. count.txt:记录该 part 中的 行数,相当于 part 级的 “统计元数据”

  5. serialization.json:描述 列的序列化 / 反序列化方式

  6. default_compression_codec.txt:记录该 part 使用的默认压缩算法(如 LZ4、ZSTD)

  7. metadata_version.txt:表示该 part 的 metadata 版本