ClickHouse v25.1.5.31-stable 版本解析:Keeper 提交摘要优化、workload 强制调度与 7 项关键缺陷修复
2026/9/17 16:06:35 网站建设 项目流程

ClickHouse v25.1.5.31-stable 版本解析:Keeper 提交摘要优化、workload 强制调度与 7 项关键缺陷修复

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

本文基于 docs/changelogs/archive/v25.1.5.31-stable.md 官方变更日志,逐条解析 ClickHouse v25.1.5.31-stable 相对 v25.1.4.53-stable 的全部变更:两项功能改进(Keeper 提交路径禁用 digest 计算、新增throw_on_unknown_workload服务器设置)与七项用户可见缺陷修复,并结合当前仓库中的源码实现(KeeperContext.h、ServerSettings.cpp、IBridgeHelper.cpp)与回归测试,说明每项变更的实际影响、默认值与配置方式。读完本文,你可以判断该补丁版本对 Keeper 高负载部署、workload 资源调度治理与 ODBC/JDBC 桥接安全性的具体意义。

版本定位:一个纯补丁性的稳定分支发布

该版本基于 commit48f17e8a805,对照基线为 v25.1.4.53-stable(commitc3f28b8bf5d)。全部条目均为 backport(回合),即这些修复先在主线完成,再回合进 25.1 稳定分支后随补丁版本发布,因此该版本不包含新特性,只包含性能改进与缺陷修复。对于运行 25.1 生产环境的团队,这类版本是典型的"低风险、高收益"升级对象。

改进一:Keeper 提交时跳过 digest 计算

变更内容:Keeper 在把事务提交到内存存储(in-memory storage)时不再计算 digest(摘要),可显著提升提交路径性能;digest 在请求预处理阶段仍然照常计算。该行为可通过keeper_server.digest_enabled_on_commit配置项重新开启。

源码印证:在 src/Coordination/KeeperContext.h 中可以看到两个相关状态字段的定义:

bool digest_enabled{true}; // 预处理阶段 digest,默认开启 bool digest_enabled_on_commit{false}; // 提交阶段 digest,默认关闭(本版本变更点)

在 src/Coordination/KeeperContext.cpp 中,该配置从服务器 XML 配置解析,默认值为false

digest_enabled_on_commit = config.getBool("keeper_server.digest_enabled_on_commit", false);

配置示例(若要恢复旧行为):

<keeper_server> <digest_enabled_on_commit>true</digest_enabled_on_commit> </keeper_server>

原理说明:Keeper 采用类 Raft 的日志复制协议(NuRaft)。digest 用于在日志条目处理时快速比对数据是否一致。在"提交到内存存储"这一热点路径上跳过摘要计算,省去的是每次 commit 的重复哈希开销;而保留预处理阶段的 digest 计算,保证了请求进入队列前的一致性校验能力不降级。对于以 Keeper 作为协调后端(ZooKeeper 协议兼容)的 ClickHouse 集群,高 QPS 的事务型负载(如分布式 DDL、fence 写入)将从中受益。

改进二:新增服务器设置throw_on_unknown_workload

变更内容:新增服务器设置throw_on_unknown_workload,控制查询中workload设置指向未知 workload 时的行为——默认(false)允许无限制访问;设为true则抛出RESOURCE_ACCESS_DENIED异常。该设置的价值在于:当 workload 层级(hierarchy)建立完成后,可以强制所有查询都必须走 workload 调度,杜绝"绕过资源配额"的漏网查询。

源码印证:该设置在 src/Core/ServerSettings.cpp 中声明,默认值false,且属于ChangeableWithoutRestart::Yes类(即可通过SYSTEM RELOAD CONFIG热更新,无需重启,见 src/Core/ServerSettings.cpp 的注册处)。设置自带的官方说明写道:

Iftrue, RESOURCE_ACCESS_DENIED exception is thrown from a query that is trying to access unknown workload. Useful to enforce resource scheduling for all queries after WORKLOAD hierarchy is established and contains WORKLOAD default. Iffalse(default), unlimited access w/o resource scheduling is provided to a query with 'workload' setting pointing to unknown WORKLOAD.

推荐的落地流程

  1. 先创建 WORKLOAD 层级并添加defaultworkload;
  2. 期间保持throw_on_unknown_workload为默认的false,让客户端逐步迁移;
  3. 全部客户端接入后开启强制模式,此后未定义 workload 的查询将被拒绝:
<throw_on_unknown_workload>true</throw_on_unknown_workload>

该机制与cpu_slot_preemption(见 src/Core/ServerSettings.cpp 相邻声明)等 workload 调度设置共同构成 ClickHouse 的资源治理体系:前者管"CPU 槽位如何分配与抢占",后者管"未接入调度的查询如何处置"。

Bug Fix:七项用户可见缺陷修复逐项解析

1. 部分存储引擎对不支持类型的检查

为若干存储引擎(storage)补充"不支持的数据类型"校验,创建表时即可提前报错,避免数据写入后再暴露兼容性问题。属于防御性检查增强,对已有表无影响。

2. JOIN ON 子句中 null-safe 比较与类型别名的问题

修复了在JOIN ... ON子句中使用 null-safe 比较(<=>)且表达式带类型别名(type alias)时的类型推导问题。此前此类写法会产生错误的类型行为,本版本后a.key <=> b.key配合别名/类型别名可正常求值。

3. PSQL 复制中的崩溃修复

修复 PostgreSQL 逻辑复制(PSQL replication)中未捕获异常导致的进程崩溃。此前若复制链路出现特定错误,异常会越过异常边界直接打崩 server;本版本将其收敛为可恢复错误。

4. SASL/Kerberos:ticket 过期时重试 RPC 调用

SASL 认证层此前存在缺陷:Kerberos ticket(krb5 ticker)过期时,任意一次 RPC 调用都可能直接失败且不会重试。本版本修复了该问题,使调用在 ticket 过期场景下能够自动重复发起,对使用 Kerberos 认证的长连接部署(典型如 HDFS 访问路径)更健壮。

5. 修改 projection PK 列后自动重建 projection

这是本版本中最具生产价值的一项修复。此前:对某列执行ALTER TABLE ... MODIFY COLUMN,若该列被某 projection 的主键(PK)引用,projection 不会随之重建,后续SELECT可能触发CANNOT_READ_ALL_DATA错误。本版本开始,当 alter modify 作用于 projection 的 PK 列时,系统会自动重建该 projection,消除这一类"改列之后查询报错"的隐蔽故障。

6. 在设置变更历史中记录 v24.12 默认启用并行 hash join

这是一条"元数据补记":v24.12 起默认启用并行 hash join 算法这一事实被正式记录进 settings change history(设置变更历史)。其实际含义是:如果你通过compatibility等机制把服务器兼容级别配置到低于 v24.12的旧版本,ClickHouse 会继续使用非并行 hashjoin 算法。这保证了旧兼容级别下行为与当年版本一致,也解释了为什么"老兼容级别下 join 变慢/变快"的现象是预期行为而非 bug。对应的无状态回归测试为 tests/queries/0_stateless/03274_join_algorithm_default.sql,本版本同时修复了该测试本身的问题(见下节)。

7. 安全修复:限制clickhouse-library-bridge可加载的库路径

这是本版本唯一的安全漏洞修复。clickhouse-library-bridge是 ClickHouse 为支持 UDF 动态加载等能力引入的辅助进程;此前它允许从文件系统任意位置打开动态库,因此设计上要求只能运行在隔离环境中。若它与clickhouse-server部署在同一主机上,恶意库路径即构成漏洞。本版本将其可加载库的路径限定在配置文件中提供的目录之内。

源码印证:从当前仓库的 src/BridgeHelper/IBridgeHelper.cpp 可以看到 bridge 可执行文件的定位逻辑——bridge 路径基于配置项application.dir(默认/usr/bin)拼接服务文件名得到,正是"路径受配置约束"这一安全模型在桥接启动侧的体现:

const auto & config = getConfig(); /// Path to executable folder fs::path path(config.getString("application.dir", "/usr/bin")); VectorWithMemoryTracking<std::string> cmd_args; path /= serviceFileName();

该漏洞由 ClickHouse Bug Bounty Program 的 Arseniy Dugin 发现。对于自行编译或部署 bridge 的用户,升级后应确认库文件均位于配置允许的路径内。

其余不对外公告的修复(NOT FOR CHANGELOG)

变更日志还列出了 6 项未进入正式公告的内部修复,对排查特定问题仍有参考价值:

  • ObjectStorageQueue 元数据关闭崩溃:修复ObjectStorageQueueMetadata在 shutdown 时的崩溃("Hopefully fix" 表述说明该问题复现概率低、修复带有一定不确定性);
  • ASTTTLElement函数名规范化:TTL 表达式中的函数名解析更规范;
  • DisksApp 初始化顺序修复:消除'Placement info has not been loaded''The IOThreadPool is not initialized'两类启动期报错;
  • ~Workload()析构不再抛异常:析构函数中抛异常属于未定义行为隐患,此项属于工程健壮性修复,与上文throw_on_unknown_workload同属 workload 子系统的配套完善;
  • 解压测试日志增强:为 decompressing 相关测试补充更多日志;
  • 测试修复03274_join_algorithm_default测试用例本身的修复(对应上文第 6 条的兼容级别行为)。

升级建议

  • 运行 25.1.x 生产环境的团队:本版本为纯 backport 补丁,风险低。其中 projection PK 列修改后的自动重建、Kerberos ticket 过期重试、PSQL 复制崩溃三项可直接改善可用性,library-bridge路径限制则是应当尽快获得的安全修复,建议升级;
  • Keeper 集群:升级后 commit 路径默认不再计算 digest,属"开箱即得"的性能改进;若你的部署依赖 commit 阶段摘要校验,请显式配置keeper_server.digest_enabled_on_commit = true
  • 使用 workload 调度的团队:可借助throw_on_unknown_workload(支持热更新)完成"全量查询纳入调度"的最后一步治理;
  • 使用 Kerberos/ODBC-JDBC 桥接的部署:升级并复核 bridge 相关配置路径,确保库文件位于允许的目录内。

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

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

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

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

立即咨询