
深度解读 ClickHouse v22.7.4.16-stable 变更日志哈希计算、ALTER 重算索引、DNS 解析等 5 个关键缺陷修复【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse本文以 ClickHouse 官方变更日志 v22.7.4.16-stable 为主体逐一拆解该稳定版相对 v22.7.3.5-stable 修复的 5 个用户可见缺陷并结合当前仓库源码如 HashMethod.h、MutateTask.cpp、CaresPTRResolver.cpp说明每个问题涉及的底层机制帮助读者理解每个修复背后的技术背景、影响范围以及在生产环境排查同类问题的思路。版本定位v22.7.4.16-stable 是一次缺陷修复发布该变更日志的基线信息为ClickHouse release v22.7.4.16-stable (0b9272f8fdc) 相对于 v22.7.3.5-stable (e140b8b5f3a) 的修复这意味着 v22.7.4.16-stable 是 v22.7 分支上的一个稳定补丁版本不包含新功能只包含 Bug Fix官方稳定版中用户可见的误行为修复以及若干标注为 NOT FOR CHANGELOG / INSIGNIFICANT不面向变更日志/影响面很小的内部修复。此类发布通常对应线上问题错误结果、崩溃、安全问题的回合backport修复对于停留在 22.7 LTS 线上运行的集群具有直接的升级参考价值。修复一HashMethodOneNumber 在常数列上取到错误的键值问题描述变更日志原文Backported in #40163: fix HashMethodOneNumber get wrong key value when column is const. #40020 (Duc Canh Le).这是一个返回错误结果级别的缺陷当聚合、JOIN 或去重使用的键列被优化为常量列const column时HashMethodOneNumber可能读取到错误的键值进而导致分组、关联结果出错。这类静默错误结果的缺陷是所有缺陷中危害最大的一类。源码机制佐证在当前仓库中HashMethodOneNumber定义于 HashMethod.h。其注释明确写道 For the case when there is one numeric key. UInt8/16/32/64 for any type with corresponding bit width即它是单数值键场景下最快的哈希方法——直接从列的原始数据内存中非对齐加载键值/// Is used for default implementation in HashMethodBase. FieldType getKeyHolder(size_t row, Arena ) const { return unalignedLoadFieldType(vec row * sizeof(FieldType)); }可以看到取键公式为vec row * sizeof(FieldType)即假设列数据是按行连续存放且每行一个字段。而常量列的原始数据中通常只存放一行一行数据被复用表示所有行。因此当row 0时vec row * sizeof(FieldType)会越过常量列实际存储的单行数据边界读到相邻内存中的其他值——这正是该缺陷get wrong key value when column is const的成因路径。从源码结构看vec的初始化逻辑区分ColumnNullable时取嵌套列数据说明该方法直接信任getRawData().data()指向的内存布局修复方向即让其在遇到常量列时正确地始终读取第一行的值而不是按行号偏移。影响面HashMethodOneNumber被广泛用于聚合AggregationMethod.h、哈希 JOINConcurrentHashJoin.cpp、SetVariants.h以及部分数组函数如 arrayUniq.cpp。触发条件典型场景是查询计划将某个键表达式判定为常量例如对SELECT 1 AS k做 GROUP BY或对某列做GROUP BY时该列在部分块中只有唯一值且被列优化替换为常量列。升级到 v22.7.4.16-stable 及之后版本即可消除该风险。修复二collectFilesToSkip 未正确识别待重算索引的扩展名.idx / idx2导致硬链接错误问题描述变更日志原文Backported in #40125: Fix bug in collectFilesToSkip() by adding correct file extension(.idx or idx2) for indexes to be recalculated, avoid wrong hard links. Fixed #39896. #40095 (Jianmei Zhang).源码机制佐证collectFilesToSkip是 MergeTree 表执行 ALTERmutation时的核心内部函数定义于 MutateTask.cpp。其作用是计算新 part 中哪些源 part 的文件可以跳过重写、直接以硬链接方式复用static NameSet collectFilesToSkip( const MergeTreeDataPartPtr source_part, const MergeTreeDataPartPtr new_part, const Block updated_header, const std::setMergeTreeIndexPtr indices_to_recalc, const std::setMergeTreeIndexPtr indices_to_drop, ...) { NameSet files_to_skip source_part-getFileNamesWithoutChecksums(); /// Do not hardlink this file because its always rewritten at the end of mutation. files_to_skip.insert(IMergeTreeDataPart::SERIALIZATION_FILE_NAME); ... }其逻辑是默认所有源 part 文件都进入files_to_skip硬链接复用然后针对需要重算的索引indices_to_recalc、需要删除的索引indices_to_drop以及 skip index 的各类子流substream逐一从集合中剔除使其在新 part 中被重新生成。缺陷点在于跳过索引skip index文件在 MergeTree part 中的实际落盘扩展名为.idx或idx2等索引类型不同文件后缀不同而原实现在剔除待重算索引的文件时没有覆盖正确的扩展名模式。后果是这些本应重算的索引文件反而被错误地硬链接到了新 part 中——新 part 里携带了旧索引数据索引内容与数据块不一致可能引发查询时索引过滤错误甚至CHECK TABLE校验失败。从 MutateTask.cpp 中该函数对getAllSubstreamsInPart与getStreamNameOrHash的使用注释Missing one leaks it into the new part with no checksum entry andCHECK TABLEfails可以印证漏剔除一个子流文件就会让它泄漏进新 part 而没有对应的校验和条目直接破坏 part 完整性。该修复正是补齐.idx/idx2扩展名的匹配保证重算索引被完整剔除、重新构建。影响面该缺陷影响的是带跳过索引INDEX ... TYPE minmax/bloom_filter/set/ngrambf_v1/tokenbf_v1等且执行过相关 ALTER增删列、重算索引等 mutation的 MergeTree 表。修复前如果发生错误的硬链接建议执行CHECK TABLE验证 part 完整性并对受影响 part 触发MUTATE ... CLEAN/重建索引或重建表以恢复一致性。修复三CaresPTRResolver 引发的段错误问题描述变更日志原文Backported in #40291: A segmentation fault that has CaresPTRResolver::resolve in the stack trace has been reported. #40134 (Arthur Passos).源码机制佐证在当前仓库中CaresPTRResolver是 ClickHouse 用 c-ares 实现的 DNS PTR 解析器定义于 CaresPTRResolver.h 与 CaresPTRResolver.cpp由 DNSPTRResolverProvider.cpp 在创建时以静态单例方式实例化Library initialization is currently done only once in the constructor。PTR 解析用于 ClickHouse 集群中通过反向 DNS 解析节点身份host_name/display_name配置。段错误出现在resolve调用栈中结合 c-ares 的回调模型可以推断崩溃与异步解析结果的回调/内存生命周期处理相关——典型风险点是 c-ares 的查询上下文在回调触发前被销毁或共享库初始化状态未就绪时仍进入解析路径。修复PR #40134由 Arthur Passos 提交针对resolve路径的稳定性做了加固。对于线上遇到Segmentation fault ... CaresPTRResolver::resolve崩溃的 22.7 集群升级到本版本是最直接的解决方式短期规避手段是避免依赖 PTR 解析的集群主机名配置方式。修复四加密函数参数校验不足问题描述变更日志原文Backported in #40210: Fix insufficient argument check for encryption functions (found by query fuzzer). This closes #39987. #40194 (Alexey Milovidov).技术背景该缺陷由官方 query fuzzer随机查询生成器发现。加密函数如encrypt/decrypt系列其实现位于 src/Functions 下此前对传入参数密钥长度、算法参数个数等的校验不够充分传入非法参数时可能触发未定义行为。修复补齐了参数合法性检查使非法调用以明确的查询错误而非崩溃/异常形式返回。从工程角度看这类参数校验不足 模糊测试发现的组合在 ClickHouse 安全加固中很常见fuzzer 持续生成畸形 SQL倒逼函数实现收紧前置检查。使用加密函数处理敏感数据时建议同时关注密钥管理最佳实践并升级到含该修复的版本。修复五CapnProto 输入格式的潜在段错误问题描述变更日志原文Backported in #40284: Fix possible segfault in CapnProto input format. This bug was found and send through ClickHouse bug-bounty program bykiojj. #40241 (Kruglov Pavel).技术背景这是本版本中一个有外部安全研究背景的修复报告者kiojj通过 ClickHouse 官方 Bug Bounty 计划提交了该漏洞对应 issue #38986由 Kruglov Pavel 通过 PR #40241 修复。CapnProto 是一种二进制序列化格式ClickHouse 在 src/Formats 中实现了其输入解析格式。二进制反序列化类缺陷的典型成因是输入数据声明的长度/嵌套深度与实际缓冲区不一致时解析器越界读取。修复后构造恶意的 CapnProto 数据不再可能触发段错误。对于以FORMAT CapnProto或File(..., CapnProto)读取外部不可信数据的场景本修复消除了一个潜在的 DoS 攻击面。三个不写入变更日志的附带修复变更日志后半部分标注为NOT FOR CHANGELOG / INSIGNIFICANT表示这些修复影响面小、不面向用户文档化但完整继承如下以便审计修复内容PR贡献者修复符号链接symlink检测的 bug#40232Alexander Tokmakov通过限制 HTTP chunk 大小修复堆缓冲区溢出heap buffer overflow#40292Sema Checherinda降低 CI 中 changelog 输出的冗长度#40360Mikhail f. Shiryaev其中值得留意的是限制 HTTP chunk 大小以修复堆缓冲区溢出这一条虽然被归类为 insignificant但它属于内存安全修复与 HTTP 传输层解析 chunked 编码时的边界处理有关。对安全基线敏感的读者在版本选型时应把这类内部修复也纳入考量。小结如何把这份变更日志用于生产决策错误结果类修复修复一与part 完整性类修复修复二是最需要关注的一类它们不报错但会产生错误数据或损坏索引静默危害大于崩溃类缺陷。若 22.7 集群执行过带常量键的聚合/JOIN 或带跳过索引的 ALTER建议升级并对关键表执行CHECK TABLE复核。崩溃类修复修复三、五对应明确的 stack traceCaresPTRResolver::resolve、CapnProto 解析路径线上遇到对应崩溃可直接对号入座升级。安全类修复修复四、内部修复二表明该补丁版本包含防御纵深加固适合作为 22.7 分支上的安全基线版本。完整的 22.7 系列其他补丁版本变更日志可在 docs/changelogs/archive/ 目录中按版本号继续查阅配合本目录下的各版本文件可还原 22.7 分支的完整修复轨迹。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考