ARTICLE DETAIL

资讯详情

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

ClickHouse v23.3.12.11-lts 补丁版本深度解析:异步插入去重、目录关停死锁与稀疏列等四项关键修复

ClickHouse v23.3.12.11-lts 补丁版本深度解析:异步插入去重、目录关停死锁与稀疏列等四项关键修复 ClickHouse v23.3.12.11-lts 补丁版本深度解析异步插入去重、目录关停死锁与稀疏列等四项关键修复【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHousev23.3 是 ClickHouse 的 LTS长期支持分支v23.3.12.11-lts是该系列的第 12 个补丁版本面向线上稳定运行场景提供向后兼容的关键修复。本文以该版本的官方变更日志docs/changelogs/archive/v23.3.12.11-lts.md为主体逐一拆解其中 4 项用户可见的 Bug Fix 与 1 项内部修复并结合当前仓库源码还原其底层机制。读完本文你将理解异步插入在复制表上的去重语义、服务器关停阶段的锁序问题、稀疏列在 JOIN 中的行为差异以及rows_before_limit_at_least在延迟源DelayedSource场景下的计数规则从而更准确地评估本次升级的收益与风险。版本背景LTS 分支中的补丁发布节奏在 ClickHouse 的版本体系中LTS 分支如 v23.3与创新分支如 v23.4 的常规发布并行演进。LTS 分支长期接收小步幅的补丁修复每个补丁版本通常只包含少量高价值的稳定性修复不会引入新功能。v23.3.12.11-lts相对上一个补丁版本v23.3.11.5-lts变更日志见 docs/changelogs/archive/v23.3.11.5-lts.md而言新增了 4 项被标记为 Bug Fix (user-visible misbehavior in an official stable release) 的修复——即官方稳定版中用户可见的异常行为以及 1 项 NOT FOR CHANGELOG / INSIGNIFICANT不进对外变更日志、仅内部用途的修复。这类补丁版本适合通过常规升级通道滚动部署但部署前建议逐条核对修复点是否命中自身的线上场景并利用 tests/queries 中的回归用例做验证。修复一ReplicatedMergeTree 上异步插入与去重算法的兼容问题#51676变更日志条目Fix async insert with deduplication for ReplicatedMergeTree using merging algorithms修复使用合并算法的 ReplicatedMergeTree 的异步插入去重。问题场景异步插入async_insert 1是 ClickHouse 为降低高频小批量写入压力而提供的缓冲机制客户端将多条小 INSERT 合并为更大的块后真正落盘。去重deduplication则保证同一数据块在重试、网络抖动等场景下不会被重复写入。当二者叠加在ReplicatedMergeTree系列引擎上并通过合并算法路径异步缓冲块被合并后参与复制日志提交时旧逻辑可能出现去重失效或误判进而产生重复数据。底层机制同步与异步插入共享同一去重目录从当前仓库源码看复制表插入的去重逻辑集中在 ReplicatedMergeTreeSink.cpp, deduplicate( [] { /// Sync and async inserts share the unified deduplication_hashes directory; /// replicated_deduplication_window governs both enabling and retention. return mt_settings[MergeTreeSetting::replicated_deduplication_window] ! 0; }) , is_async_insert(async_insert_)即同步插入与异步插入最终都向统一的deduplication_hashes目录存放在 ClickHouse Keeper 中写入去重哈希由replicated_deduplication_window统一控制开关与保留窗口。该窗口的语义在 MergeTreeSettings.cpp 中有明确说明哈希覆盖整个插入块因此只有整块数据与历史块完全一致时才判定为重复适用于重试场景而非逐行比对窗口过大时插入会比较慢因为需要比对更多条目。与异步插入相关的两个旧设置replicated_deduplication_window_for_async_inserts与replicated_deduplication_window_seconds_for_async_inserts在最新源码中已被标记为 Legacy setting retained for mixed-version rolling upgradesMergeTreeSettings.cpp新写入统一使用replicated_deduplication_window与replicated_deduplication_window_seconds管理旧设置只约束滚动升级期间由旧副本写入async_blocks目录的旧式异步哈希的保留数量与时长并由当前 leader 负责清理。工程验证仓库为此保留了专门的回归测试 gtest_async_inserts.cpp覆盖异步插入场景下的去重行为异步块 ID 的内存缓存机制实现在 AsyncBlockIDsCache.cpp通过detectConflicts在写入前检测与历史块的冲突避免 Keeper 往返。修复二DatabaseCatalog 关停阶段的死锁#51908变更日志条目Fix deadlock on DatabaseCatalog shutdown修复 DatabaseCatalog 关停时的死锁。问题场景DatabaseCatalog是 ClickHouse 服务器中维护全部数据库、表、字典等对象注册信息的核心单例几乎所有路径查询、后台任务、DDL都会访问它。服务器优雅关停shutdown时需要按特定顺序释放各子系统持有的锁与资源若此时某个后台线程恰好持有DatabaseCatalog内部锁并等待另一个已被关停的子系统就会形成锁序反转导致的死锁使进程无法按时退出影响容器编排下的滚动发布如 Kubernetes 优雅终止超时后被强制 kill。源码佐证DatabaseCatalog定义于 src/Interpreters/DatabaseCatalog.h对外提供静态关停入口static void shutdown(std::functionvoid() shutdown_system_logs)L125内部实现为void shutdownImpl(std::functionvoid() shutdown_system_logs)L297。关停逻辑需要与system.*_log等系统日志表的写路径协调这也是shutdown接收shutdown_system_logs回调的原因。本次修复即针对该过程中可能出现的死锁路径进行了调整确保各类后台线程复制任务、异步插入缓冲、日志刷新等在目录关停期间的锁获取顺序一致。修复三稀疏列上的 JOIN 崩溃#53548变更日志条目Fix crash in join on sparse column修复在稀疏列上执行 JOIN 时的崩溃。问题场景与稀疏列背景稀疏列sparse column是 ClickHouse 针对大量默认值如0、空串场景的存储优化以值数组 偏移/默认值的方式存储显著压缩了默认值占比高的列。但由于其物理表示与稠密列不同任何未显式处理稀疏布局的算子都可能触发崩溃或错误结果。JOIN 引擎涉及多路数据流的拼接与行号对齐是稀疏列的高风险路径之一。本版本修复了 JOIN 在稀疏列上可能触发的崩溃。从当前仓库代码看稀疏列的表示与转换集中维护在 src/Core/Block.cpp相关嵌套结构测试见 gtest_block_nested_sparse_structure.cpp而多个数据变换算子如 FilterTransform.cpp、DistinctTransform.cpp都需要显式考虑列的稀疏属性可以推断 JOIN 路径同样需要保证稀疏列在拼接、物化过程中的正确性。值得关注的是紧邻的前一个补丁版本v23.3.11.5-lts刚修复了稀疏列上的sorted distinct问题Fix: sorted distinct with sparse columnsdocs/changelogs/archive/v23.3.11.5-lts.md。两个连续补丁均落在稀疏列处理上说明该阶段 ClickHouse 正在系统性地收敛稀疏列特性在各算子上的行为差异使用sparse_columns特性的用户应尤其关注这两个补丁版本。修复四DelayedSource 的 rows_before_limit_at_least 计数#54122变更日志条目Fix rows_before_limit_at_least for DelayedSource修复 DelayedSource 场景下rows_before_limit_at_least的取值。何为 rows_before_limit_at_leastrows_before_limit_at_least是 ClickHouse 查询结果中的一个元信息字段它表示在应用LIMIT之前、实际读取并处理过的行数可能大于等于最终返回行数。客户端与监控脚本常借助它判断是否因 LIMIT 截断了数据。该值由查询管线中的Limit相关处理器如 LimitTransform.cpp、OffsetTransform.cpp在流水线上游逐级累加并通过RowsBeforeStepCounterRowsBeforeStepCounter.h在各处理器之间传递。问题与修复DelayedSourceDelayedSource.h是一种延迟管线计算直到开始执行的处理器首次需要数据时才会调用回调展开子管线并接入输入端口如果主输出端口从未被消费回调甚至不会执行。这种惰性机制用于避免无谓构建代价昂贵的子管线典型场景是分布式查询中远程分片的读取。问题在于在DelayedSource之前已经消费掉一部分行的场景下例如远程读路径中先处理了部分数据才到达DelayedSource旧实现没有把这段在到达 DelayedSource 之前就已被消费的行数计入rows_before_limit_at_least导致该值偏小、无法反映真实扫描行数。当前源码中 ReadFromRemote.cpp 的注释明确写道这些行在到达DelayedSource之前就已被消费但rows_before_limit_at_least必须包含它们。本次修复正是补齐了这段计数的传递保证分布式/延迟读取场景下该元信息的准确性。内部修复sorted distinct 稀疏回归测试NOT FOR CHANGELOG变更日志末尾还有一条标记为 NOT FOR CHANGELOG / INSIGNIFICANT 的修复Fix broken02862_sorted_distinct_sparse_fix修复损坏的02862_sorted_distinct_sparse_fix测试。它对应 ClickHouse 内部测试编号02862测试脚本位于 tests/queries 目录按编号组织修复的是上一个版本新增的排序去重 稀疏列回归测试本身无法正确运行的问题。这类条目不进入面向用户的对外变更说明但对保证 CI 中稀疏列相关回归覆盖的完整性有意义也再次印证稀疏列修复是本阶段补丁的主线之一。升级建议与验证路径按命中场景决定优先级如果你的线上环境启用了异步插入且表为ReplicatedMergeTree系列或依赖 JOIN 处理高默认值占比的稀疏列或使用分布式查询并依赖rows_before_limit_at_least做数据完整性判断本次补丁属于高优先级升级项。关注混合版本滚动升级若集群存在新旧副本混跑异步插入去重相关旧设置replicated_deduplication_window_for_async_inserts等仍会在过渡期生效升级期间应保留其默认值交由新 leader 逐步清理旧式哈希。升级后回归验证可通过 tests/queries 中的相关用例如异步插入、JOIN、LIMIT 计数相关查询验证行为一致性对于rows_before_limit_at_least可执行带LIMIT的查询并在结果集中检查该元字段是否覆盖实际扫描行数。查阅完整演进本版本的变更日志位于 docs/changelogs/archive/v23.3.12.11-lts.md其余 LTS 补丁的变更可参考 docs/changelogs 目录下的归档文件。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表