ClickHouse v24.6.3.95-stable 发布解读:从 Analyzer 兼容控制到 JSONMergePatch 栈溢出防护的 30+ 项修复详解
2026/9/16 20:21:33 网站建设 项目流程

ClickHouse v24.6.3.95-stable 发布解读:从 Analyzer 兼容控制到 JSONMergePatch 栈溢出防护的 30+ 项修复详解

【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse

本篇围绕 ClickHouse 24.6 分支的补丁版本 v24.6.3.95-stable(对应提交 8325c920d11,前一版本为 v24.6.2.17-stable,提交 5710a8b5c0c)的官方变更记录展开,完整覆盖其 1 项功能改进、6 项严重缺陷修复与 20 余项用户可见缺陷修复。读完后,你将掌握该版本每类修复所解决的具体问题、影响面与适用前提,并能结合源码(如 JSONMergePatch 函数实现、cgroups v2 CPU 配额检测逻辑)理解修复的底层原理,从而做出有依据的 24.6 线上升级决策。

一、版本定位:24.6 维护分支的补丁级升级

本版本的变更记录归档于 docs/changelogs/archive/v24.6.3.95-stable.md,其标题明确给出对比基线:v24.6.3.95-stable (8325c920d11) 相对 v24.6.2.17-stable (5710a8b5c0c)。这是一次典型的 LTS 风格分支补丁发布——所有条目均以 “Backported” 形式从主干回合而来,不涉及新功能面,只涉及正确性、稳定性与兼容性。

从条目构成看,本次发布的重点集中在四条主线:

  1. 新旧 Analyzer(查询分析器)兼容与稳定性:混部集群中allow_experimental_analyzer的发起端控制,以及多个针对新 Analyzer 误报错误的修复;
  2. JSON 与标量函数的安全性JSONMergePatch栈溢出防护与函数更名、unbin/unhex缓冲区溢出修复;
  3. 分布式与复制链路的正确性:分布式查询缺数据、Distributed异步插入崩溃、TRUNCATE DATABASE停止复制等;
  4. 运行环境感知:容器内 cgroups v2 CPU 限制识别。

对于运行 24.6 生产环境的团队,该版本值得升级的核心理由在于:它同时修复了可能触发崩溃(SIGSEGV / 栈溢出)的多个问题,以及 ZooKeeper 会话进入不可用状态这类“半死”故障。

二、功能改进:分布式查询中 allow_experimental_analyzer 由发起端控制

本次唯一的 Improvement 条目(PR #65777,Backport 追踪 issue #66770):allow_experimental_analyzer在分布式查询中由查询发起端(initiator)来控制,以保证混版本集群(mixed version clusters)操作期间的兼容性与正确性。

这条改动的背景是:ClickHouse 正处在旧 Analyzer(interpret_*链路)与新 Analyzer(基于Analyzer/QueryTree)并存的过渡期。在分布式查询场景下,查询由发起节点分发到各 shard 节点执行;如果各节点依据本地配置决定使用哪个 Analyzer,就会出现“发起端用新 Analyzer 生成查询计划、某个工作节点用旧 Analyzer 解释”的错配,轻则语义不一致,重则在跨版本滚动升级期间产生难以定位的结果偏差。改为由发起端统一控制后,同一分布式查询在各节点使用相同的解析器路径,混版本滚动升级的窗口期行为变得可预期。

实践建议:在滚动升级 24.6 集群期间,若曾显式调整过allow_experimental_analyzer,应确保该设置在查询发起端(通常是接入层的 proxy 节点或负载均衡后发起查询的节点)统一定义,避免各节点配置漂移。

三、严重缺陷修复(Critical Bug Fix)逐项解析

官方将以下 6 项归类为 Critical,即涉及崩溃、LOGICAL_ERROR、数据丢失或 RBAC 的缺陷。

3.1 修复函数调用中 LowCardinality 列尺寸异常(PR #65298)

“Fix unexpected size of low cardinality column in function calls”——在函数调用路径中,LowCardinality 列的字典/偏移结构尺寸可能不符合预期,导致后续计算出错。LowCardinality 是 ClickHouse 对低基数字符串列的高压缩存储编码,几乎所有字符串处理函数都会触及它的包装/解包逻辑;该修复对使用LowCardinality(String)的宽表(日志、事件流场景)稳定性有直接收益。

3.2 修复用户定义中 VALID UNTIL 子句在重启后失效(PR #66409,关闭 #66405)

SQL 用户管理支持CREATE USER ... VALID UNTIL 'timestamp'设置账号有效期。修复前,服务重启后有效期约束会被重置,属于认证/RBAC 层面的正确性问题——一个本应到期的账号可能在重启后“复活”。升级到本版本后,VALID UNTIL约束在重启后依然生效。

3.3 修复 Variant + AggregateFunction 组合崩溃(PR #67122)

官方明确标注“Only relevant to the experimental Variant data type”:实验性 Variant 数据型与AggregateFunction类型叠加使用时会触发崩溃。若你的 schema 未使用 Variant,此条目可忽略;若已在评估 Variant,本版本是该组合的一个必要的稳定性门槛。

3.4 修复 DistributedAsyncInsert 连接为空时的崩溃(PR #67219)

Distributed引擎表的异步插入(async insert)路径中,当连接(connection)为空时会崩溃。这通常出现在目标表所在 shard 的连接尚未建立或已关闭的时序窗口内,属于高可用敏感路径:异步插入失败不应以进程崩溃的形式出现。

3.5 避免 ReplaceTableNodeToDummyVisitor 遍历未解析的表函数参数(PR #67522,修复 #66026)

新 Analyzer 的ReplaceTableNodeToDummyVisitor在遍历查询树时,可能进入“尚未解析的表函数参数”分支并出错。该修复让访客跳过这些未解析节点,属于 Analyzer 计划生成阶段的健壮性修复,通常对应某些“查询报错但语法正确”的边缘用例。

3.6 JSONMergePatch:栈溢出防护 + 函数更名 + 错误诊断改进(PR #67756,关闭 #67304)

这是本版本信息量最大的一条修复,且仓库当前源码可以完整印证其修复手法。函数实现在 src/Functions/jsonMergePatch.cpp:

  • 防栈溢出的第一道防线:解析阶段强制使用迭代式(非递归)解析器——源码中通过#define RAPIDJSON_PARSE_DEFAULT_FLAGS (kParseIterativeFlag)(src/Functions/jsonMergePatch.cpp#L14-L15)使 RapidJSON 以迭代方式解析,避免恶意/畸形深层 JSON 在解析期耗尽线程栈;
  • 第二道防线:显式深度校验。由于合并(merge)与序列化阶段仍是对文档树做递归遍历,源码在解析完成后调用checkJSONDepth做一次迭代式深度检查,超过max_json_merge_patch_depth = 1000即抛出TOO_DEEP_RECURSION异常(src/Functions/jsonMergePatch.cpp#L47-L66)。注释也明确说明了设计意图:“a valid but deeply nested document would exhaust the thread stack. Reject such documents right after parsing; the check itself is iterative.”;
  • 函数更名:函数从jsonMergePatch更名为JSONMergePatch(原名大小写不符合函数命名惯例),并在 src/Functions/jsonMergePatch.cpp#L214-L244 中注册——REGISTER_FUNCTION(JSONMergePatch)之外另有factory.registerAlias("jsonMergePatch", "JSONMergePatch"),即旧名字作为别名保留兼容。存量 SQL 无需改动,新写 SQL 建议使用标准名JSONMergePatch
  • 错误诊断改进:对非法 JSON 输入的报错信息做了增强,便于定位具体出错字段。

该函数语法为JSONMergePatch(json1[, json2, ...]),即按 RFC 7396 merge patch 语义对多个 JSON 文档做链式合并(src/Functions/jsonMergePatch.cpp#L220)。

四、用户可见缺陷修复:按主题分组详解

官方共列出 20 余个 Bug Fix 条目。为便于检索引用,这里按主题分组,保留每条的具体问题与 PR 编号。

4.1 JOIN 条件与 NULL 语义

  • IS NULLjoin 条件的优化改写(PR #65835):对形如ON (a = b AND (a IS NOT NULL) AND (b IS NOT NULL)) OR ((a IS NULL) AND (b IS NULL))的 join 条件,现在能正确识别为 NULL 安全相等语义并改写为ON a <=> b;同时修复了当条件中还存在非IS NULL子句时发生的不正确优化。这是典型的“语义等价改写”优化,<=>即 NULL-safe equality,a <=> b在两边同为 NULL 时返回 true,避免 JOIN 中 NULL 行被丢弃的经典陷阱;
  • 配套测试与扩展支持:PR #66310 禁用了02911_join_on_nullsafe_optimization测试中仍会失败的用例,PR #66725 又为JOIN ON ... IS NULL增加了一种可识别的情形(归入 NOT FOR CHANGELOG)。

4.2 Analyzer(新旧)正确性

这一组是条目最密集的部分,多数错误仅在新 Analyzer(或仅旧 Analyzer)路径下触发:

  • “Not-ready set” 报错(PR #66261):约束(constraint)中使用带IN的子查询时误报 “Not-ready set” 错误;
  • “Column identifier is already registered”(PR #66400)group_by_use_nulls=true加新 Analyzer 组合触发列标识符重复注册错误;
  • “Cannot find column”(PR #66433)GROUP BY键中出现常量表达式且启用新 Analyzer 时误报找不到列;
  • “Unknown identifier” / “Column is not under aggregate function”(PR #66654):查询含(column IS NULL)表达式时误报,该 bug 由 #65088 引入,且仅在禁用 Analyzer(旧链路)时触发——这是少数明确标注“旧 Analyzer 独有”的回归修复;
  • “Method getResultType is not supported for QUERY query node”(PR #66655):新 Analyzer 下,标量子查询作为IN的第一个参数时误报;
  • DDL 依赖解析(PR #66395,NOT FOR CHANGELOG)DDLLoadingDependencyVisitor现在会忽略约束/依赖收集中的IN子查询,避免加载阶段的依赖误判。

4.3 查询执行与优化器

  • merge-filters优化被禁用(PR #66126):#64760 引入的 filter 合并优化在把两个过滤表达式合并后不做短路求值(short-circuit evaluation)时可能抛出异常,本版本选择直接禁用该优化。从源码结构看,这类“先禁优化、后修复”的处理是 ClickHouse 优化器回归的惯用节奏——正确性优先于计划形状优化;
  • 嵌套短路函数执行(PR #67520):修复嵌套 short-circuit 函数(如multiIf/nullIf组合)的执行错误,与上一条同属“短路求值”主题;
  • SumIfToCountIfVisitor与有符号整数(PR #66146)sumIfcountIf的计划改写对有符号整数类型处理有误,导致结果错误;
  • system.numbers_mt的 limit 处理(PR #66231):当无法使用索引时,system.numbers_mt表函数对LIMIT的处理不正确;
  • WINDOW 查询的并行执行错误结果(PR #66579):当PARTITION BY列使用稀疏(sparse)序列化且窗口函数并行执行时,可能返回错误结果——这是少数被归类为“结果错误”而非报错的问题之一,使用窗口函数的用户应优先升级;
  • 常量列类型转换报错(PR #67146)Merge表套Distributed表且只有一个 shard 时,误报 “Cannot convert column because it is non constant in source stream but must be constant in result.”;
  • 回归修复(PR #67178,关闭 #67156 与 #66447):修复 #62907 引入的缺陷(条目未展开细节,属于上游 PR 描述沿用)。

4.4 内存安全与内存跟踪

  • unbin/unhex缓冲区溢出(PR #66106):十六进制转二进制串的实现存在 buffer overflow,属于内存安全缺陷,涉及unbin/unhex函数的用户应升级;
  • 空元组哈希读取未初始化内存(PR #66562,关闭 #66559):对空 tuple 做哈希时会读到未初始化内存,可能引起结果不确定或 sanitizer 报警;
  • Allocator::realloc内存跟踪(PR #66548)realloc路径未正确更新内存跟踪,导致system.processes/memory tracking 口径偏差;另有 PR #66820 对 realloc 跟踪做小幅跟进修正(NOT FOR CHANGELOG)。

4.5 分布式、复制与 ZooKeeper

  • 分布式查询偶发缺数据(PR #66174,关闭 #61432):修复分布式查询结果中罕见的数据丢失,这是影响数据完整性的修复;
  • ZooKeeper 会话“卡死”(PR #66140):ZooKeeper 客户端在收到来自 ZooKeeper 的硬件错误后,会话可能长期停留在不可用状态。典型触发场景是 **ClickHouse Keeper 的“soft memory limit”(软内存限制)**把客户端“挤出”会话——修复后会话可以正常恢复而不是僵死;
  • TRUNCATE DATABASE不再中断复制(PR #67129):此前TRUNCATE DATABASE会像DROP DATABASE一样导致复制停止,这是 Replicated 数据库用户的重大行为修正;
  • distributed_ddl_output_modenone_only_active模式(PR #66218):该模式下不再误抛TIMEOUT_EXCEEDED错误;
  • Context::getDDLWorker偶发死锁(PR #66843):DDL Worker 获取路径上的锁使用方式导致偶发死锁,修复后 DDL 并发执行更稳。

4.6 容器环境:cgroups v2 CPU 核心数检测(PR #66237)

官方描述:修复 ClickHouse 服务端在 Docker 等容器中运行时、按 cgroups v2 检测可用 CPU 上限的错误。细节是:容器进程常运行在名为空字符串的根 cgroup中,此前该情况下 ClickHouse 会忽略 cgroups v2 设置的 CPU 限制,导致线程池按宿主机物理核心数扩张、与容器实际配额失配。

仓库当前源码 src/Common/getNumberOfCPUCoresToUse.cpp#L33-L99 中可以看到这套检测逻辑的形态:getCGroupLimitedCPUCores先从进程自身 cgroup 向上逐级读取cpu.max文件(格式quota period,取ceil(quota/period)与当前值的较小者,且不遇首个即停——因为子 cgroup 的上限可能大于父级,需要一路向上取最严约束),再逐级读取cpuset.cpus.effective并按0,2-4,6,9-14这类区间语法统计 CPU 集合大小。对于以 CPU 绑核(cpuset)方式限容的容器,这条路径保证了线程数不超过绑定的核心数。

实践影响:以--cpus或 cgroup v2 CPU quota 限制资源的 ClickHouse 容器,升级后可通过SELECT count() FROM system.processorssystem.metrics中的线程相关指标验证线程池规模是否与配额匹配。

4.7 存储与对象存储周边

  • 磁盘上意外 projection 导致 part 被误判损坏(PR #66898):某些磁盘上的非预期 projection 文件会令 MergeTree part 被判定为 broken,现已修复;
  • 本地存储删除命名集合(named collections)(PR #66599,条目出现两次:#66956 与 #66716):修复本地存储下删除 named collections 的问题。值得注意的是变更记录单列了NO CL ENTRY一节:PR #66922 将 #66599 的 backport 做了 Revert,说明该修复在回合过程中曾引起问题后被撤回重做——最终合入的是重新验证过的版本;
  • S3 指标多盘配置(PR #65403,NOT FOR CHANGELOG):多磁盘配置下获取 S3 指标不再抛NOT_IMPLEMENTED
  • S3::ClientCache数据竞争(PR #66644,NOT FOR CHANGELOG):修复客户端缓存的数据竞争,属于并发安全修复;
  • test_storage_s3_queue不稳定测试(PR #66009,NOT FOR CHANGELOG):测试侧修复,不影响功能行为。

4.8 输入格式与 schema 推断缓存(PR #65980)

schema inference cache(文件输入时的模式推断缓存)此前漏掉了 4 个会改变推断结果的设置项:

  • input_format_csv_skip_first_lines
  • input_format_tsv_skip_first_lines
  • input_format_csv_try_infer_numbers_from_strings
  • input_format_csv_try_infer_strings_from_quoted_tuples

修复前,若同一文件路径先以默认设置触发过推断并缓存了 schema,随后切换上述设置再读,会命中旧缓存导致推断结果与当前设置不符。对“同一批 CSV/TSV 文件、用不同 session 设置分批读取”的数据接入管道,这是一个隐蔽但真实的结果正确性问题。

4.9 其他

  • SQL UDF 重载(PR #67665):含UNION的 SQL UDF 在服务端重启后可能失效,修复了 UDF 重载逻辑;
  • 极小规格服务的 asio 线程池(PR #66761,NOT FOR CHANGELOG):当服务端配置为“tiny”规格时适当调大 asio 线程池,改善小实例下的 IO 并发;
  • CI 日志脱敏(PR #66523)与发布分支构建结果(PR #67402):均为 CI 基础设施条目,对使用者无行为影响。

五、变更日志的组织结构说明

阅读 v24.6.3.95-stable.md 时会注意到四个分区,这反映了 ClickHouse 发布流水线的分类约定:

分区含义本版本条目数
Improvement行为改进(非新功能)1
Critical Bug Fix崩溃、LOGICAL_ERROR、数据丢失、RBAC 类缺陷6
Bug Fix稳定版中用户可见的错误行为22
NO CL ENTRY不入变更日志(本版本为一次 Revert)1
NOT FOR CHANGELOG / INSIGNIFICANT测试、CI、内部健壮性修复11

其中 “NO CL ENTRY” 一节在本版本中仅含 PR #66922(对 named collections 修复的回滚)。该条目的存在提示:24.6 分支在这一时间点的 named collections 相关代码经历过一次“修复—回滚—重做”的往返,如果你在该功能上遇到过诡异行为,升级到包含最终版本的更高 24.6 补丁更稳妥。

六、升级建议与验证要点

基于本版本条目分布,给出可操作的升级判断:

  1. 必升场景:使用LowCardinality列函数调用、Variant + AggregateFunction、Distributed异步插入、unbin/unhexTRUNCATE DATABASE+ Replicated 数据库、窗口函数(并行执行 + 稀疏序列化分区列)——这些路径在本版本前存在崩溃或错误结果风险;
  2. RBAC 敏感场景:依赖CREATE USER ... VALID UNTIL做账号到期管理的,必须升级,否则重启会导致到期约束失效;
  3. 容器化部署:在 cgroups v2 内核/Docker 上以 CPU quota 限制运行的,升级后应核对服务端感知到的核心数与配额一致(可查system.metrics与日志中 CPU 相关初始化信息);
  4. 混版本滚动升级:升级窗口内注意allow_experimental_analyzer的控制点应统一在查询发起端,避免新旧 Analyzer 跨节点错配;
  5. 验证方式:可在灰度节点用 tests/queries 下对应主题的既有测试(如02911_join_on_nullsafe_optimization系列 JOIN NULL 安全用例、S3 队列存储测试)作为行为回归参照,仓库自带测试基线可用于升级后的自检。

综上,v24.6.3.95-stable 是一个以正确性与稳定性为绝对主题的补丁版本:没有任何功能面扩张,但覆盖了从查询解析(Analyzer 双链路)、执行优化(filter 合并、NULL 安全 JOIN 改写)、内存安全(unbin/unhex 溢出、JSONMergePatch 栈溢出)到基础设施感知(cgroups v2、ZooKeeper 会话恢复)的完整修复谱系,适合作为 24.6 线上集群的常规升级目标。

【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询