ARTICLE DETAIL

资讯详情

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

ClickHouse v25.8.20.4-lts 补丁版本解析:递归 CTE 崩溃、Patch Parts 列序与 O_DIRECT 读缓冲 seek 三大修复

ClickHouse v25.8.20.4-lts 补丁版本解析:递归 CTE 崩溃、Patch Parts 列序与 O_DIRECT 读缓冲 seek 三大修复 ClickHouse v25.8.20.4-lts 补丁版本解析递归 CTE 崩溃、Patch Parts 列序与 O_DIRECT 读缓冲 seek 三大修复【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse本篇技术指南聚焦 ClickHouse 官方 LTS 分支的最新补丁版本v25.8.20.4-lts提交2e1cd6354ae逐条拆解该版本相对 v25.8.19.20-lts 引入的三项 Bug Fix递归 CTE 搭配remote()与view()时的段错误segfault、MergeTree 增量 Patch Parts 列顺序不一致导致的LOGICAL_ERROR以及O_DIRECT模式下异步文件读缓冲的错误 seek 定位。读完本文你将理解每个缺陷的触发场景、根因所在以及仓库中对应的底层实现与修复落点从而能够在生产升级时准确评估影响面。本文内容以仓库中的官方发布记录 docs/changelogs/v25.8.20.4-lts.md 为主体骨架并结合src/下相关模块源码进行原理层面的印证与扩展。版本背景与升级建议v25.8.20.4-lts 属于 ClickHouse 25.8 系列的 LTS长期支持维护分支。从发布记录的版本对比行可以看出它是 v25.8.19.20-lts 的直接后继版本全部变更均为Bug Fix用户可见的官方稳定版行为异常修复未引入新特性或破坏性变更。因此对于运行 25.8 LTS 系列的集群这是一个低风险、应尽快合入的补丁升级修复涉及的三个模块分别为编号修复内容涉及模块上游跟踪1递归 CTE remote()view()组合查询段错误Analyzer / 查询执行#99081随 #99441 回溯2Patch Parts 列顺序不匹配导致的LOGICAL_ERRORMergeTree 变更转换#99164随 #99989 回溯3O_DIRECT下异步读缓冲 seek 定位错误IO 异步读#99678随 #99950 回溯关闭 #99358说明以上编号取自仓库 changelog 中的 PR/Issue 编号便于在社区中交叉检索本文不附外部链接具体上下文请以仓库源码为准。修复一递归 CTE 与remote()、view()组合时的段错误触发场景在 ClickHouse 中递归 CTERecursive Common Table Expression通过WITH RECURSIVE定义其执行依赖一个内部临时表来承载迭代过程的中间结果。当递归查询的初始化非递归子查询中同时出现remote()表函数与view()表函数时v25.8.20.4-lts 之前的版本可能触发段错误segfault导致服务进程崩溃属于用户可见的严重稳定性缺陷。底层实现印证递归 CTE 的解析与分析阶段实现在 src/Analyzer/RecursiveCTE.cppRecursiveCTETable包装了一个由TemporaryTableHolderPtr持有的临时表存储与列定义供递归子查询在迭代中反复读写。而实际数据读取由查询计划层完成src/Processors/QueryPlan/ReadFromRecursiveCTEStep.cpp 通过pipeline.init(...)将RecursiveCTESource挂入执行管道数据源实现在 src/Processors/Sources/RecursiveCTESource.cpp其中会校验递归子查询的投影列与recursive_cte_table-columns是否同构columns.size() ! recursive_query_projection_columns.size()时抛出异常。当递归 CTE 与非递归的remote()/view()子查询组合时涉及远程表的列类型/名称解析与本地临时表列定义之间的对齐。从源码结构可以推断段错误的根因在于这类组合路径下列描述ColumnsDescription或存储句柄的初始化存在未覆盖分支导致空指针解引用。修复通过补全该组合下的初始化与校验逻辑确保列投影在任何组合下都先校验、后访问从而消除崩溃。实操验证建议升级后可用如下形态的查询做回归验证注意remote()参数需替换为你实际的集群地址与表WITH RECURSIVE r AS ( SELECT number AS n FROM remote(127.0.0.1:9000, system, numbers) LIMIT 1 UNION ALL SELECT n 1 FROM r WHERE n 5 ) SELECT * FROM r;以及在view()包装场景下重复执行确认不再出现段错误且结果正确。相关查询计划与递归数据源的实现可继续阅读 src/Analyzer/UnionNode.cpp、src/Analyzer/RecursiveCTE.h 与 src/Processors/Sources/RecursiveCTESource.h。修复二Patch Parts 列顺序不匹配导致的 LOGICAL_ERROR触发场景Patch Parts 是 MergeTree 引擎为实现轻量级增量修改而引入的数据部件类型对已存在 part 的少量列进行修改时系统以“补丁部件”形式记录增量读取时在内存中将其与原始 part 合并。当某个 part 上同时存在多个待应用的 patch part且这些 patch part 与常规 part 的列顺序不一致时旧版本会抛出LOGICAL_ERROR“It is a bug”级别异常导致读取失败。底层实现印证列序合并与校验逻辑集中在 src/Storages/MergeTree/AlterConversions.cpp 与 src/Storages/MergeTree/AlterConversions.hAlterConversions构造时同时接收MutationCommands与PatchPartsForReader并通过addPatchPart(patch)将每个 patch 追加进patch_partshasPatches()/getAllPatches()暴露 patch 集合状态构造器会对“超过一个 on-fly ALTER MODIFY”的组合抛出不支持异常见AlterConversions.cpp中number_of_alter_mutations 1的检查分支说明该模块对多变更叠加的一致性极其敏感。修复前patch part 合并时直接以 patch 自身列顺序为准进行拼接未与常规 part 的列顺序对齐修复后PR #99164在读路径中统一按目标 part 的列顺序对 patch 部件做重排/对齐从根上消除了LOGICAL_ERROR。相关合并谓词对 patch 版本跨越的约束可进一步参考 src/Storages/MergeTree/Compaction/MergePredicates/MergeTreeMergePredicate.cpp 中“合并不得跨越既有 part 数据版本”的检查逻辑。影响面与建议该问题主要影响高频执行ALTER TABLE ... UPDATE/DELETE生成 patch parts并在短时间窗口内叠加读取的表。升级后建议对曾触发LOGICAL_ERROR的分区执行一次校验性查询或OPTIMIZE TABLE ... FINAL确认数据可正常读取。修复三O_DIRECT 模式下异步读缓冲的 seek 定位错误触发场景ClickHouse 在磁盘 IO 中大量使用异步预读prefetch机制并支持O_DIRECT直通模式绕过页缓存要求文件偏移与内存地址按块对齐。此前在O_DIRECT开启且缓冲区发生过 seek 的场景下会因偏移计算错误读到错误位置的数据PR #99678 同时关闭了 issue #99358影响查询结果正确性。底层实现印证相关实现在 src/IO/AsynchronousReadBufferFromFileDescriptor.h 与 src/IO/AsynchronousReadBufferFromFileDescriptor.cpp类注释明确说明其“使用现成文件描述符不负责打开/关闭文件”内部维护prefetch_buffer、internal_buffer、memory三块等长缓冲并在预读后交换required_alignment成员专门服务于O_DIRECT场景头文件注释For O_DIRECT both file offsets and memory addresses have to be aligned其值由构造参数alignment传入seek()实现src/IO/AsynchronousReadBufferFromFileDescriptor.cpp的seek函数中若目标位置仍在缓冲区内则仅移动pos指针否则执行真实 seek并存在关键分支off_t seek_pos required_alignment 1 ? new_pos / required_alignment * required_alignment : new_pos;即O_DIRECT下将目标偏移向下取整到对齐边界差额记入bytes_to_ignore修复的另一处关键语义在 seek 的返回值方法最终返回的是原始new_pos而非对齐后的seek_pos注释指出返回seek_pos会破坏依赖返回值的调用方如ReadBufferFromEncryptedFile。修复前O_DIRECT路径下 seek 后缓冲区状态与file_offset_of_buffer_end/bytes_to_ignore的记账存在不一致导致后续getPosition()其实现为file_offset_of_buffer_end - (working_buffer.end() - pos) bytes_to_ignore与实际读位置偏差从而读到错位数据。修复通过补齐对齐偏移的记账逻辑与返回语义确保O_DIRECT下 seek 结果准确。相关配置提示O_DIRECT行为通常由存储配置如磁盘的direct_io相关设置或表级min_bytes_to_use_direct_io类参数控制请以 tests/config 与 src/Disks 中的实际配置项为准。若你的环境启用了直通 IO本修复直接关系到读正确性建议优先升级并针对大文件读路径做回归。总结v25.8.20.4-lts 是一次典型的 LTS 稳定性补丁发布三项修复分别覆盖查询执行层递归 CTE、MergeTree 存储层Patch Parts与IO 基础层O_DIRECT 异步读均为用户可见的错误行为修复。对于运行 25.8 LTS 系列的集群建议按变更窗口安排升级若涉及远程分布式查询、高频轻量变更或直通 IO 场景可结合本文给出的源码路径做针对性回归验证。发布记录原始文档docs/changelogs/v25.8.20.4-lts.md递归 CTE 相关源码src/Analyzer/RecursiveCTE.cpp、src/Processors/Sources/RecursiveCTESource.cpp、src/Processors/QueryPlan/ReadFromRecursiveCTEStep.cppPatch Parts 变更转换源码src/Storages/MergeTree/AlterConversions.cpp、src/Storages/MergeTree/AlterConversions.hO_DIRECT 异步读缓冲源码src/IO/AsynchronousReadBufferFromFileDescriptor.cpp、src/IO/AsynchronousReadBufferFromFileDescriptor.h【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表