ClickHouse v25.4.3.22-stable 版本解析:性能优化、访问控制改进与关键缺陷修复
2026/9/18 14:16:31 网站建设 项目流程

ClickHouse v25.4.3.22-stable 版本解析:性能优化、访问控制改进与关键缺陷修复

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

本文基于官方仓库 docs/changelogs/v25.4.3.22-stable.md 的发布说明,逐项剖析 ClickHouse 25.4 补丁版本(v25.4.3.22-stable,commit f23535c7722)在性能、访问控制与稳定性上的变更,并结合源码讲解每一项改动背后的实现原理、适用场景与升级注意事项。读完本文,你将能判断该版本是否适合你的集群,并理解LogSeriesLimiterenable_user_name_access_type、服务端下发的async_insert设置等关键机制的底层行为。

版本背景与定位

v25.4.3.22-stable 是 ClickHouse 25.4 系列的一个补丁版本,与上一版 v25.4.2.31-stable(commit e2ce00b6885)相比,改动集中在性能提升、行为改进与用户可见缺陷修复三类。这类补丁版本面向生产环境,特点是改动范围收敛、向后兼容优先,一般建议在充分验证后滚动升级。

整个 25.4 版本线的历史变更可查看仓库的 docs/changelogs 目录,其中v25.4.3.22-stable.md位于 docs/changelogs/v25.4.3.22-stable.md。

性能改进:LogSeriesLimiter不再在每次构造时执行清理

PR 79864(Backport 自 issue 79924):修复LogSeriesLimiter在每次构造时都执行清理的问题,避免高并发场景下的锁竞争与性能回退。

LogSeriesLimiter是 ClickHouse 日志基础设施中的一个核心组件,用于"整组接受或整组静默"日志序列,防止同类对象产生过于嘈杂的日志。其实现位于 src/Common/LoggingHelpers.h 与 src/Common/LoggingHelpers.cpp:

  • 它以(logger_name, allowed_count, interval_s)为参数构造,在给定时间窗口内最多接受allowed_count条日志,其余静默;
  • 所有实例共享一个静态的SeriesRecords表(Hash(logger_name) -> (last_logged_time_s, accepted, muted)),并通过静态互斥锁std::mutex mutex保护;
  • 旧逻辑在构造函数内即执行过期记录的清扫(cleanup),清理动作需要获取全局互斥锁。在高并发场景下,大量日志对象被频繁构造时,每次构造都抢锁做全表清理,会造成明显的锁竞争和性能回退。

本次修复将清理逻辑从"每次构造必然执行"改为惰性、有条件的清理:仅在last_cleanup落后于cutoff_time(当前时间减去 600 秒的清理延迟阈值)时才触发std::erase_if删除过期记录(见 src/Common/LoggingHelpers.cpp 中LogSeriesLimiter构造函数与getSeriesRecords()的实现)。同样的按需清理模式在LogFrequencyLimiterImpl中早已存在——它通过last_cleanup + 300 <= now判断并配合thread_local_rng() % 100 == 0随机化来避免所有线程同时清理(src/Common/LoggingHelpers.cpp)。

升级价值:在大量使用 MergeTree 合并、S3 复制、压缩块读取等会产生高频重复日志路径的场景(LogSeriesLimiter被广泛用于 src/Storages/MergeTree/Compaction/PartsCollectors 与 src/IO/S3/copyS3File.cpp 等模块),该改动可显著降低日志路径上的锁开销。

改进:新增access_control_improvements.enable_user_name_access_type

PR 79842(Backport 自 issue 79904):新增服务器配置项access_control_improvements.enable_user_name_access_type,用于开启/关闭对用户/角色的精确授权(precise grants)能力。该能力最初由 PR 72246 引入,25.1 之后版本才具备。

从源码看,该配置在 src/Access/AccessControl.cpp 中加载:

/// Set `true` by default because the feature is backward incompatible only when older version replicas are in the same cluster. setEnableUserNameAccessType(config_.getBool("access_control_improvements.enable_user_name_access_type", true));

其 setter/getter 同样位于该文件(setEnableUserNameAccessType/isEnableUserNameAccessType),读取后存入AccessControl成员供权限判定使用。相关的权限元素解析逻辑位于 src/Access/Common/AccessRightsElement.cpp。

为什么需要这个开关

当集群中混有25.1 之前版本的副本时,旧副本无法理解新增的精确授权语义,可能导致授权行为不一致或同步异常。因此:

  • 默认值为true,在纯新版本集群中开启精确授权;
  • 如果你的集群包含早于 25.1 的副本,建议显式关闭:
<clickhouse> <access_control_improvements> <enable_user_name_access_type>false</enable_user_name_access_type> </access_control_improvements> </clickhouse>

该配置项与access_control_improvements组下的其他开关(如table_engines_require_grantenable_read_write_grantsthrow_on_unmatched_row_policies等)并列,属于"向后兼容改进"类开关,配置生效需要重启服务端(或按 access control 配置热加载机制生效)。

改进:ASTSelectWithUnionQuery::clone()正确处理is_normalized字段

PR 79909(Backport 自 issue 79934)ASTSelectWithUnionQuery::clone()现在会正确拷贝is_normalized字段,此前该字段在克隆时丢失。这有助于修复 issue 77569 中出现的相关问题。

在 src/Parsers/ASTSelectWithUnionQuery.cpp 中可以看到clone逻辑显式复制了该字段:

res->is_normalized = is_normalized;

is_normalized标识一个SELECT ... UNION ...查询的 AST 是否已被"规范化"(归一化处理),它影响后续查询改写与执行阶段的判断。克隆丢失该字段会导致:基于克隆 AST 的下游处理(如查询改写、物化视图匹配、缓存路径等)得到错误的规范化状态,进而引发行为偏差。该修复确保 AST 克隆在语义上与原节点完全等价,是查询处理正确性的基础性修补。

缺陷修复:用户可见的问题

本版本共包含 5 项用户可见缺陷修复,均以"Backport"方式从主线移植,属于官方稳定版发布中明确标注的 Bug Fix 类别。

1. 修复服务端下发的async_insert设置导致客户端报 "Unknown packet 11 from server"

PR 77578(Backport 自 issue 79820):此前,当客户端通过apply_settings_from_server应用服务端下发的设置时,若其中包含async_insert相关设置,会在客户端触发Unknown packet 11 from server错误。

该问题的根源在于apply_settings_from_server这一客户端设置:它在 src/Client/ClientBase.cpp 中声明(extern const SettingsBool apply_settings_from_server;),并在客户端主流程中决定是否采用服务端会话下发的设置值(src/Client/ClientBase.cpp 中apply_settings_from_server的读取点);服务端对应逻辑在 src/Server/TCPHandler.cpp 中——当会话配置了该设置时,服务端会在握手/会话初始化阶段将一组设置下发到客户端。当这批下发设置包含客户端协议不认识的async_insert类型时,客户端协议解析就会收到意外的 packet 11(Query类数据包),导致连接错误。

本次修复使服务端在下发设置时对async_insert做正确处理,客户端不再收到无法解析的数据包。影响面:所有使用async_insert且同时依赖服务端设置下发的客户端场景,升级后可正常执行异步插入。

2. 修复可刷新物化视图(Refreshable Materialized Views)破坏备份

PR 77893(Backport 自 issue 79785):可刷新物化视图(REFRESHABLE MATERIALIZED VIEW)此前会导致备份(BACKUP)失败或备份内容异常。该修复保证了包含可刷新物化视图的库表可以被BACKUP/RESTORE正确处理。涉及备份恢复的核心逻辑位于 src/Backups 目录(如 src/Backups/RestorerFromBackup.cpp),升级后可重新对相关实例执行全量/增量备份验证。

3. 修复 MergeTree Wide parts 中动态子列(dynamic subcolumns)发现导致的崩溃

PR 79466(Backport 自 issue 79741):当 MergeTree 表的 Wide 数据部分(part)包含Dynamic类型列的动态子列(如动态类型 JSON 数据的子列)时,子列发现逻辑可能触发崩溃。该修复完善了 Wide parts 中子列的发现与读取流程。动态子列相关实现主要位于 src/Columns 与 MergeTree 存储层(src/Storages/MergeTree)。影响面:使用Dynamic/JSON类型且存储格式为 Wide 的表,升级可消除偶发崩溃风险。

4. 仅在初始建表时校验表名长度,避免兼容性问题

PR 79488(Backport 自 issue 79585):表名长度校验改为仅对初始建表(initial create)查询执行,对副本上由复制机制触发的二次建表(secondary create,如ReplicatedMergeTree从 ZooKeeper 日志重放建表)不再重复校验。这是为了保证与旧版本写入元数据(表名超长但不影响运行)的向后兼容,避免升级后副本因历史遗留的长表名而无法正常拉起。

5.CREATE DATABASE datalake查询中隐藏密码

PR 79941(Backport 自 issue 79973)CREATE DATABASE datalake ENGINE = DataLakeCatalog('http://catalog:8181', 'admin', 'password')这类语句中的密码此前会在日志/查询日志中明文暴露,本次修复将其在显示与记录时脱敏。

DataLakeCatalog 相关引擎实现在 src/Databases/DataLake 目录(如 DatabaseDataLake.cpp、RestCatalog.cpp),密码脱敏依赖解析器层的参数保密机制(src/Parsers/FunctionSecretArgumentsFinder.cpp),该机制同样用于隐藏s3(...)mysql(...)等表函数中的密钥参数。升级后,建议检查system.query_log中历史敏感语句的暴露情况。

非用户可见修复(NOT FOR CHANGELOG / INSIGNIFICANT)

除上述改动外,该版本还包含三类不进入 changelog 的次要修复:

  • 修复 S3Queue 中的断言失败(PR 78792,backport 自 issue 80018):S3Queue 引擎在特定并发/重试路径下可能触发 assert,该修复消除了此隐患,涉及 src/Storages/ObjectStorageQueue 目录(如 ObjectStorageQueuePostProcessor.cpp)。
  • 落实代码评审意见(PR 79399,backport 自 issue 79775):对既有合入代码进行评审修正,无行为级变更。
  • 禁用经证明不稳定的设置(PR 79896):PR 63206 与 PR 78778 引入的某些设置被证明不稳定,该版本将其禁用。这提示用户:部分新特性设置可能在后续补丁中被回退或禁用,生产环境启用新设置前应关注版本线内的稳定性反馈。

升级与验证建议

  1. 确认集群版本矩阵:如果你的副本同时存在 25.1 之前的版本,请先设置access_control_improvements.enable_user_name_access_type = false再升级,避免精确授权语义不一致。
  2. 重点回归:建议针对async_insert+ 服务端设置下发、可刷新物化视图的BACKUP/RESTOREDynamic/JSON类型 Wide 表读写这三条路径做冒烟测试,它们是本版本修复的核心缺陷面。
  3. 关注日志与查询日志脱敏:升级后可抽查system.query_log确认 DataLakeCatalog 等含敏感参数的语句是否已脱敏。
  4. 新设置默认值enable_user_name_access_type默认开启,纯新版本集群无需额外配置;存量集群按第 1 条评估。

结合仓库 docs/changelogs 目录下的历史 changelog 可以横向追踪每个修复的演进脉络;本版本各修复对应的实现文件(src/Common/LoggingHelpers.cpp、src/Access/AccessControl.cpp、src/Parsers/ASTSelectWithUnionQuery.cpp、src/Client/ClientBase.cpp 等)均已在上文列出,可供进一步深入阅读源码。

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

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

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

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

立即咨询