ClickHouse v22.6.4.35-stable 发布解读:分布式写入、内存管控与存储引擎的关键修复
【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse
导读
本文以 ClickHouse 官方仓库中的 v22.6.4.35-stable 发布说明 为骨架,逐条解析该补丁版本(patch release)所包含的构建改进与用户可见 bug 修复。v22.6.4.35 是 22.6 稳定分支上的第四个小版本,主要针对Distributed表异步插入、S3 并行读取、文件系统缓存(File Cache)、OvercommitTracker 内存调度以及 RabbitMQ / PostgreSQL 表引擎的已知问题进行收口。读者通过本文可以掌握:每个修复对应的复现场景、涉及的核心模块与源码位置,以及如何结合仓库源码验证与规避这些问题。
版本概览:从一个补丁版本看 ClickHouse 的发布节奏
该发布说明的开头标识了版本比较基线:
ClickHouse release v22.6.4.35-stable (b9202cae6f4) FIXME as compared to v22.6.3.35-stable (d5566f2f2dd)这说明 v22.6.4.35-stable 是相对上一个补丁版本 v22.6.3.35-stable 的增量发布(文件中的 "FIXME" 为 changelog 模板遗留标记)。从仓库中 docs/changelogs/archive 目录可以看到,ClickHouse 以v22.6.x.y-stable的形式维护稳定分支的滚动补丁:主干(master)持续迭代新功能,而稳定分支只合入经过 backport(回移植)的修复,保证生产环境可以在不升级大版本的前提下获得关键 bug 修复。
本版本内容被归类为三类:
| 类别 | 含义 | 本版本条目数 |
|---|---|---|
| Build/Testing/Packaging Improvement | 构建、测试与打包改进 | 1 |
| Bug Fix (user-visible misbehavior in official stable release) | 官方稳定版中用户可见的错误行为修复 | 9 |
| NOT FOR CHANGELOG / INSIGNIFICANT | 内部改动与无足轻重的调整 | 4 |
其中 "Bug Fix" 是核心部分,下文逐一展开。
打包与发布体系改进:架构相关包与多平台发布
将all|noarch包改为架构相关包
本版本包含一条构建侧改进(backport 自 PR #38580):
- 将
all|noarch(架构无关)包改为架构相关(architecture-dependent)包; - 同步修正了相关文档说明;
- 开始向 Artifactory 与发布资产(release assets)推送 aarch64/arm64 包。
这一改动说明 ClickHouse 的发行渠道开始更严格地区分x86_64与arm64平台产物,避免把架构无关的元数据包误装到不兼容平台。仓库中 packages 目录下的clickhouse-server.yaml、clickhouse-common-static.yaml等打包配置即为该体系的实际载体。
CI 基建的配套演进
发布说明的 "NOT FOR CHANGELOG" 部分还有三条与 CI 相关的改动,共同支撑上述发布体系:
- 使用原生
Map类型存储 OpenTelemetry attributes(PR #38814); - Docker
buildx命令在失败后以递增睡眠间隔重试(PR #38898); - 将
docker_server.py的运行纳入 backport 与 release CI(PR #39011。
Distributed 表引擎:异步插入稳定性修复
场景一:从配置中移除副本时异步插入崩溃
问题:Distributed表在执行异步插入时,如果恰好有副本(replica)被从配置中移除,可能触发崩溃。
修复:backport PR #38029,确保在连接池刷新、副本集合变化的窗口期内不会访问已失效的副本连接。
源码佐证:Distributed表的异步插入由 src/Storages/Distributed/DistributedAsyncInsertDirectoryQueue.cpp 实现。其核心工作流是:processFiles()→processFile(),后者读取本地落盘的DistributedAsyncInsertHeader,然后通过ConnectionPoolWithFailover::getManyCheckedForInsert(...)从连接池取连接发送数据(见 processFile 附近逻辑)。连接池在 createPool 中按Cluster::Addresses构建,当 config 中副本集合变化时,旧池中的连接会失效,本修复保证了这一并发窗口内的安全性。
场景二:extremes = 1时物化视图插入报Block structure mismatch
问题:向挂有MATERIALIZED VIEW的表执行 INSERT,且开启设置extremes = 1时,会报错Block structure mismatch。
修复:backport PR #39125,修复了 extremes 信息在物化视图投影链中被错误附加到数据块导致结构不匹配的问题。
背景知识:extremes是 ClickHouse 查询设置(默认 0),开启后结果集末尾会附带一列极值信息。当数据流经过MATERIALIZED VIEW的转换管道(Processors链)时,需要正确剥离这些附加信息;该修复保证了在 src/Processors 的 pipeline 中数据块结构的一致性。
场景三:PREWHERE与 read-in-order 优化组合报Not found column Type in block
问题:SELECT同时使用PREWHERE和 read-in-order 优化时,报错Not found column Type in block。
修复:backport PR #39157。read-in-order 优化(按ORDER BY主键顺序读取)与PREWHERE的列裁剪逻辑叠加时,用于PREWHERE的列在块中被提前移除,本修复保证了执行顺序的正确性。
内存管理:OvercommitTracker 死锁与日志修复
问题描述
OvercommitTracker(过度提交跟踪器)内部发生任何内存分配都可能引发死锁,而当时的日志又不够有信息量,导致问题难以排查(issue #37794)。
修复方式
backport PR #39030:直接移除 OvercommitTracker 路径中的日志调用,避免"在内存管控路径里分配内存"的循环依赖。
源码原理
src/Common/OvercommitTracker.h 完整展示了该机制的内部结构:
OvercommitRatio以committed / soft_limit的形式比较各查询的内存使用强度,比较时使用交叉相乘(a*d < c*b)避免浮点误差;- 软限制(soft limit)是查询/用户保证可用的内存量,允许被超过;一旦硬限制(hard limit)达到,系统会挑选 overcommit ratio 最大的查询杀掉以释放内存;
- 内部使用
SharedMutex overcommit_m与condition_variable_any cv同步挑选过程,并通过next_id/id_to_release批量唤醒等待线程; OvercommitTrackerBlockerInThread是一个 thread_local 计数器,用于在日志期间禁止内存跟踪,这正是为避免死锁而设计的隔离机制——本版本修复将其贯彻到 OvercommitTracker 自身的日志中。
等待与唤醒逻辑在 src/Common/OvercommitTracker.cpp 中:线程通过cv.wait_for(lk, max_wait_time, ...)等待,并记录ProfileEvents::MemoryOvercommitWaitTimeMicroseconds事件,便于观测内存过载时的等待时长。
S3 与远程存储:并行读取与文件系统缓存修复
修复一:并行读缓冲下的 S3 seekable 读取
问题:使用并行读取缓冲(parallel read buffer)进行 S3 seekable 读取时存在缺陷,会影响查询期间的内存占用(issue #38258)。
修复:backport PR #38802,其中 PocoHTTPClient.cpp 实现了基于 POCO 的 HTTP 客户端,支持限速器(readLimiter/writeLimiter)与重试逻辑。并行读取缓冲(对应 src/IO/ReadBufferFromRemoteFSGather 系列实现)在多段 seek 时需保证各段偏移与缓冲状态一致,本修复收口了这一场景下的内存异常增长。
修复二:文件系统缓存容量触顶时的边界 bug
问题:文件系统缓存(File Cache)在缓存容量恰好触顶的边界场景下可能出错(issue #39066)。
修复:backport PR #39070。
源码佐证:文件系统缓存的实现位于 src/Interpreters/FileCache,核心文件包括 FileCache.cpp(容量与淘汰主逻辑)、EvictionCandidates.cpp(淘汰候选收集)以及 LRUFileCachePriority.cpp / SLRUFileCachePriority.cpp(淘汰策略)。配置参数在 FileCacheSettings.cpp 中定义,关键项包括:
max_size:最大缓存容量(与max_size_ratio_to_total_space二选一,不能同时指定);max_elements:最大缓存元素数(即文件段数量,限制磁盘上的文件个数);max_file_segment_size:单个文件段的最大尺寸;boundary_alignment:文件段对齐边界,且不得超过max_file_segment_size(源码中对该约束有显式校验)。
当缓存写入恰好越过容量上限时,淘汰逻辑需要保证"先释放、后写入"的顺序一致,本修复处理的正是这一边界竞态。
第三方依赖:simdjson 升级
修复:更新simdjson库,修复 issue #38621(PR #38838)。
背景:simdjson 是 ClickHouse 在解析 JSON 相关格式(如JSONEachRow、JSONObjectEachRow)时使用的高性能 SIMD JSON 解析器,仓库依赖声明位于 contrib/simdjson-cmake。升级第三方解析库属于典型的补丁版本操作:不改变 ClickHouse 自身接口,但消除底层解析器的已知缺陷。
设置项解析:秒单位的设置 profile 修复
问题:以"秒"为单位的设置 profile 解析存在错误。
修复:backport PR #38896。
背景:ClickHouse 中时长类设置(如max_execution_time、lock_acquire_timeout等)支持s/ms/min等单位后缀。设置 profile(在users.xml中定义、可被角色或用户引用)在解析这类带单位的值时,此前版本存在单位换算问题,本修复统一了 profile 解析与直接设置时的单位处理逻辑。相关实现位于 src/Core/Settings.cpp 与 src/Interpreters 的设置校验代码中。
表引擎修复:RabbitMQ 与 PostgreSQL
RabbitMQ:不再声明默认队列参数
问题:创建 RabbitMQ 队列时默认声明了x-max-length和x-overflow参数。
修复:backport PR #39259,取消默认参数声明,避免与 RabbitMQ 服务端配置冲突。
源码佐证:src/Storages/RabbitMQ/StorageRabbitMQ.cpp 中定义了完整的 RabbitMQ 队列设置白名单,用户可通过表参数rabbitmq_queue_settings_list显式控制,例如:
rabbitmq_queue_settings_list = 'x-dead-letter-exchange=my-dlx,x-max-length=10,x-overflow=reject-publish'可用的设置包括:x-max-length、x-max-length-bytes、x-message-ttl、x-expires、x-priority、x-max-priority、x-overflow、x-dead-letter-exchange、x-queue-type。同时队列的durable属性会自动开启(见 declareQueue 调用)。本修复的意义在于:不再由 ClickHouse 强加默认值,而是完全交由用户在rabbitmq_queue_settings_list中按需声明。
PostgreSQL 数据库引擎:修正表列表查询语句
问题:PostgreSQL 数据库引擎(PostgreSQLdatabase engine)获取远程表列表的 SQL 语句不正确,导致部分表无法被发现(issue #33502)。
修复:backport PR #39283。
源码佐证:PostgreSQL 相关实现位于 src/Storages/PostgreSQL。其中 MaterializedPostgreSQLConsumer.cpp 承担物化消费逻辑,而表列举/发现逻辑依赖查询远程information_schema/pg_catalog元数据。修复后,远程表中包含特殊字符(如大写字母、点号)或位于非默认 schema 时,均能被正确列举并映射到 ClickHouse 表。
如何验证与回退
验证修复是否生效
- 版本确认:执行
clickhouse-server --version或查询system.build_options,确认版本号为v22.6.4.35-stable(对应 commitb9202cae6f4)。 - 针对性复测:
- 分布式插入:配置
Distributed表并反复增删副本后持续异步插入,观察是否出现崩溃; - 物化视图:对挂有
MATERIALIZED VIEW的表执行INSERT ... SELECT并开启SET extremes = 1,确认不再报Block structure mismatch; - S3:对 S3 表启用并行读取(相关设置位于
s3磁盘配置与查询设置中)后跑大查询,观察内存占用是否稳定; - RabbitMQ:以默认参数创建队列,确认队列不再携带
x-max-length/x-overflow默认值。
- 分布式插入:配置
配置回退建议
- 若文件系统缓存容量边界问题仍可复现,可检查 FileCacheSettings.cpp 中
max_size、max_elements、max_file_segment_size与boundary_alignment的取值组合,确保淘汰边界与段对齐设置匹配; - 若 OvercommitTracker 相关查询被误杀,可复查
memory_overcommit相关设置与max_memory_usage/max_memory_usage_for_user的软硬限制配比(相关实现见 src/Common/MemoryTracker.h)。
小结
v22.6.4.35-stable 作为一个补丁版本,体现了 ClickHouse 稳定分支维护的核心原则:只合入经过验证的 backport,聚焦用户可见的错误行为,不引入新功能。本版本覆盖了分布式写入路径的崩溃、内存管理路径的死锁、远程存储读取与缓存边界、第三方解析库升级以及两个表引擎的交互细节,配合构建与发布体系的架构化改进,为 22.6 生产用户提供了一次低成本、高收益的升级机会。读者在升级后,可结合本文列出的源码路径(src/Storages/Distributed、src/Common/OvercommitTracker.*、src/Interpreters/FileCache、src/Storages/RabbitMQ、src/Storages/PostgreSQL)进行针对性回归验证。
【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考