ClickHouse v25.5.5.19-stable 技术解读:Keeper ACL 治理增强、HTTP 响应头兼容与稳定性修复
【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse
本篇文章基于当前仓库 docs/changelogs/v25.5.5.19-stable.md 的发布说明,结合源码逐项解读 ClickHouse 25.5 系列第五个稳定补丁版本的关键变更。读者将理解keeper_server.cleanup_old_and_ignore_new_acl配置的使用前提与代码路径、X-ClickHouse-Summary响应头格式回退的前因后果,以及五类用户可见 Bug 修复与 libxml2 依赖升级的实操影响,便于评估升级风险并设计验证方案。
版本概览:v25.5.5.19-stable 的定位
该变更日志由 ClickHouse 发布流程自动生成,标题中标明本次构建为v25.5.5.19-stable(commitc7635f09ae1),对比基线为上一补丁版本v25.5.4.38-stable(commit304d67604cf)。日志模板中的FIXME占位符是发布脚本生成的通用标记,不代表功能缺陷。
从变更分类看,本次发布包含:
- 3 项功能改进(Improvement):两项围绕 Keeper(ClickHouse 内置的 ZooKeeper 替代协调服务),一项围绕 HTTP 响应头兼容性;
- 5 项用户可见 Bug 修复(Bug Fix):覆盖查询分析器、远程查询并发、行级安全、字符串函数与聚合序列化;
- 1 项构建/测试/打包改进:升级 libxml2 至 v2.14.4。
整体定位是低风险、高兼容性的稳定补丁版本,重点在于消除 v25.5 主线在协调服务 ACL 治理、协议头兼容和边界场景上的回归。
Keeper 改进一:cleanup_old_and_ignore_new_acl——彻底移除 ACL 的治理开关
变更日志的第一项改进(PR #82496)为 Keeper 引入新配置keeper_server.cleanup_old_and_ignore_new_acl。该配置的语义是:启用后,所有已存在节点的 ACL 将被清除,同时新请求携带的 ACL 将被忽略。
配置解析位置
该配置在 Keeper 上下文初始化阶段被读取,位于 src/Coordination/KeeperContext.cpp:
block_acl = config.getBool("keeper_server.cleanup_old_and_ignore_new_acl", false);默认值为false,即默认行为保持不变——只有显式开启才会触发 ACL 清理/忽略。上下文中通过shouldBlockACL()暴露该开关(src/Coordination/KeeperContext.cpp),并保留setBlockACL()供运行时调整。
底层执行路径
ACL 过滤逻辑位于 src/Coordination/KeeperStorageImpl.cpp 的fixupACL()函数。函数开头即为短路判断:
if (block_acl || request_acls.empty()) return true;即当block_acl为真时,请求携带的 ACL 列表直接跳过合法性校验与落地,新节点将以空 ACL(等价于无 ACL 限制)创建。
升级实操要点
变更日志特别强调了一个关键操作时序:
If the goal is to completely remove ACL from nodes, it's important to leave the config enabled until a new snapshot is created.
原因是 Keeper 的 ACL 状态会持久化到快照(snapshot)与日志(log)中。若在生成新快照之前关闭该配置,重启或 Leader 切换后,旧快照中的 ACL 可能重新生效。因此完整迁移步骤建议为:
- 在所有 Keeper 节点配置
keeper_server.cleanup_old_and_ignore_new_acl: true; - 等待集群生成包含"无 ACL"状态的新快照(可通过
system.zookeeper或 Keeper 的监控指标确认快照时间戳); - 确认所有下游客户端已不再依赖 ACL 校验后,再决定是否移除该配置。
该配置的典型场景是:历史集群曾启用过 ACL,但后续希望彻底放开访问控制,且不希望逐个节点手工setACL清理。
Keeper 改进二:world:anyoneACL 支持具体权限
第二项 Keeper 改进(PR #82755)解决了world:anyoneACL 只能表达"全部权限"的问题,使其支持携带具体权限位。
对应实现同样位于fixupACL()中(src/Coordination/KeeperStorageImpl.cpp):
else if (request_acl.scheme == "world" && request_acl.id == "anyone") { /// Save world:anyone ACLs to support specific permissions if (request_acl.permissions != Coordination::ACL::All) result_acls.push_back(request_acl); valid_found = true; }代码逻辑清晰可见:当权限不是All(全部权限)时,world:anyoneACL 会被保留进结果;这与传统 ZooKeeper 中world:anyone默认拥有全部权限的行为形成差异,让 Keeper 可以表达"所有用户仅可读/仅可写"这类细粒度开放策略。对于权限为All的world:anyone,行为与之前一致。
HTTP 响应头:X-ClickHouse-Summary格式回退
第三项改进(PR #82727)与 HTTP 接口的进度/汇总响应头有关。
背景
早期 PR #73834 修改了X-ClickHouse-Progress与X-ClickHouse-Summary两个头部的 JSON 序列化格式,省略零值字段。本次发布决定仅对X-ClickHouse-Summary恢复旧行为,理由是汇总信息中保留完整字段(含零值)更有意义;X-ClickHouse-Progress维持省略零值的紧凑格式。
源码实现
两个头部的写入逻辑集中在 src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp:
void WriteBufferFromHTTPServerResponse::writeHeaderSummary() { accumulated_progress.incrementElapsedNs(progress_watch.elapsed()); /// Write the verbose summary with all the zero values included, if any. /// This is needed for compatibility with an old version of the third-party ClickHouse driver for Elixir. writeHeaderProgressImpl("X-ClickHouse-Summary: ", Progress::DisplayMode::Verbose); } void WriteBufferFromHTTPServerResponse::writeHeaderProgress() { writeHeaderProgressImpl("X-ClickHouse-Progress: ", Progress::DisplayMode::Minimal); }X-ClickHouse-Summary使用Progress::DisplayMode::Verbose(包含全部零值字段),而X-ClickHouse-Progress使用Progress::DisplayMode::Minimal(省略零值)。源码注释直接点明动机:兼容旧版第三方 Elixir ClickHouse 驱动。
升级影响
- 依赖
X-ClickHouse-Summary完整 JSON 字段(含read_rows=0、written_rows=0等零值)的客户端,在升级到本版本后行为恢复一致; - 依赖
X-ClickHouse-Progress字段集合的客户端,行为与 v25.5 中期版本保持一致,无需调整; - 通过 HTTP 接口(
/、/query)执行查询并解析这两个响应头的工具,建议在升级后做一次回归验证。
用户可见 Bug 修复详解
1. 仅含常量别名列的过滤分析错误(PR #82037)
修复当查询的过滤条件中只使用常量别名列时分析器(Analyzer)的错误。原问题单 #79448 反映的场景典型于形如SELECT ... WHERE const_alias的查询,其中const_alias是常量表达式别名。修复后,仅依赖常量别名列进行过滤的查询可被正确分析与执行,相关改动作用于 src/Analyzer 目录下的过滤表达式分析逻辑。
2. 内存压力下远程查询的死锁(PR #82160)
修复服务器内存压力(memory pressure)较大时,远程查询可能触发的死锁。分布式查询在执行阶段会借道内存追踪与内存超限(memory_tracker)机制,在高并发下存在等待资源时的锁序风险。该修复提升了clickhouse-server在内存接近上限时的健壮性,对使用分布式表(Distributedengine)的集群尤为相关。建议在高负载集群升级后,配合 tests/integration 中的内存压力相关用例进行稳定性回归。
3. 行级安全表达式的LOGICAL_ERROR(PR #82618)
修复相关列(correlated columns)参与行策略(row policy)表达式分析时抛出LOGICAL_ERROR的问题。行级安全(CREATE ROW POLICY)在查询解析阶段会将策略条件注入查询语法树,当策略表达式引用外层查询的相关列时,分析器此前会误判。修复位于分析器对行策略表达式的相关列处理路径,建议使用system.row_policies且策略中包含相关子查询或复杂表达式的用户重点验证。
4.trim{Left,Right,Both}支持FixedString(N)(PR #82691)
修复trimLeft/trimRight/trimBoth对FixedString(N)类型输入的处理。此前这些函数对FixedString输入可能因尾随\0填充而行为异常,现在与普通String输入保持一致。变更日志给出了可直接验证的示例:
SELECT trimBoth(toFixedString('abc', 3), 'ac'); -- 现在可正常工作注意FixedString的长度语义:toFixedString('abc', 3)恰好长度为 3,无填充;若使用toFixedString('abc', 5),则尾部两个\0字节的处理逻辑也一并修正。相关实现位于 src/Functions 下 trim 系列函数中,改动同时覆盖FixedString与String的通用执行路径。
5.groupArraySample/groupArrayLast空元素反序列化(PR #82763)
修复groupArraySample与groupArrayLast聚合结果在元素为空时的反序列化缺陷:若输入数据为空,反序列化可能跳过部分二进制流,导致数据读取损坏,并在 TCP 协议下报出UNKNOWN_PACKET_FROM_SERVER。
变更日志明确指出该问题不影响数值类型与日期时间类型,仅影响可能产生空元素的类型(典型如Array、String、Nullable等变长或可空类型)。建议使用这两个聚合函数且通过 TCP 原生协议(clickhouse-client、JDBC/ODBC 原生连接)消费结果的用户,升级后执行针对空分组场景的读写回归。
构建与打包改进:libxml2 升级至 v2.14.4
本次发布将捆绑的libxml2依赖升级到 v2.14.4(PR #82649 中的 XML 相关输入/输出格式(如XML输出格式、XPath相关函数)。依赖升级通常带来安全修复与解析稳定性改进,对使用 XML 格式输出或复杂 XML 配置的用户属于无感变更,但建议打包分发版本(RPM/DEB)在升级后冒烟验证clickhouse-server的配置解析与SELECT format(..., 'XML')输出。
升级建议与验证清单
综合以上变更,v25.5.5.19-stable 的升级建议归纳如下:
| 变更 | 涉及组件 | 升级关注点 | 验证建议 |
|---|---|---|---|
cleanup_old_and_ignore_new_acl | Keeper | 配置默认关闭,需显式开启并配合快照生成时序 | 在测试集群验证快照重建后 ACL 彻底移除 |
world:anyone具体权限 | Keeper | 新增细粒度权限能力,不影响旧行为 | 用setACL写入非All权限并验证读取 |
X-ClickHouse-Summary回退 | HTTP 接口 | 汇总头恢复含零值完整字段 | 解析响应头并对比字段集合 |
| 常量别名列过滤 | Analyzer | 修复WHERE仅含常量别名的查询 | 执行含常量别名的过滤查询 |
| 远程查询死锁 | 分布式执行 | 内存压力下的并发健壮性 | 高并发 + 低max_memory_usage压测 |
行策略LOGICAL_ERROR | Analyzer / Access | 相关列场景 | 回归system.row_policies注入查询 |
trim*支持FixedString | Functions | 行为与String对齐 | 执行示例SELECT trimBoth(toFixedString('abc', 3), 'ac') |
groupArraySample/Last反序列化 | AggregateFunctions / TCP | 空元素场景,不影响数值与时间类型 | 空分组 + 原生 TCP 协议读写回归 |
| libxml2 v2.14.4 | 构建依赖 | XML 解析与 XML 格式 | 冒烟验证配置加载与 XML 格式输出 |
该版本不包含破坏性的配置或协议变更,两个 Keeper 改进均为新增能力(默认关闭或向后兼容),HTTP 头回退仅影响依赖"省略零值"行为的极少数客户端。对于运行 25.5 系列且受上述 Bug 影响的用户,建议尽快升级;对使用 Keeper ACL 治理或 Elixir 驱动等兼容性敏感场景,请按上文清单逐项验证。
【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考