ClickHouse v25.11.4.19-stable 变更详解:投影位置参数、聚合溢写内存检测与关键 Bug 修复
2026/9/17 22:57:29 网站建设 项目流程

ClickHouse v25.11.4.19-stable 变更详解:投影位置参数、聚合溢写内存检测与关键 Bug 修复

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

本文基于 docs/changelogs/v25.11.4.19-stable.md 编写,系统梳理 ClickHouse 25.11 系列第 4 个 stable 补丁版本(2c64eff7334,相对基线v25.11.3.54-stable)引入的 1 项向后不兼容变更、1 项功能改进、12 项用户可见 Bug 修复与若干构建/测试改进。读者可据此评估升级影响、理解新设置enable_positional_arguments_for_projections的集群升级作用,并快速定位每个修复对应的源码与测试位置。

版本概览与升级建议

v25.11.4.19-stable是一个典型的补丁(patch)版本:不含新功能开发,聚焦于修复 25.11 系列先前版本暴露的稳定性问题,并引入一项刻意设计为向后不兼容的变更——投影(Projection)定义中的位置参数(positional arguments)被正式禁用,同时新增逃生舱设置enable_positional_arguments_for_projections帮助存在旧投影的用户平滑升级集群。

升级建议:

  • 若集群投影定义中从未使用GROUP BY 1ORDER BY 2这类位置引用,可直接升级;
  • 若投影中存在位置参数,需先开启enable_positional_arguments_for_projections再升级,避免兼容性报错;
  • 该补丁修复了聚合溢写、countDistinct优化、数据跳过索引、ALTER TABLE ... REWRITE PARTS等多处可能引发崩溃或错误结果的问题,建议生产环境尽快跟进。

向后不兼容变更:投影中的位置参数与enable_positional_arguments_for_projections

这是本版本唯一标记为Backward Incompatible Change的条目。该变更是对上游 PR #88380 的后续(follow-up):旧实现允许在PROJECTION定义中通过列序号引用列(即位置参数),但这种写法依赖固定的列顺序与别名解析规则,在多表联查、物化列变化的场景下结果不可靠。

新设置说明

版本为此引入了新的专家级设置enable_positional_arguments_for_projections,其定义位于 src/Core/Settings.cpp:

-- 全局/会话级启用 SET enable_positional_arguments_for_projections = 1;
  • 类型Bool
  • 默认值0(不支持位置参数)
  • 取值0— 投影定义中不支持位置参数;1— 支持位置参数,可用列序号代替列名
  • 适用场景:官方文档明确标注这是专家级设置,仅当投影中已存在位置参数、需要在集群升级期间保证兼容时才应开启(Settings.cpp 中的 Note 原文)。
  • 该设置与既有的enable_positional_arguments(普通查询中允许位置参数,默认true,见 Settings.cpp)相互独立:前者仅作用于投影定义解析上下文。

源码级原理:投影解析如何联动该设置

在 src/Storages/ProjectionsDescription.cpp 中可以看到该设置的底层作用路径:当 ClickHouse 在构建投影数据(ProjectionDataSink)内部查询上下文时:

auto mut_context = Context::createCopy(context); ... const bool positional_arguments_for_projections = context->getSettingsRef()[Setting::enable_positional_arguments_for_projections]; ... /// Setting `enable_positional_arguments_for_projections` may enable /// positional arguments for projections. It is needed for compatibility /// with existing projections that use positional arguments to allow /// successful cluster upgrade. mut_context->setSetting("enable_positional_arguments", positional_arguments_for_projections);

也就是说:投影的物化/写入路径在默认情况下会强制关闭enable_positional_arguments(因为位置引用依赖的列序在此内部上下文中既不保证也不合理),只有当用户显式开启enable_positional_arguments_for_projections时,内部上下文才重新放开位置参数支持。这正是该设置的用途:它是给“带旧投影升级集群”的场景准备的兼容开关

在设置历史(src/Core/SettingsChangesHistory.cpp)中,该设置被记录为 25.11 版本的新增项,随本补丁一并归入 25.11 的设置历史(见 changelog 的 NOT FOR CHANGELOG 条目:“Move enable_positional_arguments_for_projections into 25.11 in settings history”)。

功能改进:聚合与排序溢写磁盘时的内存检测更健壮

相关 PR:#92500

本版本对聚合(aggregation)与排序(sorting)过程中检测是否应溢写(spill)到磁盘的内存用量判断进行了健壮性改进。此前在某些边界条件下,内存使用量的探测可能失真,导致:

  • 过晚触发溢写,造成MEMORY_LIMIT_EXCEEDED
  • 或过早溢写,白白损失吞吐。

改进后的逻辑让max_bytes_before_external_group_bymax_bytes_before_external_sort等溢写阈值在判断时更贴近真实内存消耗。这项改进与同版本“聚合函数在MEMORY_LIMIT_EXCEEDED后可能崩溃”的修复(见下文 Bug Fix)形成互补,共同提升了内存受限环境下的稳定性。

Bug 修复详解

本版本共修复 12 项用户可见问题(均为官方 stable 版本中可复现的异常行为)。按影响面分类如下:

查询错误结果类

  1. not match(...)在 WHERE 中导致数据跳过索引误判(#92726,关闭 #92492) 修复了数据跳过逻辑(data skipping)在使用not match(...)时可能错误跳过数据块、返回不完整结果的严重问题。使用match/not match与跳过索引组合的查询用户应重点关注。

  2. count_distinct_optimization对窗口函数与多参数的重写错误(#92376)count_distinct_optimization(默认false,Settings.cpp)会把countDistinct/uniqExact重写为“子查询 + GROUP BY + count”。修复前该优化在涉及窗口函数多参数的查询上会产生错误结果。

    从实现看,该优化由 src/Analyzer/Passes/CountDistinctPass.cpp 中的CountDistinctVisitor驱动,重写前会做一系列严格前置检查:查询只能含 SELECT 子句(不得有 WHERE/GROUP BY/HAVING/WINDOW/ORDER BY/LIMIT 等)、只能作用于单表、投影只能有一个节点、函数必须是countDistinctuniqExact不带窗口function_node->hasWindow()返回 true 时直接跳过,见 CountDistinctPass.cpp)。本补丁正是在此基础上补齐了窗口函数与多参数场景的边界处理。

  3. MergeTree 变更(mutation)后序列化信息未继承导致查询结果错误(#92419) 修复了数据类型序列化方式变化后,对已变更(mutated)part 的查询可能得到错误结果的问题——现在 mutation 会继承源 part 的序列化信息设置。

崩溃与逻辑错误类

  1. Log 引擎读取子列时可能触发 logical error(#91711,关闭 #91710) 修复Log表引擎在子列(subcolumns,如Map的 key/value 子列、Tuple的命名子列等)读取路径上的逻辑错误断言。

  2. 聚合函数在MEMORY_LIMIT_EXCEEDED之后可能崩溃(#92390) 修复聚合执行中内存超限异常传播路径上的空指针/状态不一致问题,与上文溢写检测改进协同生效。

  3. tokens()第二参数为 NULL 时崩溃(#92586) 修复字符串分词函数tokens(s, delimiter)在 delimiter 传入NULL时的崩溃。

  4. ALTER TABLE ... REWRITE PARTS报 "Cannot add action to empty ExpressionActionsChain"(#92754) 修复 v2 版本的ALTER TABLE ... REWRITE PARTS在构造表达式动作链为空时报错的问题。该命令用于按当前表设置重写 part(如应用新压缩编码、TTL 表达式等)。

数据一致性与生命周期类

  1. 共享数据中 JSON 重复路径的修复机制(#91886) 针对此前 PR #90816 修复的缺陷,可能遗留“shared data 与动态路径中出现重复 JSON 路径”的脏数据,本补丁增加了修复机制来清理这类异常状态。

  2. glob 模式建表时仅缓存推断来源文件的结构(#92006,关闭 #91745) 修复了SELECT * FROM file('dir/*.parquet')等 glob 场景下,schema 推断缓存被错误地应用到目录中所有文件(而非仅推断时使用的那个文件)的问题。

  3. read-only 磁盘上的 MergeTree 启动时不再尝试删除临时目录(#92748) 避免在只读磁盘上建表的 MergeTree 于启动阶段执行无意义的临时目录清理(删除操作会失败并产生噪音)。

连接与并发类

  1. INSERT INTO ... SELECT未释放请求流导致 HTTP 连接被关闭(#92175) 修复 HTTP 接口下执行INSERT INTO ... SELECT时,请求流(request stream)未及时释放导致连接无法复用甚至被提前关闭的问题。

  2. Backup 数据库SHOW CREATE DATABASE死锁(#92541) 修复对BACKUP类型的数据库执行SHOW CREATE DATABASE时的死锁。

构建 / 测试 / 打包改进

  • Rust 编译缓存适配(#92404 目录。

非用户可见的内部修复(NOT FOR CHANGELOG)

  • Polaris 目录(Catalog)嵌套命名空间编码修复(#92079):修复 Polaris catalog 中嵌套命名空间的编码问题。
  • 日志级别调整(#92810):降低某条日志的级别以减少噪音。
  • 设置历史归位(#92841):将enable_positional_arguments_for_projections归入 25.11 的设置历史记录。

结语与验证建议

v25.11.4.19-stable是一个“小而关键”的补丁:多数修复面向错误结果与崩溃,其中投影位置参数禁用与data skipping修复直接关系查询正确性。升级后可重点验证以下场景:

  • Projection且定义中带列序号的表(确认是否需要开启enable_positional_arguments_for_projections);
  • 使用count_distinct_optimizationuniqExact的查询(涉及窗口函数/多参数);
  • 大内存聚合、排序任务(观察溢写触发与内存超限表现);
  • match/not match与跳过索引组合的查询结果完整性。

如需查看完整变更条目与原始 PR/Issue 链接,可直接阅读 docs/changelogs/v25.11.4.19-stable.md;相关设置的默认值与详细说明可在 src/Core/Settings.cpp 中检索enable_positional_arguments_for_projectionscount_distinct_optimizationDECLARE条目确认。

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

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

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

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

立即咨询