ClickHouse v26.1.3.52-stable 版本更新详解:S3Queue 元数据缓存、Variant/JSON 修复与分布式查询稳定性改进
2026/9/19 8:22:36 网站建设 项目流程

ClickHouse v26.1.3.52-stable 版本更新详解:S3Queue 元数据缓存、Variant/JSON 修复与分布式查询稳定性改进

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

本文基于当前仓库中 docs/changelogs/v26.1.3.52-stable.md 这一官方发布日志,逐条解析 ClickHouse v26.1.3.52-stable 相比 v26.1.2.11-stable 引入的向后不兼容变更、性能改进、功能增强与 30 余项用户可见 Bug 修复。读完本文,你将掌握该版本对S3Queue/AzureQueue系统表命名的影响、Nullable(Tuple)类型推断的新行为、以及 JOIN、JSON、Variant、分区裁剪等高频场景下的修复要点与升级注意事项。

一、版本概览

本次发布的完整信息如下:

  • 版本号v26.1.3.52-stable
  • 提交哈希5549f2acae9
  • 对照基线v26.1.2.11-stable53779390caa
  • 条目结构:分为 Backward Incompatible Change(2 条)、Performance Improvement(1 条)、Improvement(4 条)、Bug Fix(30 余条)、Build/Testing/Packaging Improvement(1 条)以及若干内部维护类条目。

值得说明的是,原始发布日志标题中带有FIXME标记,这是 ClickHouse 发布流程中用于提醒维护者核对发布基线的占位符,实际发布内容以本文所解析的条目为准。该版本属于 26.1 系列的 stable 分支,是在前一个 stable 版本基础上回移(backport)了大量修复后的维护性发布,其显著特征是:不引入新特性,而是以稳定性和正确性修复为主

二、向后不兼容变更:S3Queue / AzureQueue 系统表重命名

本版本最需要升级者注意的变更来自 PR #95809(作者 Kseniia Sumarokova):为限制S3Queue/AzureQueue在内存中的元数据占用,相关系统表被统一重命名,查询这些系统表的存量脚本/监控面板需要同步修改

旧表名新表名说明
system.s3queuesystem.s3queue_metadata_cache展示 S3Queue 每个文件处理状态的内存态(正在处理 / 已处理 / 失败),非持久化
system.azure_queuesystem.azure_queue_metadata_cache展示 AzureQueue 的内存态
system.s3queue_log不变持久化表,记录 processed / failed 文件的历史信息

在仓库源码中可以验证这一命名结构。例如 src/Storages/ObjectStorageQueue/registerQueueStorage.cpp 中明确写道:

For introspection use thesystem.s3queue_metadata_cacheandsystem.s3_queue_metadatastateless tables and thesystem.s3queue_logpersistent table.

同时该文件还给出了新表的实际 DDL(CREATE TABLE system.s3queue_metadata_cache ...)以及SELECT ... FROM system.s3queue_metadata_cache的示例用法。对于 Azure 队列,registerQueueStorage.cpp 中说明:服务端版本 >= 25.1 时使用system.azure_queue_metadata_cache查看内存态,更早版本则回退到system.s3queue_metadata_cache(其中同样包含 azure 表的信息)。系统表在启动时的挂载注册逻辑位于 src/Storages/System/attachSystemTables.cpp。

升级建议

  1. 将依赖system.s3queuesystem.azure_queue的查询语句、Grafana 面板、告警脚本统一替换为新表名;
  2. 内存态表用于排障实时状态,长期统计仍应使用持久化的system.s3queue_log
  3. 该重命名的动机是限制 S3/Azure 队列的 in-memory 元数据规模,因此对元数据量大的队列,新表本身也更适合按需查询而非全量扫描。

另一条向后不兼容变更是 PR #95811:修复了Variant类型不匹配时的逻辑错误(logical error)。它改变了此前在类型不匹配场景下可能抛出的异常行为,属于行为修正,一般不影响正常 SQL 语义。

三、性能改进:CachedOnDiskReadBufferFromFile 结构体缩小约 50 倍

PR #96098(作者 Azat Khuzhin)将CachedOnDiskReadBufferFromFile结构体的大小缩减了约 50 倍("Trim size ... 50x")。

该结构体是 ClickHouse 本地磁盘缓存(local_filesystem_read_method为缓存读路径)的核心实现,位于 src/Disks/IO/CachedOnDiskReadBufferFromFile.h 与 src/Disks/IO/CachedOnDiskReadBufferFromFile.cpp。从源码结构看,它被用于ReadPipeline的磁盘缓存阶段(见 src/IO/ReadSettings.h 中 "Used by CachedOnDiskReadBufferFromFile and the ReadPipeline disk cache stage" 的注释),同时也被 S3 对象存储的缓存磁盘(CachedObjectStorage)复用,参见 src/Disks/DiskObjectStorage/ObjectStorages/Cached/CachedObjectStorage.cpp。

影响面:每个读取缓冲区实例占用的内存显著下降。在高并发、大量文件读取的负载下(例如高频小文件查询、多查询并发读取同一 S3 数据集),该改进能降低内存占用并减少缓存未命中带来的分配开销。对普通用户而言是透明的性能收益,无需任何配置变更。

四、功能改进(Improvement)

4.1 Schema inference 支持allow_experimental_nullable_tuple_type

PR #95525(作者 Nihal Z. Miaji)让格式文件的 schema 推断(schema inference)开始尊重allow_experimental_nullable_tuple_type设置。开启后,推断出的元组类型可以是Nullable(Tuple(...)),缺失的嵌套对象会变成NULL,而不是「由若干个NULL元素组成的元组」。这一行为差异对 JSON/JSONEachRow 等半结构化数据入表时的 nullability 语义影响明显。

仓库中该设置的实现位于 src/Core/Settings.cpp,定义形式为DECLARE_WITH_ALIAS(Bool, enable_nullable_tuple_type, true, ...),即当前正式名称为enable_nullable_tuple_type(默认开启),并保留allow_experimental_nullable_tuple_type作为别名(alias)。从 src/Core/SettingsChangesHistory.cpp 中的设置演进记录可以看出该设置的演变路径:

变更旧值新值说明
Nullable(Tuple)GAfalsetrue该设置被重命名为正式名称
enable_nullable_tuple_type新增falsefalse作为allow_experimental_nullable_tuple_type的别名引入
allow_experimental_nullable_tuple_type新增falsefalse最初为实验性设置

从源码结构还可以看到另一个关联设置:文档注释中明确指出,该设置并不控制从 Dynamic、Variant、JSON 或 Tuple 列提取出的子列是否可以为Nullable——那由allow_nullable_tuple_in_extracted_subcolumns控制。也就是说,本版本修复的是「推断(inference)阶段」对 nullable tuple 的尊重问题,与「提取子列阶段」的控制点相互独立。

4.2 依赖升级与对象存储查询优化

  • libxml2 升级到 2.15.1(PR #95574):内部携带的 libxml2 库从旧版本升级至 2.15.1,主要影响 XML 格式的解析能力与安全性,对使用XML输入格式或依赖 XML 解析(如部分集成场景)的用户有益。
  • 查询DeltaLake表时跳过对象存储读取(PR #95899):查询system.tables时不再为 DeltaLake 表发起对象存储读取。此前列出系统表会触碰底层存储元数据,耗时且可能触发不必要的远程请求;修复后元数据列举更快、更省网络开销。
  • 更完善的 jemalloc 内省能力(PR #96840):增强对 jemalloc 分配器的 introspection,便于诊断内存占用来源,属于可观测性改进。

五、Bug Fix 详解:覆盖 JOIN、JSON、Variant、分区裁剪等高频场景

本次发布包含 30 余条 Bug Fix,均标注为"user-visible misbehavior in an official stable release"。以下按子系统归类解析,并对其中影响面较大的修复给出仓库级佐证。

5.1 查询计划与 JOIN 相关

  • 多 JOIN +USING的类型推断修复(PR #95157):此前在SELECT t2.a FROM t1 LEFT JOIN t2 USING (a) LEFT JOIN t3 USING (a)这类查询中,后续 JOIN 会错误地把未被该 JOIN 涉及的源列类型统一升级为公共超类型。修复后t2.a的类型只由t1.at2.a决定,排除t3.a的影响。此前该问题可能导致逻辑错误甚至崩溃(当函数期望的列类型与执行计划实际类型不一致时)。
  • 外连接与多 INNER JOIN 组合的错误重排(PR #96193):当外连接的 ON 条件引用多个先前已连接表的列时,优化器可能未考虑全部表依赖关系而错误重排 JOIN,导致 LEFT/RIGHT/FULL 外连接与多个 INNER JOIN 组合的查询返回缺失行。
  • directjoin 算法 + 空 MergeTree 表(PR #95935):修复了direct连接算法遇到空 MergeTree 表时的NOT_SUPPORTED错误。
  • 旧分析器中 JOIN 与重复别名崩溃(PR #96405):修复旧 analyzer 下 JOIN 与重复别名组合导致的崩溃。

5.2 JSON 数据类型

  • tupleElement应用于 JSON 数组时崩溃(PR #95647):修复了tupleElement作用于 JSON 数组时可能崩溃的问题。
  • tupleElement嵌套路径返回错误结果(PR #95907):修复了 JSON 嵌套路径上执行tupleElement可能返回错误查询结果的问题。
  • JSON(SKIP path)跳过路径修复(PR #95948):此前JSON(SKIP path)会跳过所有带path前缀的键,例如"pathpath"也会被误跳过,导致插入时这些路径数据丢失。修复后仅跳过完全等于"path"的键。注意这是一条会改变插入行为的数据安全类修复,使用JSON(SKIP ...)的用户建议核对存量写入数据。

5.3 Variant / Dynamic / 聚合函数

  • FunctionVariantAdaptor的 const 参数逻辑错误(PR #97116):修复了需要 const 参数的函数(如arrayROCAUC)作用于 Variant 列时的逻辑错误。
  • FunctionVariantAdaptorNothing类型处理(PR #97213):当函数作用于 Variant 列返回Nothing类型时(UNION ALL中的空数组可触发),修复了LOGICAL_ERROR异常。
  • optimize_syntax_fuse_functionsLowCardinality(Nullable)(PR #96239 中有完整定义:开启后(默认true),对具有相同参数的sumcountavg至少两个聚合函数,会融合为一次sumCount()调用(返回(sum, count)元组),从而只扫描一次数据;该设置被SET optimize_syntax_fuse_functions = 0关闭。其优化实现位于 src/Analyzer/Passes/FuseFunctionsPass.cpp,对应的聚合函数实现是 src/AggregateFunctions/AggregateFunctionSumCount.cpp。
  • indexOfAssumeSorted不兼容类型(PR #96877):修复了indexOfAssumeSorted在类型不兼容(如 IPv4 数组配整型搜索值)时的std::terminate异常。

5.4 LIMIT/OFFSET 与执行控制

  • 负的LIMIT/OFFSET分布式查询逻辑错误(PR #95357):修复分布式查询中负数 LIMIT/OFFSET 触发逻辑错误的场景。
  • 分数的LIMIT/OFFSET分布式查询逻辑错误(PR #96475):继续修复分数 LIMIT/OFFSET 在分布式查询中的逻辑错误。
  • max_execution_time过大导致的 livelock(PR #96450):修复了高max_execution_time值下 cancellation checker 线程的活锁问题;相关的CancellationChecker线程竞争修复见 PR #95563(内部条目)。
  • ProcessList 潜在死锁(PR #96182):修复了内存 overcommit tracker 在向 cancellation checker 添加任务时可能触发的锁序反转导致的死锁。

5.5 分区裁剪与索引

  • not IN/not has分区裁剪错误(PR #96241):修复了某些情况下not INnot has函数分区裁剪不正确的问题。
  • use_primary_key禁用时的 use-after-free(PR #96112):修复了禁用use_primary_key且条件析取项极多时索引分析中的 use-after-free。
  • 查询条件缓存哈希冲突(PR #96172):修复了 CTE 折叠常量场景下查询条件缓存哈希冲突导致错误结果的问题。

5.6 物化投影、TTL 与 ALTER

  • _minmax_count_projection与 TTL(PR #96703):修复了 TTL merge 后某块所有行被过滤时,min(timestamp)通过_minmax_count_projection返回1970-01-01纪元值的问题。
  • 轻量更新后DROP COLUMN失败(PR #96861):修复了对同一列先执行 lightweight update(UPDATE ... WHERE的轻量更新)再执行ALTER TABLE DROP COLUMN失败的问题。

5.7 权限与角色

  • ATTACH视图 SQL Security 权限提升风险(PR #94865):移除ATTACH查询中视图 SQL Security 不必要的权限跳过检查,防止用户以未经验证权限的 definer 附加视图造成权限提升。这是安全相关修复,建议尽快升级。
  • AccessRights::contains部分撤销返回错误(PR #96170):修复部分撤销(partial revokes)场景下权限包含判断结果错误。
  • 撤销默认角色(PR #96103):修复 revoke 默认角色失败的问题。

5.8 可观测性与格式

  • 全局 profiler 周期截断(PR #96048):修复了由global_profiler_real_time_period_nsglobal_profiler_cpu_time_period_ns控制的全局 profiler 周期——此前使用的是截断值而非设定值,导致 profiler 唤醒过于频繁。
  • system.asynchronous_metric_log的 event_date(PR #95947):修复该日志表 event_date 不正确的问题。
  • formatDateTime未初始化值(PR #96133):修复非定宽格式化器(MySQL 风格、JODA 风格)下的 use-of-uninitialized-value。

5.9 内存安全与稳定性(内部维护类)

  • 修复CREATE TABLE带 constraints 时的heap-use-after-free(PR #96669)。
  • 修复向量相似度索引中的stack-use-after-scope(PR #96259)。
  • 修复MergeTreeReadPoolBase的析构顺序(PR #95393)。
  • 修复applyUncommittedState对无路径 delta 的断言失败(PR #95846)。
  • 恢复特殊 MergeTree 允许空 order by keys 的行为(PR #96058)。
  • bech32 witness 版本校验,避免缓冲区溢出(PR #96671)。

5.10 数据湖集成(Iceberg / Delta Lake)

  • Iceberg position delete 空引用(PR #96061):修复 manifest 中 position delete 引用数据文件为 null 时无法获得正确边界的问题。
  • Iceberg ORDER BY 崩溃(PR #96484):修复 iceberg 查询中 order by 的崩溃问题。
  • Iceberg position delete 日志增强(PR #95901):增加 position deletes 追踪日志。
  • Delta Lake 分区数据 squashing(PR #95773):修复分区化 delta lake 数据合并(squashing)问题。

5.11 窗口函数与其他

  • 窗口函数 +group_by_use_nulls(PR #96878):修复group_by_use_nulls = 1且使用 CUBE/ROLLUP/GROUPING SETS 时窗口函数的Bad cast异常。
  • arrayJoin重复行(PR #96989):修复部分谓词下推优化错误地将含arrayJoin的过滤条件下推到 JOIN 下方,导致arrayJoin配合 INNER JOIN 与 WHERE 产生重复行的问题。
  • 运行时过滤中的 Nullable 连接列竞态(PR #95775):修复运行时过滤(runtime filters)中 Nullable 连接列的竞态条件。

六、构建与测试改进

  • Docker 镜像版本固定(PR #96500):将第三方 Docker 镜像固定到具体版本,提升构建可复现性,避免基础镜像漂移导致的构建不一致。
  • 另有 PR #97289 标记为NO CL CATEGORY,属于发布流程中的杂项提交。

七、升级建议与验证要点

综合以上分析,从 v26.1.2.11-stable 升级到 v26.1.3.52-stable 时建议重点核对:

  1. 系统表改名(必须行动)system.s3queuesystem.s3queue_metadata_cachesystem.azure_queuesystem.azure_queue_metadata_cache,更新所有依赖这些表的脚本与监控;历史统计请使用system.s3queue_log
  2. 安全修复优先ATTACH视图权限检查(PR #94865)属于权限提升类修复,公网暴露的实例应尽快升级。
  3. JSON(SKIP path)行为修正:若你的表结构使用了JSON(SKIP ...),本版本改变了键匹配语义(精确匹配代替前缀匹配),建议审查相关写入链路。
  4. 数据正确性类修复:多 JOIN +USING的类型推断、外连接重排、tupleElement嵌套路径、_minmax_count_projection与 TTL、轻量更新后 DROP COLUMN 等修复,建议在升级后的回归测试中覆盖对应查询形态。
  5. 性能收益无需配置CachedOnDiskReadBufferFromFile内存占用缩小、DeltaLake 系统表元数据跳过对象存储读取等改进为透明收益。

相关实现与文档的仓库路径汇总:

  • 发布日志原文:docs/changelogs/v26.1.3.52-stable.md
  • S3/Azure 队列元数据缓存表注册与使用说明:src/Storages/ObjectStorageQueue/registerQueueStorage.cpp
  • 系统表挂载:src/Storages/System/attachSystemTables.cpp
  • 磁盘缓存读取缓冲区实现:src/Disks/IO/CachedOnDiskReadBufferFromFile.h
  • optimize_syntax_fuse_functionsenable_nullable_tuple_type设置定义:src/Core/Settings.cpp
  • 聚合函数融合 Pass:src/Analyzer/Passes/FuseFunctionsPass.cpp
  • 设置演进历史(Nullable(Tuple)GA 记录):src/Core/SettingsChangesHistory.cpp

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

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

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

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

立即咨询