资讯动态

ClickHouse v26.2.15.4-stable 补丁版本深度解读:三大稳定性修复的源码级分析

发布时间:2026/9/19 17:02:23 来源:尧图企业网站定制
ClickHouse v26.2.15.4-stable 补丁版本深度解读三大稳定性修复的源码级分析【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse导读本文基于当前仓库的官方变更记录docs/changelogs/v26.2.15.4-stable.md逐条剖析 ClickHouse v26.2.15.4-stable 相对 v26.2.14.5-stable 引入的 3 个用户可见 Bug 修复ASTColumnsExceptTransformer的LOGICAL_ERROR、字符串检索器StringSearcher.h的未初始化值访问以及 CPU lease 调度器中定时器越过工作线程生命周期导致的 use-after-free。读完本文你将理解这三处缺陷的触发场景、底层修复思路以及如何在自建环境中复现验证为评估是否升级补丁版本提供依据。一、补丁版本概览v26.2.15.4-stable 修复了什么本次发布是一个典型的 stable 分支补丁版本构建提交为8df18e81311对比基线是上一个稳定版本 v26.2.14.5-stable提交edcd1986fd8。变更记录只包含一个分类Bug Fix用户可见的官方稳定版异常行为共 3 项。补丁版本的这类发布原则是不引入新功能只收敛稳定分支上已被社区确认并 backport 的问题。三个修复均先有上游 PR/Issue 编号如 #99119、#100225、#101761再以 backport 形式合入本分支对应 #102657、#101420、#102679这符合 ClickHouse 稳定分支的发布流程。三个修复覆盖了三类典型问题域查询改写列变换器、字符串检索文本函数核心路径与资源调度CPU lease 生命周期。下面逐一深入。二、修复一ASTColumnsExceptTransformer::transform中的 LOGICAL_ERROR2.1 缺陷背景ASTColumnsExceptTransformer是 ClickHouse 列变换器columns transformer机制的一部分对应 SQL 语法中的SELECT * EXCEPT (...)与SELECT * EXCEPT regexp。该机制在 src/Parsers/ASTColumnsTransformers.h 定义实际执行逻辑位于 src/Interpreters/applyColumnsTransformer.cpp。applyColumnsExceptTransformer见 applyColumnsTransformer.cpp的核心流程是若未指定正则模式则把EXCEPT列表中的子节点标识符或其别名/列名收集进expected_columns遍历当前节点列表将名称命中的列移除若声明了EXCEPT STRICTtransformer.is_strict且仍有未匹配到的列则抛出NO_SUCH_COLUMN_IN_TABLE异常提示Columns transformer EXCEPT expects following column(s) :...若指定了正则模式则通过getColumnsExceptMatcher编译re2::RE2正则用RE2::PartialMatch做部分匹配过滤列。当查询被旧分析器与新分析器Analyzer以不同顺序、不同时机重复应用列变换或EXCEPT列表中的节点形态标识符 vs 带别名的表达式与预期不符时内部不变量会被破坏从而在transform中触发LOGICAL_ERROR。这正是本补丁修复的用户可见异常合法查询在特定组合下直接报错。2.2 修复的意义与验证方式修复保证了列变换器在处理EXCEPT时对节点形态ASTIdentifier与带别名表达式的识别路径一致避免内部状态不一致。仓库中已有专门的状态测试脚本 tests/queries/0_stateless/01470_columns_transformers2.sql 覆盖了列变换器的组合用法例如SELECT * EXCEPT bytes, COLUMNS(bytes) APPLY formatReadableSize FROM columns_transformers;这行语句同时使用了EXCEPT 正则与COLUMNS(...) APPLY两种变换器正是列变换器组合场景的典型回归用例。你在自己的实例上可以通过构造「先EXCEPT排除、再对剩余列做APPLY/REPLACE」的嵌套查询来验证该路径不再抛出LOGICAL_ERROR。三、修复二StringSearcher.h中的未初始化值访问3.1 缺陷背景StringSearcher.hsrc/Common/StringSearcher.h是 ClickHouse 字符串检索基础设施的一部分被position、like、startsWith等高频文本函数使用。文件头部注释明确说明这类检索器在多数场景下性能低于 Volnitsky 算法见 src/Common/Volnitsky.h但适用于短模式与特定调用路径。文件内部实现了几种检索器CaseSensitiveStringSearcherStringSearcher.h区分大小写短 needle32 字节走逐字节比较循环长 needle 委托给 StringZilla 的sz_find/sz_equalASCIICaseInsensitiveStringSearcherStringSearcher.h不区分大小写的 ASCII 折叠版本在__AVX2__或__aarch64__ ARM_NEON下用向量指令构建首字符缓存patl/patu与 needle 前 N 字符的cachel/cacheu配合cachemask做无分支过滤。修复针对的 use-of-uninitialized-value 属于未定义行为在某些输入例如特定长度的 needle、空 needle、或走非向量化回退分支下检索器会读取未被完整初始化的缓存或栈数据导致 MemorySanitizerMSan在 CI 中报use-of-uninitialized-value。这类问题在正常构建下往往碰巧正常但在 sanitizer 构建、不同编译器或不同架构x86_64 AVX2 与 aarch64 NEON下可能产生非确定性结果。3.2 修复的影响面修复针对向量化缓存构造路径补齐了初始化保证无论 needle 长度如何cachemask与缓存字节都以确定的方式生成。值得注意的实现细节缓存掩码full_cache_mask专门按 32 位安全方式计算(N 32) ? 0xFFFFFFFFu : ((1u N) - 1u)避免1u 32的未定义行为向量路径填充 needle 字节时使用uint8_t needle_bytes[N] {};零初始化后再memcpy确保剩余字节确定。这意味着修复不仅消除了 sanitizer 告警也提升了检索器在不同 SIMD 架构上的确定性。如果你的部署通过positionCaseInsensitive等函数处理大量字符串检索升级后可关注相关路径的稳定性。四、修复三CPU lease 调度器中定时器越过线程生命周期的 use-after-free4.1 缺陷背景这是三个修复中风险最高的一项。CPU lease 调度器位于 src/Common/Scheduler 目录是 ClickHouse 并发控制/工作负载资源管理Workload Resource Management的一部分相关组件包括CPULeaseAllocation、CPUSlotsAllocation、WorkloadResourceManager等。缺陷描述为当等待定时器wait timer存活时间超过其引用的ProfileEvents::Counters所属工作线程时定时器刷新计数时访问已销毁的计数器对象造成 use-after-free 崩溃。根因分析CPULeaseAllocation在调度schedule()时需要记录等待耗时。旧实现可能在调度线程上下文里取CurrentThread::getProfileEvents()返回的计数器引用并交给ProfileEvents::Timer持有。一旦该工作线程先行退出、其Counters被销毁而定时器仍在排队等待刷新就会出现悬垂引用。4.2 修复方案用 ThreadGroup 所有权托管计数器生命周期修复的源码证据清晰体现在 src/Common/Scheduler/CPULeaseAllocation.cpp// Capture query-level counters (ThreadGroup) that outlive all worker threads. // Cannot use CurrentThread::getProfileEvents() in schedule() — it returns the calling // threads counters, which may be destroyed before the timer is flushed (UAF). wait_thread_group CurrentThread::getGroup(); if (wait_thread_group) wait_counters wait_thread_group-performance_counters;即不再捕获「调用线程」的计数器而是捕获查询所属 ThreadGroupThreadGroupPtr一个std::shared_ptr的计数器。ThreadGroup 的生命周期覆盖该查询的所有工作线程只要查询未结束其performance_counters就必然存活从而保证定时器在刷新时引用仍然有效。与之配套的成员声明顺序也有讲究见 src/Common/Scheduler/CPULeaseAllocation.h/// Stable counters for wait_timer. We cannot use CurrentThread::getProfileEvents() in /// schedule() because it returns the calling threads counters, which may be destroyed /// before the timer is flushed — storing a Timer with a dangling Counters causes UAF. /// The ThreadGroupPtr keeps the ThreadGroup (and its performance_counters) alive. /// Declared before wait_timer so the owner outlives the timer during member destruction. std::shared_ptrThreadGroup wait_thread_group; ProfileEvents::Counters * wait_counters ProfileEvents::global_counters; std::optionalProfileEvents::Timer wait_timer;两个关键点wait_thread_group声明在wait_timer之前——C 成员按声明顺序析构因此ThreadGroupPtr计数器所有者一定比定时器晚销毁即使析构路径上也安全兜底策略当线程组不可用时wait_thread_group为空wait_counters回退到进程级ProfileEvents::global_counters后者与全局进程同生命周期永不悬垂。4.3 测试与复现背景CPU lease 调度器是本版本中高度活跃且经过大规模重构的模块仓库在 src/Common/Scheduler/Nodes/tests/gtest_workload_resource_manager.cpp 中保存了大量调度器单测其中不乏针对生命周期问题的回归测试该文件注释中多次出现 use-after-free、outlive等主题。这类缺陷在并发压力大、线程频繁创建销毁的高负载场景下最容易浮出水面官方在 CHANGELOG 中以 user-visible misbehavior 定性说明其可能造成服务端进程崩溃。五、升级建议与验证清单5.1 是否值得升级本次三个修复均针对 stable 分支的稳定路径修复项触发场景风险等级ASTColumnsExceptTransformerLOGICAL_ERROR使用EXCEPT/APPLY/REPLACE列变换器的复杂查询中等查询报错StringSearcher.h未初始化值大量字符串检索函数position/like等sanitizer 构建更明显低~中UB 类CPU lease 调度器 use-after-free高并发、工作线程频繁退出的调度场景高进程崩溃如果你的集群启用了工作负载资源管理workload_path相关配置且并发压力大第三项值得优先关注如果业务大量使用EXCEPT/COLUMNS列变换器组合查询第一项会直接影响线上可用性。5.2 升级路径从 v26.2.14.5-stable 升级到 v26.2.15.4-stable 为同一 minor 版本的补丁升级属于常规 stable 分支升级配置兼容性风险低升级前建议先在一台节点上执行冒烟验证跑一遍 01470_columns_transformers2.sql 中的列变换器用例并对核心查询集做一次回归若使用 sanitizer 构建MSan/ASan可重点跑字符串检索与调度器相关测试如gtest_workload_resource_manager验证告警清零。5.3 关键代码路径速查列变换器执行逻辑src/Interpreters/applyColumnsTransformer.cpp列变换器语法定义src/Parsers/ASTColumnsTransformers.h字符串检索器src/Common/StringSearcher.hCPU lease 分配器src/Common/Scheduler/CPULeaseAllocation.cpp、src/Common/Scheduler/CPULeaseAllocation.h工作负载资源管理器src/Common/Scheduler/WorkloadResourceManager.cpp调度器回归测试src/Common/Scheduler/Nodes/tests/gtest_workload_resource_manager.cpp官方变更记录原文docs/changelogs/v26.2.15.4-stable.md六、小结v26.2.15.4-stable 是 ClickHouse 26.2 稳定分支上一个聚焦正确性与稳定性的补丁版本。三个修复分别触及查询改写、字符串检索与 CPU 资源调度三条核心路径其中 CPU lease 调度器的 use-after-free 修复以ThreadGroupPtr持有计数器所有权 成员声明顺序保证是典型的生命周期管理教科书案例值得资源调度类系统开发者借鉴。对于生产环境使用者建议结合本文的触发场景与验证清单评估并规划升级窗口。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价