ClickHouse v24.5.7.31-stable 稳定版变更解析:九个关键缺陷修复的源码级解读
2026/9/16 14:00:55 网站建设 项目流程

ClickHouse v24.5.7.31-stable 稳定版变更解析:九个关键缺陷修复的源码级解读

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

ClickHouse v24.5.7.31-stable 是 24.5 LTS 分支的一个维护性稳定发布,官方变更日志 v24.5.7.31-stable.md 记录了它相对 v24.5.6.45-stable 的全部九个用户可见的 Bug Fix,涉及 Parquet 读取路径、Schema 推断、日期函数、分布式表虚拟列、Variant 列与聚合函数等模块。本文逐条解读这些修复的具体问题、对应配置项与影响面,并结合当前仓库源码给出实现层面的佐证,帮助你在评估是否升级该版本时准确判断其收益与兼容性变化。

发布概览

该版本对应的提交为6c185e9aec1(基线为 v24.5.6.45-stable 的bdca8604c29),所有条目均标注为 "Backported in #xxxxx",表明它们是通过 backport 流程从 master 回合进 24.5 分支的。变更日志按三个区块组织:

  • Bug Fix (user-visible misbehavior in an official stable release):9 条用户可见缺陷修复,是本次发布的全部内容主体;
  • NO CL CATEGORY:1 条未分类条目(backport PR #68897);
  • NOT FOR CHANGELOG / INSIGNIFICANT:2 条仅测试基础设施的修正(fault injection 开关、flaky 测试修复)。

这意味着这是一个"纯修复"型稳定版:没有新增功能,风险主要集中在个别行为兼容性变化上(后文第 3 节的schema_inference_make_columns_nullable是唯一一处需要关注行为变化的条目)。

日期函数修复:fromModifiedJulianDay 的上界纠正

问题:函数fromModifiedJulianDay把 Modified Julian Day 数值转换为YYYY-MM-DD文本日期。其声明支持的上界本应是9999-12-31,但此前被错误地设置成了9999-01-01,导致 12 月的合法输入被误判为越界。

源码佐证:当前仓库中该函数实现于 fromModifiedJulianDay.cpp,其文档注释明确写道:

This function supports day number from-678941to2973483(which represent 0000-01-01 and 9999-12-31 respectively). It raises an exception if the day number is outside of the supported range.

即合法日号区间为-678941(0000-01-01)到2973483(9999-12-31),越界即抛异常。修复前实现与文档不一致,把9999-01-01当成了上界;修复后与文档注释声明的范围保持一致。对应 backport 追踪单为 #68996,修复 PR 为 #67583。

实战提示:如果你的 ETL 管道中存在依赖fromModifiedJulianDay处理 12 月份数据的逻辑(例如把 MJD 天号批量转成日期分区值),升级此版本后原本会抛异常的任务将恢复正常。

Parquet 读取修复:filter push down 遇到类型不匹配时不再崩溃

问题:当通过file()等表函数读取 Parquet 文件、且显式声明的列类型与文件实际类型差异很大时,Parquet 的 filter push down 路径会发生崩溃。变更日志给出的典型场景是:

SELECT * FROM file('a.parquet', Parquet, 'x String') -- 但文件中 x 实际是 Int64

官方规避手段:在升级到本版本之前,可通过设置input_format_parquet_filter_push_down = 0关闭基于 WHERE/PREWHERE 与 Parquet 元数据 min/max 统计的 row group 跳过,作为临时规避。

源码佐证:当前仓库中该设置的定义见 FormatFactorySettings.h:

DECLARE(Bool, input_format_parquet_filter_push_down, true, R"( When reading Parquet files, skip whole row groups based on the WHERE/PREWHERE expressions and min/max statistics in the Parquet metadata. )", 0)

其默认值为true,即默认启用 row group 级过滤跳过;相邻还有input_format_parquet_bloom_filter_push_down(默认开启)和input_format_parquet_dictionary_filter_push_down(默认 1024×1024 字节阈值)两项同类优化。对应 backport 追踪单 #68865,修复 PR #68131。

实战提示:这条修复对"宽表外部文件 + 显式 schema 声明"的容错能力是实质性提升——声明类型与物理类型不一致(StringvsInt64)不再意味着进程级崩溃。同时建议升级后检查是否还需要保留input_format_parquet_filter_push_down = 0的临时设置,可以安全移除以恢复读放大优化。

Schema 推断行为修正:schema_inference_make_columns_nullable 回归并新增 auto

这是本次发布中唯一一条行为兼容性相关的变更,需要重点理解:

  • 此前 PR #61984 引入的改动使得即使设置schema_inference_make_columns_nullable = 0,Parquet/Arrow 格式推断出的列仍可能变成Nullable,属于向后不兼容的行为漂移;
  • 本版本将其恢复为"0 = 永不推断 Nullable"的旧语义,同时为该设置引入新值auto:仅当数据中带有可空性信息(样本中出现 NULL,或文件元数据声明了可空性)时才推断Nullable

源码佐证:当前仓库中该设置的完整取值语义在 FormatFactorySettings.h 中有权威定义:

DECLARE(UInt64Auto, schema_inference_make_columns_nullable, 3, R"( Controls making inferred types `Nullable` in schema inference. Possible values: * 0 - the inferred type will never be `Nullable` (use input_format_null_as_default to control what do do with null values in this case), * 1 - all inferred types will be `Nullable`, * 2 or `auto` - the inferred type will be `Nullable` only if the column contains `NULL` in a sample that is parsed during schema inference or file metadata contains information about column nullability, * 3 - the inferred type nullability will match file metadata if the format has it (e.g. Parquet), always Nullable otherwise (e.g. CSV). )", 0)

注意两点:类型是UInt64Auto(因此auto字符串可被接受),且当前仓库的默认值已是 3(跟随文件元数据)——这是 24.5 分支之后 master 继续演进的默认值,24.5.7.31 本身并未改变默认值,只是恢复了0的语义并让auto成为可用的显式选择。

实战提示

  • 显式使用= 0且依赖"绝不出现 Nullable"的下游逻辑,升级后可放心;
  • 介于"全 Nullable"与"永不 Nullable"之间、希望由数据本身决定的场景,可以改用= auto(或= 2)。

分布式查询修复:嵌套子查询中的 DateTime64 小常量不再被错误转成 Null

问题:分布式查询(Distributed 表场景)中,嵌套子查询返回的小型 DateTime64 常量会被错误地转换(transform)为 Null,进而导致查询报错甚至返回不正确的结果。这是变更日志中明确标注"possible incorrect query results"的严重性级别。

影响面:跨节点查询中,只要查询计划触发了嵌套子查询常量下推/提升路径、且常量为 DateTime64 小值(如toDateTime64('2024-01-01')之类),都可能命中该缺陷。对应 backport 追踪单 #68882,修复 PR #68323,同时关闭了长期存在的缺陷单 #50868。

实战提示:如果你的集群在 24.5 早期版本上出现过"同一查询本地正确、走 Distributed 表报错或结果偏 Null"的现象,且涉及 DateTime64,优先排查本条。

分布式表虚拟列回归:_table 与 _database 恢复

问题:虚拟列_table_database在 24.3 版本之前一直可用(用于在查询 Distributed 表时标识数据来自哪个库/表),之后一度缺失。本版本将其重新加回。

实战提示:依赖_table/_database做多租户审计、来源统计的查询(例如SELECT _table, count() FROM distributed_table GROUP BY _table)升级后可直接恢复使用,无需再借助SETTINGS distributed_table_function_*之类的替代写法。对应 backport 追踪单 #69023,修复 PR #68672。

Variant 列修复:permutation 时的尺寸校验错误

问题:对 Variant 列做行重排(permutation,常见于ORDER BY物化、EXCHANGE等算子)时可能抛出错误:

Size of permutation (0) is less than required (...)

错误信息中 permutation 尺寸为 0,说明 Variant 列在某些路径下没有正确实现 permutation 的尺寸契约。修复后该报错路径被消除。对应 backport 追踪单 #68858,修复 PR #68681。

实战提示:如果你已启用 Variant 列(实验性数据类型)并且排序大结果集时偶发此异常,本版本可直接解决。

哈希函数修复:sipHash(64/128)Keyed 的物化常量键

问题:在"以含数组为键的 Map 参与哈希"的场景下,sipHash64Keyed/sipHash128Keyed遇到物化常量键(materialized constant key)时处理不正确,导致哈希结果异常。

源码佐证sipHash系列函数实现在 src/Functions/ 目录中(如 sipHash 相关实现文件),函数族由 FunctionFactory 统一注册;本条修复针对的是常量列在 Map-contains-array 键路径上参与 keyed 哈希时的取值。对应 backport 追踪单 #68784,修复 PR #68731。

实战提示:影响面相对窄,主要波及"常量键 + 复杂 Map 键 + keyed 哈希"三者同时出现的查询(例如对sipHash64Keyed(mapColumn, constKey)做去重或分桶)。常规无键哈希不受影响。

聚合函数修复:anyHeavy 状态合并可能产生错误结果

问题:近似去重/近似计数聚合函数anyHeavy状态合并(partial state merge,即两阶段聚合的第二阶段)时可能返回错误结果。这类缺陷在单机小数据量下不易暴露,只在分布式/预聚合的分片状态合并时才显现。

对应 backport 追踪单 #69154,修复 PR #68950。

实战提示:如果你用anyHeavy做高基数近似 Top-N 且跨分片运行,建议升级;对结果精度敏感的关键报表可临时用精确集合聚合交叉验证。

其余修复与工程类条目

  • indexHint 大小写问题:fuzzer 发现的indexHint函数大小写处理缺陷,backport 追踪单 #68564,PR #66286。涉及通过 indexHint 指定数据跳索引的查询解析。

  • 无分类条目:backport 单 #68940 / PR #68897,日志未给出描述("NO CL CATEGORY")。

  • 测试基础设施(NOT FOR CHANGELOG):

    • 关闭测试01396_inactive_replica_cleanup_nodes_zookeeper中 insert 的 fault injection(#68828 / PR #68715);
    • 修复01114_database_atomic的不稳定(flaky)表现(#69046 / PR #68930)。

    这两条不影响用户行为,说明该稳定版同时清理了 CI 侧的测试噪声。

修复条目与 backport 追踪单对照表

模块问题摘要Backport 单修复 PR
Functions/indexHintfuzzer 发现的大小写缺陷#68564#66286
Functions/fromModifiedJulianDay上界误设为 9999-01-01#68996#67583
Parquet reader类型不匹配时 filter push down 崩溃#68865#68131
Schema inferencemake_columns_nullable=0行为回归 + 新增auto#69004#68298
Distributed嵌套子查询 DateTime64 小常量被转为 Null#68882#68323
Distributed恢复_table/_database虚拟列#69023#68672
Variant 列permutation 尺寸校验报错#68858#68681
sipHash(64/128)Keyed物化常量键 + 数组键 Map 哈希错误#68784#68731
anyHeavy状态合并可能产生错误结果#69154#68950

升级评估小结

v24.5.7.31-stable 是一个纯缺陷修复的稳定版,适合 24.5 用户直接跟进。按影响面排序,最需要关注的是:

  1. Distributed 场景下 DateTime64 常量被转 Null——唯一可能已造成"错误结果"的条目;
  2. Parquet 类型不匹配崩溃——外部文件读取容错性提升;
  3. schema_inference_make_columns_nullable语义修正——唯一涉及行为变化的条目,0恢复旧语义、auto成为新选项(注意当前 master 默认值已演进为3,见 FormatFactorySettings.h,升级时以实际部署版本的设置默认值为准)。

其余条目(_table/_database虚拟列回归、Variant permutation、sipHashKeyed、anyHeavy、indexHint、MJD 日期上界)均为窄而明确的正确性修复。变更日志原文及各条目引用的源码路径(fromModifiedJulianDay.cpp、FormatFactorySettings.h)可在仓库中直接查阅复核。

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

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

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

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

立即咨询