ClickHouse v25.10.4.104-stable 发布详解:投影参数兼容开关、JSON 动态子列合并上限与 50+ 项修复
2026/9/17 23:19:21 网站建设 项目流程

ClickHouse v25.10.4.104-stable 发布详解:投影参数兼容开关、JSON 动态子列合并上限与 50+ 项修复

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

本篇技术指南基于 ClickHouse 官方仓库中的 v25.10.4.104-stable 变更日志,系统梳理该稳定版相比上一版本 v25.10.3.100-stable 引入的向后不兼容变更、新特性、性能改进与全部修复项,并深入源码验证关键设置与实现。读完本文,你将掌握新版本的核心变化、各设置的作用机制与适用场景,以及升级前需要评估的兼容性要点。

版本概览与定位

v25.10.4.104-stable(源码提交5051266d584)是 ClickHouse 25.10 系列的一个稳定修复版本,其对比基准为v25.10.3.100-stable(源码提交1e703eae565)。该版本以「修复为主、稳字当头」为基调,包含:

  • 1 项向后不兼容变更:投影(Projection)中的位置参数(positional arguments)默认禁用;
  • 1 项新特性:MergeTree 新增合并时限制动态子列数量的表设置;
  • 1 项性能改进:放宽INSERT SELECT FROM s3cluster()分布式并行执行对查询的限制;
  • 5 项常规改进:涵盖 libssh 安全修复、JSON 读取线程池、QBit 类型转换、聚合/排序落盘内存检测、AzureBlobStorage 复制降级等;
  • 50+ 项 Bug 修复,覆盖 JSON/Dynamic/Variant 子列、MergeTree 合并与 TTL、权限系统、各类表引擎与函数;
  • 若干构建/测试/打包改进与内部基础设施修复。

向后不兼容变更:投影中的位置参数默认关闭

变更内容

本次版本将「投影定义中禁用位置参数」标记为向后不兼容变更,并引入新设置enable_positional_arguments_for_projections用于平滑升级集群。

所谓位置参数,是指投影定义中可以用列序号代替列名的写法。设置项源码位于 src/Core/Settings.cpp,其含义如下:

  • 0— 投影中不支持位置参数(默认值,本次变更后的行为);
  • 1— 投影中支持位置参数:可以使用列序号代替列名。

该设置被官方注释标记为expert-level 设置,并提示与既有设置enable_positional_arguments相互关联,两者分别控制普通查询与投影定义中的位置参数行为。

升级影响与操作建议

对于在投影中使用了位置参数(如PROJECTION p (SELECT 1, 2 ORDER BY 1))的生产集群,直接升级到本版本可能导致相关投影解析行为变化。官方提供的平滑升级路径是:

  1. 升级前先在服务端配置中显式开启enable_positional_arguments_for_projections = 1
  2. 在集群所有节点完成升级后,将投影中的位置参数改写为显式列名(推荐做法,避免后续维护歧义);
  3. 确认所有投影均可正确解析后,再将设置改回0(默认值)或移除该配置。

从源码结构看,投影定义解析位于 src/Storages/ProjectionsDescription.cpp,该文件同时处理投影的解析与校验逻辑,位置参数开关的变化会直接影响该解析路径的分支选择。

新特性:合并时限制 Wide Part 的动态子列数量

设置语义

新增 MergeTree 表设置merge_max_dynamic_subcolumns_in_wide_part,用于在合并生成 Wide 数据 part 时,限制每个列可以创建的动态子列(dynamic subcolumns)最大数量,从而不受数据类型中动态参数(如max_dynamic_paths)的约束,控制数据 part 中的文件数量。

该设置的完整定义与示例位于 src/Storages/MergeTree/MergeTreeSettings.cpp:

例如,若表中某列类型为JSON(max_dynamic_paths=1024),而merge_max_dynamic_subcolumns_in_wide_part设置为128,则合并进 Wide part 后该 part 内动态路径数量将被缩减到 128,且只有这 128 条路径会作为动态子列写入。

设置默认值为autoUInt64Auto类型,即自动模式)。与之一同新增的还有对称的merge_max_dynamic_subcolumns_in_compact_part(src/Storages/MergeTree/MergeTreeSettings.cpp),用于控制 Compact part 场景。

解决的问题与原理

JSON/Dynamic 这类「动态路径」数据类型会随着写入数据中出现的新键不断扩充子列集合。若单个列上动态路径过多,合并后的 Wide part 会产生大量独立的子列文件(substream files),带来:

  • 文件描述符与元数据膨胀;
  • 合并与读取时的调度开销上升;
  • 长时间运行后 part 目录内文件数量不可控。

merge_max_dynamic_subcolumns_in_wide_part允许 DBA 在表级别对动态子列数量设定硬性上限,在合并阶段主动收敛路径数量,而无需改写表结构或数据类型定义。该设置在合并任务执行链路(src/Storages/MergeTree/MergeTask.cpp)中被读取,并在数据类型层面(src/DataTypes/DataTypeObject.cpp)参与序列化与路径管理逻辑。

使用示例

-- 建表时直接指定 CREATE TABLE events ( ts DateTime, attrs JSON ) ENGINE = MergeTree ORDER BY ts SETTINGS merge_max_dynamic_subcolumns_in_wide_part = 128; -- 对已有表动态调整 ALTER TABLE events MODIFY SETTING merge_max_dynamic_subcolumns_in_wide_part = 64;

配置后,后续合并生成的 Wide part 中,每个列的动态子列数量将不超过该上限。若需同时约束 Compact part,可一并设置merge_max_dynamic_subcolumns_in_compact_part

性能改进:放宽INSERT SELECT FROM s3cluster()的查询限制

此前(对应的上游变更)为INSERT SELECT FROM s3cluster()的分布式并行执行增加了查询约束,导致原本可用的WHERE过滤条件被禁止。本次版本放开该限制,允许在s3cluster()分布式并行写入场景中继续使用WHERE子句,恢复此前的可用能力。

这对将 S3 上多个文件集群化读取、过滤后写入本地表的 ETL 任务是一处实用改善:无需再改写为「先全量读取再过滤」或「拆分为多段查询」的形式,并行度与下推能力得以保留。相关查询路径的测试位于 tests/queries 目录的分布式查询用例中。

常规改进(Improvements)逐项解析

安全修复:libssh 升级解决 CVE-2025-5318

本次版本解决了 ClickHouse 内置 libssh 组件中编号为CVE-2025-5318的安全问题(src 目录下所有依赖该库的 SSH 相关功能均受影响)。配套的构建改进将 libssh 从 0.9.8 升级至 master 分支(0.11.3),以彻底消除相关安全公告中的漏洞面。

注意:变更日志中还记录了「Revert 'Resolve CVE-2025-5318'」与重新引入修复的两个相邻条目,最终合入状态以本版本二进制为准。建议使用 SSH 表函数或外部字典的场景在升级后做一次连通性回归验证。

JSON 多子列读取:尊重前缀反序列化线程池设置

修复了 JSON 列存在大量子列时读取列样本可能导致的**线程池饥饿(thread pool starvation)**问题。修复前该路径无条件使用线程池;修复后改为遵循merge_tree_use_prefixes_deserialization_thread_pool设置,按配置决定是否使用线程池,避免在线程池资源紧张时阻塞。

QBit 类型:允许从整数/浮点数组隐式转换

QBit是 ClickHouse 新增的量化位图数据类型(实现位于 src/DataTypes/DataTypeQBit.cpp 与 src/DataTypes/Serializations/SerializationQBit.cpp)。本次改进允许将整数数组和浮点数组直接插入 QBit 列而无需显式类型转换

-- 此前需要显式 CAST -- INSERT INTO t (q) SELECT CAST([1, 2, 3] AS Array(Float32)); -- 现在可直接插入 INSERT INTO t (q) VALUES ([1, 2, 3]);

类型转换的底层校验逻辑可在 src/DataTypes/Utils.cpp 中看到 QBit 类型的归一化处理分支。该类型单元测试位于 src/DataTypes/Serializations/tests/gtest_qbit_serialization.cpp。

聚合/排序落盘:更稳健的内存占用检测

改进了聚合(aggregation)与排序(sorting)过程中为**落盘(spilling to disk)**而进行的内存使用量检测逻辑,使触发落盘的判断在内存统计波动场景下更加稳健,降低因误判导致的内存溢出或落盘不及时风险。

AzureBlobStorage:原生复制失败时自动降级

对于所有AzureBlobStorage原生复制(native copy)失败的情况,现在会自动回退到「读取后写入」的方式完成数据复制,提升对象存储复制操作的健壮性。

Bug 修复分类详解

本节将本版本的 50+ 项修复按主题归类,便于按自身业务场景定位。

JSON / Dynamic / Variant 子列与稀疏序列化(本版本修复最密集的领域)

JSON/Dynamic 数据类型的动态子列机制是本版本修复投入最大的方向,主要包括:

  • Compact part 子列读取修复:修复读取 compact part 中 JSON 子列时可能出现的CANNOT_READ_ALL_DATA错误(对应问题 90264);
  • 共享数据与动态路径不一致:修复 JSON 中共享数据(shared data)与动态路径(dynamic paths)可能出现的状态不一致,该问题曾引发逻辑错误与意外结果,并进一步引入针对重复路径的自愈机制(repair mechanism)
  • Compact part 写入动态结构不一致:修复写入 compact part 时动态结构不一致可能导致的段错误(segfault);
  • 禁用子流标记(marks)时的子对象读取:修复write_marks_for_substreams_in_compact_parts被禁用时,路径同时存在于共享数据与动态路径场景下的读取错误;
  • 内存占用:修复读取 JSON/Dynamic/Variant 列时的高内存占用问题;
  • 物化列中的动态子列读取:修复 mutation 中从物化列读取动态子列的错误;
  • Summing/Aggregating/Coalescing MergeTree 合并:修复合并时 JSON 列可能产生意外动态路径的问题,以及向 CoalescingMergeTree 中Tuple形式的 JSON/Dynamic 与 LowCardinality 组合列插入的问题;
  • 稀疏序列化(sparse serialization):修复ratio_of_defaults_for_sparse_serialization=0.0或通过 ALTER 改为1.0后对稀疏列执行 mutation 可能出现FILE_DOESNT_EXIST的问题,以及读取带稀疏编码的子列(如 string size)时结果不正确的问题;
  • 类型提示(type hint):修复创建 JSON 路径'skip'的类型提示时的问题;
  • 列名与子列名冲突:修复列与同名子列冲突时可能使用错误序列化并导致查询失败的问题。

MergeTree / 数据 part / mutation

  • TTL 中列被提前移除:修复 TTL 处理中因列被过早移除引发的多个问题(对应问题 88002);
  • ALTER 组合操作:修复同一条 ALTER 中「重命名并修改同一个 Nested 列」可能出现的逻辑错误;修复ALTER ADD COLUMN后旧 part 中列的惰性物化问题;
  • ALTER MODIFY QUERY:修复dictGet()与字典名出现在 CSE(公共子表达式)中时ALTER MODIFY QUERY的报错(SharedCatalog 云特性);
  • mutation 序列化信息继承:使 MergeTree mutation 继承源 part 的序列化设置,修复数据类型序列化变更后对 mutation 后 part 查询可能得到错误结果的问题;
  • 只读磁盘启动:当 MergeTree 表建立在只读磁盘上时,不再在启动阶段尝试删除临时目录;
  • ALTER TABLE REWRITE PARTS:修复报错 "Cannot add action to empty ExpressionActionsChain" 的问题;
  • 轻量更新(lightweight update)主键索引:修复轻量更新WHERE谓词中含IN子查询子句时主键索引未正确使用的问题;
  • 内存超限后崩溃:修复聚合函数在MEMORY_LIMIT_EXCEEDED之后可能出现的崩溃。

投影(Projection)

  • UNION 场景下的未用投影列:修复存在UNION时移除未使用投影列的逻辑错误(对应问题 88180);
  • 合并重建投影:在合并重建投影时移除未使用列,降低内存占用并减少产生的临时 part。

权限与访问控制

  • 通配符授权与吊销:修复部分吊销时通配符授权检查问题,并补充测试;修复吊销通配符授权可能误伤CREATE USER等全局授权的问题;随后重构了通配符授权的检查逻辑,修复「为修复漏洞而过度收紧导致无关 GRANT 失败」的问题;
  • ALTER UPDATE访问校验:修复remote表函数以localhost为目标主机时的ALTER UPDATE访问校验问题;
  • 命名集合(named collections)隐藏密钥:修复隐藏密钥未遵循display_secrets_in_show_and_selectformat_display_secrets_in_show_and_select的问题。

表引擎与存储

  • Hive 分区兼容性:修复 25.8 升级路径中 "All hive partitioning columns must be present in the schema" 错误,保证平滑升级;
  • Log 引擎:修复读取 String 数据与.size子列时崩溃、子列读取逻辑错误等问题;
  • Buffer 引擎:修复高频 INSERT 时后台 flush 行为异常与过度 flush(消耗 CPU 并产生大量日志)的问题;
  • S3Queue(Ordered 模式):将Failed to set file processing within 100 retries逻辑错误降级为警告,避免因 keeper 会话过期直接报错;
  • Object Storage 表引擎:禁止不支持的 ALTER(如ALTER ADD PROJECTION),此前该操作可能导致服务无法重启;
  • Delta Lake:修复表引擎(而非表函数)场景下delta_lake_snapshot_version与 -1(禁用)组合时的错误结果;
  • Distributed:修复optimize_skip_unused_shards优化可能因类型错误导致 "Serialization is not implemented for data type Set" 的问题;
  • Azure list blobs:修复可能出现的无限循环;
  • SYSTEM DROP FILESYSTEM CACHE ON CLUSTER:修复集群级文件系统缓存清理命令。

函数与类型系统

  • toDateTimeOrNull:修复负数参数时错误返回NULL的问题;
  • base58Decode:修复缓冲区分配问题;
  • tokens():修复第二个参数为NULL时的崩溃;
  • L2DistanceTransposed:修复使用非常量参考向量(如表数据)时返回错误结果的问题;
  • dictGetDescendants:修复字典类型声明了 Hierarchy 支持但无HIERARCHICAL列时因NULL导致的崩溃;
  • caseWithExpression:修复参数中出现Nothing类型时的逻辑错误;
  • count_distinct_optimization:修复对窗口函数及多参数场景的错误优化;
  • ARRAY JOIN:修复表列包含空Tuple列时的逻辑错误;
  • remote函数星号参数:修复remote函数中星号参数导致的逻辑错误;
  • 递归 CTE:修复RecursiveCTEChunkGenerator中的LOGICAL_ERROR
  • CTE + dictGet:修复无参数dictGet在 CTE 中的std::out_of_range异常;
  • LowCardinality:修复分区键中使用LowCardinality列的类型转换错误;修复SummingMergeTreeNested LowCardinality列的聚合;修复LowCardinality(Bool/Date32)在 Arrow 格式输出时的逻辑错误;
  • QBit反序列化崩溃:修复恶意构造的字节流反序列化到嵌套 QBit 类型时可能导致服务崩溃的安全问题;修复QBit配合查询参数(如SET param_q=[1,2,3,4]; SELECT {q:QBit(Float32,4)})时的失败;
  • String 聚合状态内存序列化:修复不同版本实例间 String 聚合状态内存序列化不兼容可能导致重复结果的问题,新序列化可通过serialize_string_in_memory_with_zero_byte启用;
  • match相关数据跳过逻辑:修复WHERE中使用not match(...)not materialize(...)not CAST(...)时数据跳过逻辑错误导致结果不正确的问题。

分布式与连接管理

  • 副本激活重试:在本地主机地址解析失败时重试markReplicasActive,无活动主机时输出警告而非抛异常;
  • DDL 任务自检:主机自检异常时打印警告日志;
  • 连接状态:修复从已断开的Connection读取可能导致的崩溃;修复分布式查询预取消后连接处于损坏状态的问题;
  • insert select 连接释放:释放请求流,防止 HTTP 连接无法关闭;
  • PooledConnection析构:移除~PooledConnection中的 try/catch(内部清理)。

其他修复

  • 别名表:修复 Replicated 数据库中空参数Alias表的问题;
  • Schema 推断:globs 场景下只缓存推断来源文件本身的 schema,而非所有文件;
  • UDF 替换:修复 format 中的 UDF 替换;
  • 稀疏列清理:修复稀疏列 mutation 后可能的FILE_DOESNT_EXISTratio_of_defaults_for_sparse_serialization=0.01.0两种场景);
  • Parquet 旧版读取器:修复 JSON 列位于 Tuple 列之后时的 schema 推断与空元组失败问题(旧版读取器,非默认启用)。

构建、测试与打包改进

  • libssh 升级:从 0.9.8 升至 master(0.11.3),解决安全公告 GHSA-98qw-prqm-9f4p 对应的问题;
  • Rust 编译缓存chcachesccache均可作为 Rust 包装器使用;
  • 测试稳定性:修复 00906_low_cardinality_cache 的 flaky、S3Queuetest_failed_startup的 flaky,以及分布式 insert select 测试因去重导致的 flaky;
  • CI 修复:版本 tweak 计算、tmpfs 权限变化(runc 1.3.3)、并行集成测试拉取、fd 泄漏可见性(ulimit -n变更)等基础设施问题;
  • 内部完善:改进 DDLDependencyVisitor、为空的 metadata_files 增加断言、Polaris catalog 嵌套 namespace 编码修复、相关日志级别调整等。

升级评估与运维要点

综合本版本变更,升级到 v25.10.4.104-stable 前建议重点核对以下事项:

  1. 投影位置参数:这是唯一一项向后不兼容变更。若投影中使用列序号,先开启enable_positional_arguments_for_projections = 1完成滚动升级,再逐步改写投影定义(见本文第二节);
  2. JSON 动态列规模:若存在JSON/Dynamic列且 part 文件数量膨胀明显,可评估配置merge_max_dynamic_subcolumns_in_wide_part(及 Compact 版对称设置)控制动态子列数量;
  3. SSH 相关功能回归:libssh 大版本升级后,对使用 SSH 外部字典、SSH 表函数的任务做连通性与认证回归;
  4. String 聚合状态序列化:若聚合查询跨不同版本实例执行,注意serialize_string_in_memory_with_zero_byte提供的兼容序列化开关;
  5. S3Queue Ordered 模式:此前遇到的Failed to set file processing within 100 retries错误在本版本已降级为警告,但高并发处理下仍理论可能出现,可结合重试机制观察。

结论

v25.10.4.104-stable是一个典型的稳定修复版本:以一项明确标记的向后不兼容变更(投影位置参数默认禁用 + 升级开关)为主轴,新增了针对 JSON 动态子列数量的合并期控制能力,并围绕 JSON/Dynamic/Variant、MergeTree、权限系统、函数与各表引擎完成了 50+ 项修复。对于运行 JSON 密集负载、依赖投影优化或使用对象存储复制能力的生产集群,该版本值得重点评估与跟进。

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

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

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

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

立即咨询