解析 ClickHouse v23.11.5.29-stable 版本变更:Jemalloc 内存诊断命令与 Iceberg 引擎新设置
解析 ClickHouse v23.11.5.29-stable 版本变更Jemalloc 内存诊断命令与 Iceberg 引擎新设置【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse本篇围绕 ClickHouse 2023 年 11 月的一个稳定分支修订版 v23.11.5.29-stable构建提交 d83b108deca相对上一稳定版 v23.11.4.24-stable的官方 changelog 展开。这个版本本身没有大规模功能新增但集中补强了三块对生产运维有价值的东西SYSTEM JEMALLOC系列内存诊断命令、Keeper 侧对应的 4LW 诊断命令以及 Iceberg 表引擎的iceberg_engine_ignore_schema_evolution设置同时修复了 7 个影响面较大的用户可见 Bug。读完本文你可以掌握该版本新增命令的用法与底层实现、Iceberg 读取策略的取舍以及每条修复所对应的问题域便于评估是否值得升级到该稳定版。一、版本定位稳定分支上的“补丁包”式发布v23.11.5.29-stable 是 v23.11 稳定分支上的一个修订版。从 changelog 结构看它的两条 Improvement 均标注了 “Backported in ...”说明这两个特性原本先合入主线分别对应 PR #58665 与 #59133随后被反向移植backport到稳定分支。这类修订版的典型特征是不加新的大功能只引入风险可控的增强和 Bug 修复适合作为生产环境的小版本升级目标。二、Improvement 1SYSTEM JEMALLOC命令族——把 jemalloc 诊断能力暴露给 SQL2.1 版本中新增的命令该版本为使用 jemalloc 构建的 ClickHouse 新增了如下 SQL 命令详见 changelog 的 Improvement 第一条对应 PR #58665命令作用SYSTEM JEMALLOC PURGE向 jemalloc 发出 arena purge 请求把不再使用的内存页归还给操作系统降低 RSS 占用SYSTEM JEMALLOC ENABLE PROFILE在 profiler 已编译启用的前提下打开 jemalloc 堆采样剖析SYSTEM JEMALLOC DISABLE PROFILE关闭堆采样剖析SYSTEM JEMALLOC FLUSH PROFILE立即把当前堆剖析数据落盘供后续符号化分析配合这些命令运维侧第一次可以直接用 SQL 回答两个常见问题“ClickHouse 为什么不还内存了”用 PURGE 触发归还和“内存都分配在哪了”用 ENABLE PROFILE → 跑负载 → FLUSH PROFILE 拿到堆剖析文件。2.2 源码层面的实现印证结合当前仓库源码可以看到这套命令的落地方式权限模型上这四条命令被归入同一个访问类型。AccessType.h 中定义M(SYSTEM_JEMALLOC, SYSTEM JEMALLOC PURGE, SYSTEM JEMALLOC ENABLE PROFILE, SYSTEM JEMALLOC DISABLE PROFILE, SYSTEM JEMALLOC FLUSH PROFILE, GLOBAL, SYSTEM) \即执行这些命令需要GLOBAL级别的SYSTEM权限属于典型的“高权限运维操作”。执行路径在 InterpreterSystemQuery.cpp 中。JEMALLOC_PURGE分支先做checkAccess(AccessType::SYSTEM_JEMALLOC)然后调用Jemalloc::purgeArenas()JEMALLOC_FLUSH_PROFILE分支会调用Jemalloc::flushProfile(/tmp/jemalloc_clickhouse)随后根据会话设置生成.symbolized或.collapsed后缀的符号化产物并把输出文件路径作为查询结果返回。剖析产物格式由会话设置控制Settings.cpp 中的声明jemalloc_profile_text_output_format取值raw原始 profile、symbolizedjeprof 格式带符号或collapsedFlameGraph 折叠栈格式默认collapsedjemalloc_profile_text_symbolize_with_inline是否包含 inline 帧默认开启关闭可换取更快的符号化速度jemalloc_profile_text_collapsed_use_count折叠格式按“分配次数”而非“字节数”聚合默认关闭。配套的 system 表system.jemalloc_profile_text用于查看符号化后的堆剖析attachSystemTables.cpp 中注册时给出了使用前提“Run SYSTEM JEMALLOC FLUSH PROFILE to generate a profile first”——即必须先执行一次 FLUSH 才能查到数据。2.3 相关配置项与后续演进jemalloc 行为的总体开关在 Jemalloc.h 中集中声明了配置键名与默认值配置键默认值说明jemalloc_enable_global_profilerfalse是否启用全局堆剖析器jemalloc_enable_background_threadstrue是否启用 jemalloc 后台线程jemalloc_max_background_threads_num0后台线程数上限0 表示由 jemalloc 自行决定jemalloc_collect_global_profile_samples_in_trace_logfalse是否把全局剖析采样写入 trace logjemalloc_profiler_sampling_rate19剖析采样率lg_prof_sample需要注意一个版本演进细节从当前仓库代码看全局SYSTEM JEMALLOC ENABLE/DISABLE PROFILE已被标记为废弃路径——InterpreterSystemQuery.cpp中这两个分支直接抛出异常提示“Please use config jemalloc_enable_global_profiler or enable it per query using setting jemalloc_enable_profiler”。也就是说在 v23.11 时期这四条命令均可用但在后续主线中全局 profiler 的开关收敛到了启动配置或按查询设置层面SQL 命令主要负责 PURGE 与 FLUSH。如果你基于 v23.11.5.29-stable 做运维自动化ENABLE/DISABLE PROFILE 是可用的若迁移到新版本应改用配置项方式。三、Improvement 1 的 Keeper 侧延伸jmst/jmfp/jmep/jmdp四条 4LW 命令同一 PR 还给 KeeperClickHouse 的 ZooKeeper 兼容协调服务加了 4 条四字母命令4LWFour Letter Word同样是 jemalloc 诊断能力命令对应实现功能jmstJemallocDumpStatsdump jemalloc 统计信息jmfpJemallocFlushProfile在 profiler 启用时 flush 堆剖析jmepJemallocEnableProfile在 profiler 启用时开启堆剖析jmdpJemallocDisableProfile关闭堆剖析源码印证如下四个命令类定义在 FourLetterCommand.h整体被#if USE_JEMALLOC包裹——即只有以 jemalloc 构建时这四个命令才编译进二进制非 jemalloc 构建下执行会报未知命令。命令行客户端的合法命令白名单里也登记了它们见 KeeperClient.h因此可以用clickhouse-keeper-client -q jmst这类方式直接对 Keeper 节点发诊断请求。CoordinationSettings.cpp 中默认允许的四字母命令列表包含jmst,jmfp,jmep,jmdp说明这四条命令默认是放行的Keeper 对 4LW 命令有 allow-list 机制防止误用。这条增强的意义在于Keeper 虽然负载轻但在高吞吐场景大量会话、watcher、事务下同样可能受 jemalloc 内存归还策略影响4LW 命令让 Keeper 与 Server 具备了同一套内存诊断手段。四、Improvement 2Iceberg 引擎的iceberg_engine_ignore_schema_evolution4.1 设置语义changelog 第二条记录了 Iceberg 表引擎的一个读取策略开关PR #59133新设置iceberg_engine_ignore_schema_evolution默认关闭false开启后读取 Iceberg 表时忽略 schema 演进所有数据文件都使用同一份 schema 读取——要么是用户建表时指定的 schema要么是建表时从元数据解析到的最新 schemachangelog 明确警告对存在 schema 演进的数据集开启该设置可能得到错误结果因为所有数据文件都会用同一份 schema 去解释。4.2 适用场景与源码印证这个设置的价值在于“一致性优先于正确性”的特定场景当上游 Iceberg 表 schema 演进历史复杂、或者用户只想按自己定义的视图读全量数据时逐文件按历史 schema 解析可能不符合预期此时可以强制用单一 schema 读全部数据。作为交换你要接受“schema 不匹配的数据可能被误读或丢失”的风险。在仓库中可以找到该设置的完整生命周期记录引入记录见 SettingsChangesHistory.cpp{iceberg_engine_ignore_schema_evolution, false, false, Allow to ignore schema evolution in Iceberg table engine}登记在 v23.11 版本段与本次 backport 一致值得注意在当前主线代码 Settings.cpp 中该设置已被MAKE_OBSOLETE标记默认值仍为false。这意味着在后续版本里Iceberg 引擎的读取/schema 演进处理策略发生了重构v23.11 时期的这一独立开关不再是当前形态。如果你的集群长期停留在 23.11 分支并依赖此设置升级主线前需要确认新版本的等价行为。五、Bug Fix七个用户可见修复逐条解读该版本的 Bug Fix 部分修复了 7 个“official stable release 中用户可见的错误行为”以下逐条说明其问题域与影响修复内容对应 PR问题域解读Fix a stupid case of intersecting parts#58482MergeTree 分区间合并intersecting parts的边界场景。MergeTree 依赖“part 之间主键范围互不重叠”的不变量来路由查询该修复消除了一个会导致查询命中错误 part 或合并行为异常的路径。作者 Alexander Tokmakov 是 MergeTree 核心维护者之一Fix stream partitioning in parallel window functions#58739并行窗口函数window 1下多流并行执行的流划分stream partitioning错误。分区键不一致会导致窗口函数如row_number、lag等在错误的数据分组上计算结果集内部顺序/值出错Fix double destroy call on exception throw in addBatchLookupTable8#58745聚合函数基于查找表lookup table的批量计算路径在抛异常时发生“双重释放”double destroy属于内存安全问题。addBatchLookupTable8接口定义于 IAggregateFunction.h约 L400 处声明的虚函数addBatchLookupTable8并被 Aggregator.cpp 的批处理路径调用此修复消除了该异常路径上的重复析构Fix JSONExtract function for LowCardinality(Nullable) columns#58808JSONExtract系列函数处理LowCardinality(Nullable(...))组合列时出错取不到值或取错值。这是 JSON 半结构化查询的常见列类型修复后对这类列的提取结果恢复正确Fix LIMIT BY and LIMIT in distributed query#59153分布式查询LIMIT BY与LIMIT同时存在下子查询改写/下推错误可能导致结果行数或分组不符合预期。分布式场景下LIMIT BY需要在各分片与协调端之间正确传递属于经典的分布式改写类 BugFix not-ready set for system.tables#59351system.tables系统表的 not-ready 集合维护错误可能把尚未就绪的表错误地标记为就绪或反之影响依赖系统表做轮询/就绪判断的客户端Fix translate() with FixedString input#59356字符串函数translate()处理FixedString输入时结果错误修复后对定长字符串列的字符映射替换行为正确从修复分布可以看出这个修订版的质量取向既覆盖存储层part 边界、执行层并行窗口函数、聚合异常路径、SQL 语义层JSONExtract、translate也覆盖系统表与分布式查询改写适合作为 23.11 分支用户的一次“攒够一批修复”的升级点。六、NOT FOR CHANGELOG不计入用户变更的内部修复changelog 末尾的 “NOT FOR CHANGELOG / INSIGNIFICANT” 部分列出了一些不进正式变更说明的内部改动其中两条对稳定性敏感的系统仍有参考价值Fix rare race in external sort/aggregation with temporary data in cache#58013当外部排序/聚合的临时数据落入 cache 时存在一个罕见的竞态条件。开启临时数据缓存如使用 cache disk 存放 spill 数据的部署应关注此修复Fix possible race in ManyAggregatedData dtor#58624多行聚合数据结构析构时的潜在竞态属于并发安全加固。其余条目为日志级别调整#59168、错误信息措辞细化#57991以及 #58482 的跟进补丁#58574。七、小结这个稳定版值得你关注什么v23.11.5.29-stable 虽然只是一个稳定分支修订版但技术含量集中在三条主线上内存可观测性与可控性SYSTEM JEMALLOC PURGE让“jemalloc 不还内存”这类问题第一次可以在不重启的情况下主动干预ENABLE/DISABLE/FLUSH PROFILE加system.jemalloc_profile_text表与格式设置jemalloc_profile_text_output_format等构成了完整的堆剖析工作流Keeper 侧用jmst/jmfp/jmep/jmdp四条 4LW 命令补齐了对称能力实现见 FourLetterCommand.h。注意这些能力均要求 jemalloc 构建源码中大量#if USE_JEMALLOC条件编译。Iceberg 读取策略可配置iceberg_engine_ignore_schema_evolution默认关闭提供了“按单一 schema 读全量数据”的逃生舱changelog 同时明确提示了开启后结果可能不正确的风险该设置在当前主线已被标记 obsolete说明后续版本对该策略有更完整的重构。执行与存储稳健性7 个用户可见 Bug 修复覆盖了 intersecting parts、并行窗口函数分区、聚合异常路径双重释放、JSONExtract/translate 函数行为、分布式LIMIT BY、system.tables就绪状态等高频使用面。如果你正在使用 23.11 分支这一版对“内存运维”和“正确性修复”都有实质收益同时建议在执行SYSTEM JEMALLOC系列命令前确认目标构建确实启用了 jemalloc并保留SYSTEM级别的访问权限管理避免普通查询账号误操作全局内存行为。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考