惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Google DeepMind News
Google DeepMind News
T
Tenable Blog
博客园_首页
S
Securelist
Spread Privacy
Spread Privacy
Google Online Security Blog
Google Online Security Blog
Forbes - Security
Forbes - Security
Engineering at Meta
Engineering at Meta
U
Unit 42
L
LINUX DO - 热门话题
量子位
T
Threat Research - Cisco Blogs
博客园 - 【当耐特】
C
Cyber Attacks, Cyber Crime and Cyber Security
K
Kaspersky official blog
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
The Last Watchdog
The Last Watchdog
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
Martin Fowler
Martin Fowler
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Security Latest
Security Latest
Scott Helme
Scott Helme
V
Vulnerabilities – Threatpost
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
InfoQ
Know Your Adversary
Know Your Adversary
Cisco Talos Blog
Cisco Talos Blog
The Register - Security
The Register - Security
T
The Blog of Author Tim Ferriss
aimingoo的专栏
aimingoo的专栏
V2EX - 技术
V2EX - 技术
T
Tailwind CSS Blog
月光博客
月光博客
Recent Announcements
Recent Announcements
G
Google Developers Blog
F
Full Disclosure
W
WeLiveSecurity
宝玉的分享
宝玉的分享
腾讯CDC
G
GRAHAM CLULEY
Vercel News
Vercel News
Simon Willison's Weblog
Simon Willison's Weblog
美团技术团队
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Help Net Security
Help Net Security

土法炼钢兴趣小组的算法知识备份

国密算法与国密 TLS 系列索引 【系统架构设计】架构质量属性:不只是"高可用高性能" 【系统架构设计百科】告警策略:如何避免"狼来了" 【系统架构设计】CQRS:读写分离的架构哲学 【系统架构设计】空间架构:极端扩展场景的解法 【系统架构设计】微服务架构深度审视:优势、代价与适用边界 【系统架构设计】扩展性原理:水平、垂直与对角扩展 【系统架构设计】无状态设计:扩展的第一步也是最难的一步 【系统架构设计】缓存架构:从本地到分布式的多级缓存体系 【系统架构设计】管道与过滤器:Unix 哲学的架构表达 【系统架构设计】复杂性管理:架构的核心战场 【系统架构设计】消息队列架构:异步解耦的设计与陷阱 【系统架构设计】CDN 架构:全球加速的设计原理 【系统架构设计】连接池设计:被忽视的性能杀手 【系统架构设计】弹性设计模式:熔断器、舱壁与超时 【系统架构设计】高可用设计模式:冗余、故障转移与仲裁 【系统架构设计】容量规划:从拍脑袋到数据驱动 【系统架构设计】数据库扩展:分库分表的工程实践与替代方案 【系统架构设计】SLO 工程:可靠性的量化管理 【系统架构设计】性能建模:用数学思维分析系统瓶颈 【系统架构设计】混沌工程:主动验证系统的韧性 【系统架构设计】零拷贝与内存映射:数据搬运的极致优化 【系统架构设计】线程模型:从 thread-per-request 到协程 【系统架构设计】容灾架构:多活与灾备设计 【系统架构设计】数据库性能模式:索引、查询与连接管理 【系统架构设计】数据建模:从关系范式到文档模型的真实权衡 【系统架构设计】吞吐量优化:批处理、流水线与并发模型 【系统架构设计】流处理架构:从批处理到实时的范式迁移 【系统架构设计】搜索引擎架构:倒排索引之上的系统设计 【系统架构设计】时序数据架构:监控与 IoT 的存储设计 【系统架构设计】数据迁移与版本化:在线不停机的数据演进 【系统架构设计】数据湖与数据仓库:分析架构的演进路线 【系统架构设计】API 网关设计:入口层的职责边界 【系统架构设计】应用层数据一致性模式:在正确性与性能之间走钢丝 【系统架构设计】多模数据库选型:Polyglot Persistence 的工程实践 【系统架构设计】服务发现与注册:动态拓扑的基础设施 【系统架构设计】配置管理架构:从配置文件到配置中心 【系统架构设计】全链路压测:大规模系统的性能验证 【系统架构设计】幂等性设计:分布式环境下的安全重试 【系统架构设计】契约测试与 Schema 演进:服务间的信任协议 【系统架构设计】长连接与推送架构:WebSocket、SSE 与 MQTT 【系统架构设计】延迟分析:从 P50 到 P999 的全链路追踪 【系统架构设计百科】DDD 战术模式:聚合、实体与值对象 【系统架构设计百科】防腐层与开放主机服务:系统集成的 DDD 方案 【系统架构设计百科】领域事件与事件风暴:从业务到架构的桥梁 【系统架构设计百科】CQRS + Event Sourcing 完整实战:从领域建模到部署 【系统架构设计百科】DDD 与微服务:用领域模型划分服务边界 【系统架构设计】DDD 战略设计:限界上下文与上下文映射 【系统架构设计百科】认证架构:从 Session 到 JWT 到 OIDC 【系统架构设计】API 设计哲学:REST vs GraphQL vs gRPC 的真实权衡 排序算法专题:从 TimSort 到并行排序 【密码学百科】国密算法体系:SM2/SM3/SM4/SM9 全景解读 【密码学百科】承诺方案:Pedersen 承诺、向量承诺与多项式承诺 【密码学百科】不经意传输与隐私信息检索:OT、OT 扩展与 PIR 【密码学百科】门限密码学:门限签名、门限解密与分布式密钥生成 完美哈希:从理论到 gperf 实践 【密码学百科】安全多方计算:从 Yao 的混淆电路到实用 MPC 【密码学百科】同态加密:从 Paillier 到全同态加密(FHE) 【密码学百科】零知识证明系统:zk-SNARKs、zk-STARKs 与 Bulletproofs 【密码学百科】概率论与密码分析:生日攻击、差分分析与线性分析 【密码学百科】计算复杂性与归约:密码安全性证明的基石 【密码学百科】秘密共享:Shamir 方案、VSS 与安全多方计算入口 【密码学百科】椭圆曲线代数:Weierstrass 方程、点群运算与曲线选择 【密码学百科】离散对数与配对密码学:从 DLP 到 BLS 签名 【密码学百科】格密码数学基础:SVP、LWE 与格基约化 【密码学百科】抽象代数:群、环、域的密码学视角 【密码学百科】有限域算术:GF(2^n) 运算与在 AES/ECC 中的应用 【密码学百科】数论进阶:二次剩余、椭圆曲线上的 Weil 配对 【密码学百科】密码学简史:从凯撒密码到量子时代 【密码学百科】威胁模型与安全目标:CIA 三要素之外 【密码学百科】Kerckhoffs 原则与现代密码设计哲学 【密码学百科】随机性:密码学的基石 【密码学百科】信息论入门:熵、完美保密与 Shannon 定理 【密码学百科】分组密码原理:Feistel 网络与 SPN 结构 【密码学百科】AES 逐步拆解:SubBytes 到 MixColumns 的数学 【密码学百科】分组密码工作模式全览:ECB/CBC/CTR/OFB/CFB 【密码学百科】流密码:RC4 的兴衰与 ChaCha20 的崛起 【密码学百科】密码学哈希函数:MD5→SHA-2→SHA-3 的进化之路 【密码学百科】MAC 与 HMAC:消息认证的正确姿势 【密码学百科】认证加密(AEAD):GCM、ChaCha20-Poly1305 与 OCB 【密码学百科】密钥派生函数:HKDF、PBKDF2、Argon2 与密码存储 【密码学百科】公钥密码的数论基础:模运算、群、原根 【密码学百科】RSA 从原理到攻击:教科书 RSA 为什么不安全 【密码学百科】Diffie-Hellman 密钥交换与离散对数问题 【密码学百科】椭圆曲线密码学(ECC):从几何直觉到点群运算 【密码学百科】数字签名:ECDSA、EdDSA 与 Schnorr 签名 【密码学百科】现代密钥交换:X25519、ECDHE 与前向保密 【密码学百科】混合加密与 KEM/DEM 范式:ECIES 与 HPKE 【密码学百科】填充方案:PKCS#1 v1.5、OAEP 与 PSS 【密码学百科】TLS 协议全解析:从握手到 0-RTT 【密码学百科】PKI 与数字证书:信任链的构建与崩塌 【密码学百科】密码认证协议:从 SRP 到 OPAQUE 【密码学百科】零知识证明入门:如何证明你知道而不泄露 【密码学百科】安全信道构造:Noise 协议框架与 Signal 协议 【密码学百科】密钥管理工程:HSM、KMS 与密钥生命周期 【密码学百科】侧信道攻击:从时序攻击到功耗分析 【密码学百科】密码学实现陷阱:三层漏洞分类、审计工具链与系统性预防 密码敏捷性:如何设计可升级的密码系统 【密码学百科】OpenSSL/BoringSSL 架构剖析:ENGINE、Provider 与 FIPS 模块 排序基准测试:用数据说话
【列存引擎内核】Merge 与 Mutation
Liao Tonglang · 2026-06-18 · via 土法炼钢兴趣小组的算法知识备份

Insert 只 追加 Part;后台 merge 把多个小 Part 归并为更大 Part——列存的「心脏手术」,类比 LSM CompactionMutation 则异步重写 Part 实现 UPDATE/DELETE,堆积会拖垮集群。


无 merge 有 merge
Part 数线性涨 Part 数受控
每次查询打开大量目录 读放大下降
parts_to_throw_insert 拒绝写 可持续 ingest
flowchart LR
  P1[Part 小] --> M[Merge]
  P2[Part 小] --> M
  M --> P3[Part 大]

二、Merge 触发与 selector

MergeTreeBackgroundExecutor 调度任务;selector 根据 Part 大小、level、分区挑选可 merge 组合(SimpleMergeSelector 等)。

Settings:max_bytes_to_merge_at_max_space_in_poolmerge_max_block_sizenumber_of_free_entries_in_pool_to_execute_merge

观察(本机):

SELECT * FROM system.merges;
SELECT database, table, sum(1) FROM system.parts WHERE active GROUP BY database, table;

不伪造 system.merges 行。


三、Merge 做什么

对同分区、排序键兼容的 Part 多路归并(与 LSM 归并相似):

  • 输出新 Part,旧 Part Outdated
  • 重新压缩、可应用新 CODEC
  • Replacing/Summing 等引擎在归并时应用语义

源码:MergeTreeDataMergerMutator.cpp


四、ReplacingMergeTree

CREATE TABLE r (
  id UInt64,
  v String,
  ver UInt64
) ENGINE = ReplacingMergeTree(ver)
ORDER BY id;

Merge 同 id 保留 ver 最大行。查询可能见重复,除非 FINAL(有性能成本)。


五、CollapsingMergeTree

Sign Int8:+1 插入,-1 撤销;merge 折叠。适合变更流。


六、Mutation

ALTER TABLE UPDATE v = ... WHERE ... → 队列 → 读旧 Part 写新 Part。

危害:

  • 与 merge 争线程
  • 磁盘写放大
  • system.mutations 堆积

生产尽量避免大范围 mutation;用 Replacing 或重建表替代。

stateDiagram-v2
  [*] --> Queued: ALTER UPDATE
  Queued --> Executing: background
  Executing --> Done: 新 Part 替换
  Executing --> Failed: 磁盘/超时

七、TTL

TTL 规则在 merge 时删除/移动过期 granule,依赖 merge 运行。


八、小结

Merge = 归并 Part、控制读放大、实现引擎语义;Mutation = 重写 Part、应慎用。


上一篇查询读取路径

下一篇索引与跳数索引


附录、扩展阅读与工程注记

Merge selector

SimpleMergeSelector / TTLMergeSelector 等根据 Part 大小、年龄、分区挑选 merge 任务;目标减少 Part 数且控制写放大。

ReplacingMergeTree

replace 版本列默认 is_deleted 或显式 version;merge 同排序键保留 version 最大。查询仍可能见重复行,除非 FINAL 或应用层去重。

CollapsingMergeTree

Sign 列 +1/-1 表示插入与撤销;merge 折叠成 net 行。适合变更流而非物理 DELETE。

Mutation 路径

ALTER TABLE UPDATE/DELETEMutationCommands 队列 → 后台读 Part 重写新 Part → 原子替换。堆积时 system.mutations 可见;与 merge 争用 BackgroundSchedulePool。 ### index_granularity

两个 Mark 之间最大行数;影响稀疏索引粒度与单次读 granule 行数上限。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):8192

index_granularity_bytes

自适应 granule:限制 granule 预估字节大小,宽行表避免单 granule 过大。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):10485760 (10 MiB)

enable_mixed_granularity_parts

是否启用 index_granularity_bytes 与 index_granularity 混合控制。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):1

min_bytes_for_wide_part

Part 体积超过阈值时使用 Wide 布局(列独立文件)。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):10485760

min_rows_for_wide_part

行数超过阈值转 Wide。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):0

parts_to_throw_insert

活跃 Part 数超过阈值拒绝 insert。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):3000

parts_to_delay_insert

超过阈值开始延迟 insert。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):1000

merge_max_block_size

单次 merge 输出块大小上限。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):8192

max_bytes_to_merge_at_max_space_in_pool

merge 池有空闲时单任务最大字节。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):161061273600

number_of_free_entries_in_pool_to_execute_mutation

mutation 与 merge 共享池时的调度参数。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):见文档

compress_marks

是否压缩 Mark 文件。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):1

compress_primary_key

是否压缩 primary.idx 落盘(内存仍解压使用)。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):1

S3 磁盘与冷存

S3 作 disk 时 Part 对象化;读延迟高于本地 SSD。merge 仍发生,网络带宽成为瓶颈。

Replicated 与 S3

零拷贝 replication 到 S3 磁盘配置见官方;副本 fetch 可走对象存储。与第 8 篇 queue 类型相关。

数据倾斜与 PARTITION BY

单分区过大 merge 慢;过多分区 metadata 膨胀。按天/租户合理切分;避免 PARTITION BY rand()

PRIMARY KEY 长度

PK 列过多/long String 增大 primary.idx 与内存。仅前缀必要列;其余放 ORDER BY 后缀或跳数索引。

跳数索引 GRANULARITY 选择

GRANULARITY 过大索引粗;过小索引体积接近逐 granule。默认 1–4 需按列选择性实验(第 7 篇)。

bloom_filter 假阳性

Bloom 仅跳过 granule;假阳性多读 granule 仍正确。无 false negative。

minmax 索引失效场景

列值在 granule 内分布宽但谓词窄,minmax 无法跳过——需更细 ORDER BY 或 bloom。

set 索引大小上限

set 索引 granule 内 distinct 超上限则退化;高基数列不适用 set。

向量索引(边界)

向量相似搜索非 MergeTree 经典跳数索引范畴;24.x 实验特性不在此系列承诺。

Pipeline EXPLAIN 用法

EXPLAIN PIPELINE 展示 Processor 图;与 EXPLAIN indexes=1 互补。本环境无实例不贴输出。

QueryPlan 阶段

Analyzer 产出 QueryPlan,再转 Pipeline。PREWHERE 下推在此阶段决定;SQL 写法影响是否自动 PREWHERE。

Constant 折叠与 primary key

常量谓词与 PK 范围交集在优化期计算;参数化查询仍受益 prepared 边界。

FINAL 与 dedup

ReplacingMergeTree 的 FINAL 在查询期归并;替代方案 MV 去重或应用层 argMax

Lightweight DELETE(版本边界)

较新版本 lightweight delete 标记删除 granule;与 mutation 路径不同。以 24.x 文档为准是否 GA。

Transaction 语义边界

单 insert block 原子;跨 Part 无 MVCC 快照隔离。勿与 PG MVCC 类比。

chDB / clickhouse-local

嵌入式 clickhouse-local 适合 Part 格式实验(第 2 篇);与 server 共用 MergeTree 代码路径。

版本升级与 Part 兼容

大版本升级前查 release notes Part 格式变更;通常向后读旧 Part,merge 逐步重写。

checksum 算法

checksums.txt 使用 CityHash128 等;损坏 Part 拒绝加载保护下游。

Serialization 与类型变更

ALTER MODIFY COLUMN 可能触发 mutation 重写;类型不兼容需中间列。

Dictionary 与外部维表

字典非 MergeTree Part;JOIN 字典与 MergeTree scan 是不同 IO 路径。

Global IN 代价预告

Distributed 上 GLOBAL IN 广播维表(第 9 篇);本地 MergeTree 无此问题。

测试数据 hits 样本

官方 hits 数据集适合验证读路径;下载与导入步骤见 clickhouse.com/docs getting started。

benchmark 伦理

引用外部 benchmark 必须标注来源;自测需 3 轮中位数与环境表(WRITING_GUIDE)。

源码阅读顺序建议

MergeTree:StorageMergeTreeIMergeTreeDataPartMergeTreeReaderWideMergeTreeDataMergerMutator。执行:PipelineExecutorIProcessor

社区与 LTS

24.x LTS 安全/backport 周期见官网;生产锚定 LTS 而非 latest。

system.parts 字段解读

运维读 Part 状态时常用列:databasetablename(目录名)、part_type(Wide/Compact)、rowsbytes_on_diskbytes_on_disk_uncompressedprimary_key_bytes_in_memorymarks_bytes_on_diskleveldata_versionis_frozenactive=0 表示已被 merge 替换但未物理删除。与 LSM SST 层数 类似,应监控每表 active part 数趋势。

system.merges 与 merge 进度

system.merges 展示当前运行中的 merge:databasetableelapsedprogress(0–1)、num_partsresult_part_nametotal_size_bytes_uncompressed。长时间 progress 不动可能磁盘 IO 饱和或单 Part 过大。merge_max_block_size 影响单次归并行数。

system.query_log 读路径指标

启用 query_log 后,read_rowsread_bytesresult_rows 对比可验证索引剪枝是否生效。PREWHERE 优化通常降低 read_bytesread_rows 仍含 granule 内过滤前行数。本系列不在此环境给出样本数值。

MergeTreeWriteSettings 与 insert

除表级 merge_tree settings 外,insert 受 max_insert_block_sizemin_insert_block_size_rowsasync_insert(24.x 异步 insert 特性以文档为准)影响。小 block 直接对应小 Part——平台侧应强制 batch 或 Buffer 引擎。

StoragePolicy 与多磁盘

TTL MOVE 与 storage_policy 可将 Part 移至慢盘/对象存储。merge 与 fetch 路径需保证目标卷有足够空间;system.diskssystem.storage_policies 描述卷与策略。

Projection 与读优化(边界)

24.x 支持 projection 预聚合/排序副本。属于高级 DDL,本系列主路径不展开;知晓其存在可避免与跳数索引职责混淆——projection 是额外 Part 子集,非跳数索引。

Sample By 与近似查询

SAMPLE BYSAMPLE 子句依赖排序键哈希;与主键剪枝独立。日志采样分析常用,但不替代正确 ORDER BY 设计。

Nullable 与 Default 列存储

Nullable 列额外 .null.bin(视版本/序列化而定);默认值列可能仅 .default 文件。读路径需合并 null map;宽表 Nullable 多会增加文件数。

UUID / IPv6 类型

固定长度类型序列化紧凑;仍受 granule 与 codec 影响。随机 UUID 作 ORDER BY 前缀会导致稀疏索引几乎无效——工程上避免。

DateTime64 与时区

DateTime64 排序键常用 DoubleDelta;插入时区 session_timezone 与显示无关存储。跨时区报表在 SQL 层转换,不在 Part 内改。

Enum 与 LowCardinality

Enum 存整数标签;LowCardinality 字典适合低基数。高基数 String 强行 LowCardinality 字典膨胀,压缩与查询均变差。

Nested 与 JSON 类型

Nested 在磁盘展开为多个子列 Array;JSON 类型(若启用)路径提取有独立序列化。宽 Nested 增加 Part 文件数,merge 成本上升。

Materialized Column

物化列随 insert 计算持久化,占独立 .bin。适合重复表达式,但增加写放大与存储;与 MV 目标表不同。

TTL DELETE vs DROP PARTITION

TTL DELETE 在 merge 时删 granule;ALTER DROP PARTITION 整分区移除 Part。后者运维更干净;前者适合行级过期。

Freeze / UNFREEZE 备份

FREEZE 硬链 Part 到 shadow/ 目录做一致性快照;与副本 fetch 互补。恢复需 ATTACH PART 流程,见官方 Backup 文档。

detach / attach part

手动 DETACH PART 将目录移入 detached/,不参与查询与 merge。排障错误 Part 或迁移数据时使用;attach 前需校验 checksums。

并发 insert 与 block 边界

多客户端 insert 各自形成 Part;无跨客户端单 block 合并。高并发小 insert 是 parts 爆炸主因——应用侧 batch 或 async_insert 缓冲。

OPTIMIZE TABLE FINAL

强制 merge 至单 Part(分区内)并应用 Replacing 等语义。生产大表慎用:IO 峰值、长时间锁表语义以文档为准。更适合维护窗口。

system.parts_columns

逐列 data_compressed_bytesdata_uncompressed_bytescompression_codec——压缩实验应用此表而非猜。见第 3 篇 benchmark 框架。

Mark Cache 与 Primary Index Cache

频繁查询受益 mark_cacheprimary_index_cache(配置与 metric 见文档)。冷查询首次读盘仍取决于 Mark/PK 大小。

ReadInOrder 优化

若查询 ORDER BY 与表排序键一致且无大幅改写,优化器可走 ReadInOrder 减少全量排序内存。与 merge 物理排序强相关。

分布式 DDL 边界

ReplicatedMergeTree 上 ON CLUSTER DDL 通过 distributed DDL queue;与 Part 级复制不同层。第 8 篇聚焦 Part 同步。

Keeper 与 ZooKeeper 差异

24.x 推荐 Keeper(Raft);ZK 路径约定兼容。新集群优先 Keeper,减少 JVM 依赖与 tail latency。

Quorum insert

insert_quorum 要求 N 副本确认 Part;与 async insert 策略互斥需谨慎。金融场景可能启用,吞吐下降。

Recovery 线程

副本 system.replication_queueGET_PART 失败会重试;Broken Part 需人工 SYSTEM DROP REPLICA / 重新同步。监控 last_exception

与 PG 外表对比

PostgreSQL 作源时,MaterializedPostgreSQL 或 CDC 工具写入 MergeTree;PG 仍行存 MVCC,CH 侧 append Part。一致性窗口由复制协议决定。

与 observability ingest

日志写入 CH 常用 Kafka 引擎 + MV(第 10 篇规划)。ingest 侧 batch 大小直接决定 Part 尺寸——与 可观测性系列 管道设计联动。

CPU vs IO bound 判定

高压缩率 + 宽 granule 可能 CPU bound(解压);NVMe 上低压缩可能 IO bound。system.eventsOSIOWait* vs UserTime 辅助判断,需本机 profile。

max_threads 与 cores

max_threads 默认与 CPU 核相关;过大线程增加 Part 并行读开销与内存。HTAP 混部应限制 CH 查询线程池。

内存跟踪

system.metricsMemoryTrackingMergesMutationsMemoryTracking;OOM 前常见 merge 与 big aggregation 同抢内存。

Part 命名与 mutation

mutation 产生 xxx_mutyyy 中间 Part;完成后旧 Part outdated。system.mutationsparts_to_do 反映剩余工作量。

Collapsing 与 VersionedCollapsing

VersionedCollapsing 用 (Sign, Version) 对消;比纯 Collapsing 更适合乱序变更。merge 前查询仍需应用层理解 sign。

SummingMergeTree 列和

仅数值列默认 sum;非键列需显式指定 summing 列。非 sum 列取任意值(merge 确定性规则见文档)。

AggregatingMergeTree 状态

AggregateFunction 状态;查询需 -Merge 组合器。适合预聚合管道,schema 设计门槛高。

GraphiteMergeTree rollup

按时间精度 rollup 规则在 config 定义;监控迁移场景专用。与普通 Summing 不同。

S3 磁盘与冷存

S3 作 disk 时 Part 对象化;读延迟高于本地 SSD。merge 仍发生,网络带宽成为瓶颈。

Replicated 与 S3

零拷贝 replication 到 S3 磁盘配置见官方;副本 fetch 可走对象存储。与第 8 篇 queue 类型相关。

数据倾斜与 PARTITION BY

单分区过大 merge 慢;过多分区 metadata 膨胀。按天/租户合理切分;避免 PARTITION BY rand()

PRIMARY KEY 长度

PK 列过多/long String 增大 primary.idx 与内存。仅前缀必要列;其余放 ORDER BY 后缀或跳数索引。

跳数索引 GRANULARITY 选择

GRANULARITY 过大索引粗;过小索引体积接近逐 granule。默认 1–4 需按列选择性实验(第 7 篇)。

bloom_filter 假阳性

Bloom 仅跳过 granule;假阳性多读 granule 仍正确。无 false negative。

minmax 索引失效场景

列值在 granule 内分布宽但谓词窄,minmax 无法跳过——需更细 ORDER BY 或 bloom。

set 索引大小上限

set 索引 granule 内 distinct 超上限则退化;高基数列不适用 set。

向量索引(边界)

向量相似搜索非 MergeTree 经典跳数索引范畴;24.x 实验特性不在此系列承诺。

Pipeline EXPLAIN 用法

EXPLAIN PIPELINE 展示 Processor 图;与 EXPLAIN indexes=1 互补。本环境无实例不贴输出。

QueryPlan 阶段

Analyzer 产出 QueryPlan,再转 Pipeline。PREWHERE 下推在此阶段决定;SQL 写法影响是否自动 PREWHERE。

Constant 折叠与 primary key

常量谓词与 PK 范围交集在优化期计算;参数化查询仍受益 prepared 边界。

FINAL 与 dedup

ReplacingMergeTree 的 FINAL 在查询期归并;替代方案 MV 去重或应用层 argMax

Lightweight DELETE(版本边界)

较新版本 lightweight delete 标记删除 granule;与 mutation 路径不同。以 24.x 文档为准是否 GA。

Transaction 语义边界

单 insert block 原子;跨 Part 无 MVCC 快照隔离。勿与 PG MVCC 类比。

chDB / clickhouse-local

嵌入式 clickhouse-local 适合 Part 格式实验(第 2 篇);与 server 共用 MergeTree 代码路径。

版本升级与 Part 兼容

大版本升级前查 release notes Part 格式变更;通常向后读旧 Part,merge 逐步重写。

checksum 算法

checksums.txt 使用 CityHash128 等;损坏 Part 拒绝加载保护下游。

Serialization 与类型变更

ALTER MODIFY COLUMN 可能触发 mutation 重写;类型不兼容需中间列。

Dictionary 与外部维表

字典非 MergeTree Part;JOIN 字典与 MergeTree scan 是不同 IO 路径。

Global IN 代价预告

Distributed 上 GLOBAL IN 广播维表(第 9 篇);本地 MergeTree 无此问题。

测试数据 hits 样本

官方 hits 数据集适合验证读路径;下载与导入步骤见 clickhouse.com/docs getting started。

benchmark 伦理

引用外部 benchmark 必须标注来源;自测需 3 轮中位数与环境表(WRITING_GUIDE)。

源码阅读顺序建议

MergeTree:StorageMergeTreeIMergeTreeDataPartMergeTreeReaderWideMergeTreeDataMergerMutator。执行:PipelineExecutorIProcessor

社区与 LTS

24.x LTS 安全/backport 周期见官网;生产锚定 LTS 而非 latest。

system.parts 字段解读

运维读 Part 状态时常用列:databasetablename(目录名)、part_type(Wide/Compact)、rowsbytes_on_diskbytes_on_disk_uncompressedprimary_key_bytes_in_memorymarks_bytes_on_diskleveldata_versionis_frozenactive=0 表示已被 merge 替换但未物理删除。与 LSM SST 层数 类似,应监控每表 active part 数趋势。

system.merges 与 merge 进度

system.merges 展示当前运行中的 merge:databasetableelapsedprogress(0–1)、num_partsresult_part_nametotal_size_bytes_uncompressed。长时间 progress 不动可能磁盘 IO 饱和或单 Part 过大。merge_max_block_size 影响单次归并行数。

system.query_log 读路径指标

启用 query_log 后,read_rowsread_bytesresult_rows 对比可验证索引剪枝是否生效。PREWHERE 优化通常降低 read_bytesread_rows 仍含 granule 内过滤前行数。本系列不在此环境给出样本数值。

参考资料

  1. ClickHouse Documentation, ReplacingMergeTree, CollapsingMergeTree, Mutations
  2. ClickHouse Source, MergeTreeDataMergerMutator.cpp, MergeTreeBackgroundExecutor.cpp
  3. LSM 系列, Compaction

Merge selector

SimpleMergeSelector / TTLMergeSelector 等根据 Part 大小、年龄、分区挑选 merge 任务;目标减少 Part 数且控制写放大。

ReplacingMergeTree

replace 版本列默认 is_deleted 或显式 version;merge 同排序键保留 version 最大。查询仍可能见重复行,除非 FINAL 或应用层去重。

CollapsingMergeTree

Sign 列 +1/-1 表示插入与撤销;merge 折叠成 net 行。适合变更流而非物理 DELETE。

Mutation 路径

ALTER TABLE UPDATE/DELETEMutationCommands 队列 → 后台读 Part 重写新 Part → 原子替换。堆积时 system.mutations 可见;与 merge 争用 BackgroundSchedulePool。 ### index_granularity

两个 Mark 之间最大行数;影响稀疏索引粒度与单次读 granule 行数上限。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):8192

index_granularity_bytes

自适应 granule:限制 granule 预估字节大小,宽行表避免单 granule 过大。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):10485760 (10 MiB)

enable_mixed_granularity_parts

是否启用 index_granularity_bytes 与 index_granularity 混合控制。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):1

min_bytes_for_wide_part

Part 体积超过阈值时使用 Wide 布局(列独立文件)。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):10485760

min_rows_for_wide_part

行数超过阈值转 Wide。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):0

parts_to_throw_insert

活跃 Part 数超过阈值拒绝 insert。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):3000

parts_to_delay_insert

超过阈值开始延迟 insert。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):1000

merge_max_block_size

单次 merge 输出块大小上限。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):8192

max_bytes_to_merge_at_max_space_in_pool

merge 池有空闲时单任务最大字节。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):161061273600

number_of_free_entries_in_pool_to_execute_mutation

mutation 与 merge 共享池时的调度参数。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):见文档

compress_marks

是否压缩 Mark 文件。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):1

compress_primary_key

是否压缩 primary.idx 落盘(内存仍解压使用)。

官方文档默认值(24.x,以实例 system.merge_tree_settings 为准):1

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-06-18 · database / storage

【列存引擎内核】列存基础与 ClickHouse 架构

行存 vs 列存的带宽、压缩与向量化三角;ClickHouse Server 进程模型、线程池与 MergeTree 引擎家族地图;src/Storages 与 src/Processors 源码入口。对照 PG 行存与 LSM 写优化路径,版本锚定 ClickHouse 24.x LTS。

2026-06-18 · database / storage

【列存引擎内核】MergeTree Part 文件格式

ClickHouse MergeTree Part 目录结构:columns.txt、checksums.txt、.bin、.mrk2、primary.idx 语义,Granule 与 Mark 的定位作用,Wide/Compact 布局与 MergeTreeDataPart 源码入口。版本锚定 24.x LTS。

2026-06-18 · database / storage

【列存引擎内核】压缩与编码

ClickHouse 列压缩:LZ4、ZSTD、Delta、DoubleDelta、Gorilla 时序编码与列类型关系;CODEC 链顺序、LowCardinality 与 PG TOAST 对照。压缩比须本机实测,本文不编造倍数。

2026-06-18 · database / storage

【列存引擎内核】向量化执行引擎

ClickHouse Block 列向量 batch、IProcessor Pipeline 与 filter/project/aggregate 向量实现;对照 PostgreSQL 火山模型 ExecProcNode。源码入口 src/Processors、src/Columns。24.x LTS。