ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ClickHouse v25.4.12.9-stable 变更深度解析:Variant 崩溃修复、Iceberg 文件裁剪收敛与 Keeper 监视计数校正

ClickHouse v25.4.12.9-stable 变更深度解析:Variant 崩溃修复、Iceberg 文件裁剪收敛与 Keeper 监视计数校正 ClickHouse v25.4.12.9-stable 变更深度解析Variant 崩溃修复、Iceberg 文件裁剪收敛与 Keeper 监视计数校正【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse本文以 ClickHouse 官方变更日志 v25.4.12.9-stable 为主线逐一拆解该稳定版本中合入的 3 个用户可见缺陷修复与 1 个内部健壮性补丁并结合src/下相关源码说明每个修复背后的根因、实现位置与验证手段。读者将能理解 Variant 类型在 UNION 查询中崩溃的修复原理、Iceberg 表 bounds 元数据裁剪被收紧的原因以及 ClickHouse Keeper 中监视watch计数在临时节点清理时如何保持一致并据此评估自己集群是否需要升级。版本背景v25.4 系列的一条补丁分支该条目属于 ClickHouse 2025 年度变更日志docs/changelogs对比基线为 v25.4.11.15-stablecommitd384a0dd98b本次发布为v25.4.12.9-stablecommit65820a0cf71。从变更分类看本次发布以稳定性为目标包含 3 条Bug Fix用户可见的官方稳定版异常行为和 1 条NOT FOR CHANGELOG / INSIGNIFICANT不对外声明、仅内部健壮性的补丁不包含任何新功能属于典型的补丁分支patch branch迭代。这类发布面向生产环境中已运行 v25.4 系列的集群它不改变 SQL 语义只修复已确认的回归或边界缺陷因此升级风险低、收益明确。下文按变更日志顺序展开。一、修复 Variant 类型在 UNION 中的潜在崩溃#83295现象与修复内容变更日志原文指出修复 Variant 类型在 UNION 中可能崩溃的问题Backported in #83471。该修复由 Pavel KruglovAvogar提交属于合并到 v25.4 稳定分支的补丁。Variant 是 ClickHouse 中的多态列类型允许一个列在内部按需容纳多种备选类型。从 DataTypeVariant.cpp 的构造函数校验逻辑可以看到该类型的严格约束Nullable(...)、LowCardinality(Nullable(...))不允许出现在 Variant 内部嵌套 Variant 不允许Nested Variant types are not allowedDynamic 类型不允许出现在 Variant 内部至少需要包含一个嵌套类型且嵌套类型数量不能超过ColumnVariant::MAX_NESTED_COLUMNS。崩溃根因分析结合源码推断从源码结构看Variant 的底层存储是 ColumnVariant.h 与SerializationVariantSerializationVariant.h列内部维护各备选子列的“判别子discriminator”映射。当 UNION 两侧的 Variant 类型在编译期被推断合并、或在序列化/反序列化路径中遇到未对齐的备选类型列表时就可能在取子列、展开局部列时触发越界或空指针访问从而表现为服务端崩溃而非查询报错这正是它被列为“用户可见的官方稳定版异常行为”的原因。需要强调该条目在变更日志中未给出具体触发 SQL我们不应编造复现语句。合理的处理方式是若线上存在大量使用 Variant 列参与 UNION/UNION ALL 的查询升级前可重点回归这类场景。修复验证方向从代码约束可以推断修复后的行为应在以下方面得到保证UNION 结果类型推断为 Variant 时不再发生空指针/越界访问嵌套类型数量超限、Nullable 包裹等非法组合仍按BAD_ARGUMENTS报错而非崩溃。相关合法性校验集中在 DataTypeVariant.cpp可作为阅读入口。二、为 Iceberg 数组元素与 Map 值禁用基于 bounds 的文件裁剪#83520修复内容变更日志原文指出对 iceberg array element 与 iceberg map values包括其所有嵌套子字段禁用基于 bounds 的文件剪枝Disable bounds-based file pruning。为什么需要收紧裁剪bounds 语义的复杂性Iceberg 表的每个数据文件data file在 manifest 清单中携带统计元数据lower_bounds/upper_bounds用于查询引擎在读取时跳过明显不满足过滤条件的文件。这一点可以从 Iceberg 读取层的元数据定义得到确认Constant.h 中定义了lower_bounds、upper_bounds两个字段AvroSchema.h 的 manifest 条目标识中同样携带这两个字段IcebergFieldParseHelpers.h 明确指出Iceberg 的 lower_bounds/upper_bounds 是“以自定义反序列化方式序列化”的字节数组并不能直接当作普通标量参与比较。正是这种“自定义字节序列化”导致了问题对于list数组元素、map 的 value这类复合/嵌套子字段其 bounds 的序列化格式与标量主列不一致直接套用标量裁剪逻辑会对嵌套子字段产生错误的裁剪结论——即可能把本应命中的文件当作“范围外”而跳过造成数据丢失式的漏读。因此本次修复选择对数组元素与 Map 值含其全部嵌套子字段整体关闭 bounds 文件裁剪以正确性换取这部分剪枝收益。从实现布局看Iceberg 相关裁剪逻辑位于 src/Storages/ObjectStorage/DataLakes/Iceberg其中 ChunkPartitioner.cpp、IcebergFieldParseHelpers.cpp 分别负责分块切分与字段级统计解析是阅读 bounds 解析与裁剪判定的核心文件。升级影响评估该修复是保守化修改对包含 Iceberg 嵌套集合列数组/Map的过滤查询可能少做一层文件级裁剪、扫描略增但换来查询结果的正确性保证。对纯标量列的 Iceberg 查询bounds 裁剪不受影响。生产环境若使用 Iceberg 表引擎且查询涉及arrayElement(...)、map[...]等嵌套访问过滤升级后可留意相关查询的 profile 事件与扫描字节数变化。三、Keeper会话关闭删除临时节点时正确更新总监视计数#83583修复内容变更日志原文指出Keeper 修复——在会话关闭导致临时ephemeral节点被删除时正确更新总监视计数update total watch count correctly when ephemeral nodes are deleted on session close。修复者为 Antonio Andelicantonio2368。底层数据结构监视计数如何维护ClickHouse Keeper 的存储实现位于 src/Coordination/KeeperStorage.cpp 与 src/Coordination/KeeperStorage.h其中Watches watches、list_watches、persistent_watches、persistent_list_watches、persistent_recursive_watches五张映射表分别保存节点路径到订阅会话的映射见 KeeperStorage.h反向映射sessions_and_watcherssession_id - 被监视路径集合用于会话维度回收全局计数器size_t total_watches_countKeeperStorage.h对外报告监视总数。当会话正常关闭时清理路径是 KeeperStorage::clearDeadWatches遍历sessions_and_watchers中该会话的所有 (path, watch_type)逐类从五张 watch 映射中摘除会话并累加erased_watches最后统一执行total_watches_count - erased_watches。缺陷根因结合源码推断临时节点的删除发生在会话关闭流程中。在 KeeperStorageImpl.cpp 的Close请求处理分支中流程为遍历该会话的未提交 deltas对每个删除节点增量调用processWatchesImpl(delta.path, Event::DELETED)将返回值中的cnt_removed_watches累减到total_watches_count执行commit(deltas_range)提交调用clearDeadWatches(session_id)清理该会话剩余监视。可以推断缺陷在于临时节点删除产生的监视触发与计数回收与clearDeadWatches的计数回收之间存在重叠或遗漏路径如果某个 watch 已被 delta 删除流程计数回收、又被clearDeadWatches再次统计就会出现双重扣减反之若存在未被覆盖的监视类型如持久化 watch 与临时节点删除的组合则会出现计数残留。无论哪种方向最终都表现为total_watches_count与实际监视数不一致进而污染监控指标。该计数如何被观测运维视角total_watches_count会暴露到两个可观测渠道系统指标KeeperWatchCount见 KeeperAsynchronousMetrics.cpp其说明为“ClickHouse Keeper 中的监视数量”会随system.asynchronous_metrics周期性采集四字命令输出见 FourLetterCommand.cpp 与 FourLetterCommand.cppstatwatch_count字段等四字命令会直接打印监视总数。此外源码在 KeeperStorage.cpp 中存在一致性断言chassert(actual_watches_count total_watches_count)即内部会定期重算实际监视数与维护计数比对。升级后可重点观察KeeperWatchCount在长时间运行、会话频繁开关尤其涉及临时节点后是否出现异常跳变或负值这是验证本修复是否生效的直观手段。四、NOT FOR CHANGELOG为 executeReplaceRange 持有临时分区锁#83095修复内容该条目被标记为NOT FOR CHANGELOG / INSIGNIFICANT即不写入对外发布说明但仍在本次发布中合入。原文为在 executeReplaceRange 执行时持有临时分区锁hold the temporary part lock when executeReplaceRange修复者 Sema ChecherindaCheSema。REPLACE_RANGE 在复制表中的角色executeReplaceRange是 ReplicatedMergeTree 复制队列中处理REPLACE_RANGE日志条目的执行函数位于 StorageReplicatedMergeTree.cpp其调用点在日志条目分发处StorageReplicatedMergeTree.cpp当entry.type LogEntry::REPLACE_RANGE时调用executeReplaceRange(entry)。该操作常用于REPLACE PARTITION/ATTACH PARTITION等场景用一个数据源的分区数据替换本地分区内的部分区间。函数内部StorageReplicatedMergeTree.cpp的核心步骤包括从分区名解析MergeTreePartInfo drop_rangefromPartName等待过期分区加载完成waitForOutdatedPartsToBeLoaded确保替换命令作用于磁盘上全部分区若为真正的替换非 ATTACH/MOVE则取消该分区内的合并cancelInPartition临时暂停 part 检查线程part_check_thread.temporaryPause()从复制队列中移除该区间内正在产 part 的条目queue.removePartProducingOpsInRange取消对该区间的过期分区检查cancelRemovedPartsCheck。锁的作用结合代码结构推断在REPLACE_RANGE执行期间被替换区间的分区会经历“标记过期 → 删除”的短暂窗口。若此时 part 检查线程或其他并发路径正在操作同一批分区如把某个临时分区推进为 Active、或对过期分区做清理检查就可能在替换尚未完成时对分区做不完整的状态变更。本次补丁在executeReplaceRange期间持有临时分区锁temporary part lock串行化替换过程与临时分区生命周期管理避免出现并发窗口下的竞态。该修改被标记为“insignificant”说明它属于并发健壮性加固正常路径下用户无感知。升级与验证建议升级目标运行 v25.4 系列的集群可考虑升级到 v25.4.12.9-stable该版本不含新特性聚焦于稳定分支缺陷修复升级回滚面小升级前仍建议按常规流程先在测试环境回归。重点回归场景使用Variant列参与 UNION / UNION ALL 的查询验证修复一对 Iceberg 表按数组元素 / Map 值做过滤的查询核对结果集与扫描量验证修复二长时间运行 ClickHouse Keeper制造会话开关与临时节点创建/删除负载观察system.asynchronous_metrics中的KeeperWatchCount与四字命令stat输出的watch_count是否保持稳定一致验证修复三。进一步阅读Variant 类型定义与校验DataTypeVariant.cppIceberg bounds 字段与解析说明Constant.h、IcebergFieldParseHelpers.hKeeper 监视清理与计数KeeperStorage.cpp、KeeperStorageImpl.cppREPLACE_RANGE 执行逻辑StorageReplicatedMergeTree.cpp完整变更日志v25.4.12.9-stable.md【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表