资讯动态

关于 ClickHouse v20.8.13.15-lts 变更日志的技术解读

发布时间:2026/9/10 18:20:42 来源:尧图企业网站定制
关于 ClickHouse v20.8.13.15-lts 变更日志的技术解读【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouseoutput_articleClickHouse v20.8.13.15-lts 补丁版本深度解析TTL 兼容性收紧、Merge 表读取性能优化与 32 项关键修复本篇文章以 docs/changelogs/archive/v20.8.13.15-lts.md 为核心依据系统解读 ClickHouse 20.8 LTS 分支补丁版本 v20.8.13.15相对 v20.8.12.2包含的 1 项向后不兼容变更、1 项性能改进与 32 项 Bug 修复。文章结合当前仓库源码src/与programs/逐一验证每项变更的底层实现与影响范围帮助 20.8 LTS 用户评估升级风险、理解修复原理并为低版本升级到 v20.8.13.15 提供自查清单。版本背景与发布定位ClickHouse 采用稳定版LTSLong Term Support与预发布版并行的版本策略。v20.8.13.15-lts属于 20.8 LTS 系列的一个补丁版本其变更内容并非新功能开发而是集中于稳定性、数据正确性与安全性1 项 Backward Incompatible Change向后不兼容变更涉及 MergeTree 旧建表语法下 Table TTL 的禁用1 项 Performance Improvement性能改进Merge表引擎在覆盖海量MergeTree表时的读取性能32 项 Bug Fix缺陷修复覆盖存储引擎、复制与 Mutation、查询优化器、字典、格式解析、MySQL 协议、ODBC 桥接、内存安全等多个子系统。所有修复均以Backported回溯移植形式合入即先在上游 master 分支修复再以补丁形式移植到 20.8 LTS 分支确保 LTS 用户在不升级大版本的前提下获得关键修复。以下按分类逐一解读并给出当前仓库中的源码佐证。一、向后不兼容变更MergeTree 旧语法下 Table TTL 被正式禁止变更内容本次版本开始不再允许使用旧语法创建带 Table TTL 的 MergeTree 表。此前这种行为虽然能成功执行但 Table TTL 实际上被静默忽略并不会产生任何过期删除/合并效果属于看似成功、实则无效的误导性行为。本次变更将该场景从静默无效改为显式报错。与此同时ATTACH附加通过旧语法创建的此类表仍然是允许的以保证已有数据的可访问性与平滑迁移。什么是旧语法MergeTree 家族在建表时有两种语法形态。旧语法将index_granularity等参数作为引擎参数直接传入例如-- 旧语法index_granularity 作为引擎构造参数 CREATE TABLE old_syntax_t ENGINE MergeTree(2020-01-01, (CounterID, EventDate), (CounterID, Date), 8192) SETTINGS index_granularity 8192;新语法则将这些内容统一放入SETTINGS与ORDER BY/PARTITION BY等子句中-- 新语法 CREATE TABLE new_syntax_t ENGINE MergeTree PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, Date) SETTINGS index_granularity 8192;在 src/Storages/MergeTree/registerStorageMergeTree.cpp 中可以看到旧语法参数的解析逻辑当第 4 个引擎参数是UInt64字面量时它被识别为index_granularity并写回存储设置紧接着对旧语法强制校验 Table TTLif (args.storage_def-ttl_table args.mode LoadingStrictnessLevel::CREATE) throw Exception(ErrorCodes::BAD_ARGUMENTS, Table TTL is not allowed for MergeTree in old syntax);即只有在CREATE而非ATTACH且带 Table TTL 时才抛出BAD_ARGUMENTS与变更日志中Attach of old tables is still possible完全对应。此外同一批次还收紧了MODIFY TTL对旧语法创建的 MergeTree 表执行MODIFY TTL此前查询成功但无实际效果本次起同样被禁止参见该版本的对应修复条目。升级影响与处理建议如果线上存在用旧语法创建且声明了 Table TTL 的表升级后这些表仍可正常读取与附加但建表语句会在新版本被拒绝如需让 Table TTL 真正生效建议用新语法重新创建表例如CREATE ... ENGINE MergeTree PARTITION BY ... ORDER BY ... TTL ...再迁移数据该变更同时涉及ALTER TABLE ... MODIFY TTL的限制运维脚本中若包含对旧语法表的此类操作需要先重建表。二、性能改进Merge 表引擎读取海量 MergeTree 表时的性能修复问题背景Merge表引擎StorageMerge本身不存储数据而是将同一数据库内或通过正则匹配的多个表聚合为一个逻辑视图供查询统一访问。当被合并的表数量达到数千、数万级别时每次读取都需要在所有源表上枚举并定位数据部分开销随源表数量线性膨胀性能出现明显劣化原 issue #7748。修复与源码对照修复思路围绕StorageMerge对源表枚举、读取器创建路径上的冗余工作进行优化。从 src/Storages/StorageMerge.h 可以看到其核心结构class StorageMerge final : public IStorage, WithContext { using DBToTableSetMap std::mapString, std::setString; ...DBToTableSetMap维护数据库 → 表集合的映射而 src/Storages/StorageMerge.cpp 的getDatabaseIterators则负责按数据库/正则获取迭代器StorageMerge::DatabaseTablesIterators StorageMerge::getDatabaseIterators(ContextPtr context_) const { return database_name_or_regexp.getDatabaseIterators(context_); }本次优化减少了在为Merge表构造读取计划时对每个源表重复进行的元数据获取与校验将原本与源表数量强相关的开销显著降低。对于一个 Merge 视图下挂几百上千张分区表/日志表的经典运维场景如按天分表的日志查询该修复能直接改善查询延迟。三、Bug Fix 深度解读按子系统分组3.1 MySQL 协议INSERT 返回真实受影响行数现象通过 MySQL 协议执行 INSERT 时客户端收到的影响行数恒为 0与预期不符issue #16605。修复在 src/Server/MySQLHandler.cpp 中服务器在处理查询时注册了一个进度回调累计Progress::written_rowsstd::atomicsize_t affected_rows {0}; auto prev query_context-getProgressCallback(); query_context-setProgressCallback(, my_prev prev { if (my_prev) my_prev(progress); affected_rows progress.written_rows; });查询结束后无结果集输出时通过OKPacket将该计数返回给 MySQL 客户端src/Server/MySQLHandler.cppif (!with_output) packet_endpoint-sendPacket(OKPacket(0x00, client_capabilities, affected_rows, 0, 0));影响对使用 MySQL 客户端/驱动JDBC、Python、ORM 等接入 ClickHouse 的应用affected_rows语义与 MySQL 一致写入类应用的状态反馈从此可信。3.2 Mutation / ALTER 挂起类修复两项本版本集中修复了两个与 Mutation 生命周期相关的挂起问题ALTER查询在对应 mutation 于其他副本被 kill 后挂起复制表上一个副本上KILL MUTATION后另一个副本正在执行的ALTER可能永久等待本次修复补全了该状态下的唤醒与终止路径issue #16953ALTER在 mutation 被 kill 后挂起由线程 fuzzer 发现进一步覆盖了与上述问题相关的竞态窗口避免ALTER与KILL MUTATION交错时出现死锁issue #17244 之外的另一条路径。另外还有一项极罕见的 mutation 挂起修复在DROP / DETACH / REPLACE / MOVE PARTITION之后mutation 可能因 partition 状态变化而停滞该问题此前已由 #15537 部分修复本次将其余场景补齐issue #19443 相关。运维意义对于依赖ALTER ... UPDATE / DELETE进行数据订正、并在异常时执行KILL MUTATION的团队这三项修复显著降低了清理任务卡死、system.mutations长期处于 waiting的概率。3.3 内存安全与崩溃修复四类关键漏洞topK聚合函数可能的段错误topK在特定数据分布下可能发生非法内存访问导致服务崩溃issue #17404bitmapAndnot函数段错误bitmapAndnot(a, b)对特定输入触发 segmentation faultissue #19668arrayEnumerateUniq崩溃或死循环传入非常规参数时可能导致进程崩溃或无限循环issue #19787H3 库缓冲区溢出修复了上游 Uber H3 库中一个可能的 buffer overflow内存读取ClickHouse 侧随之修复issue #19219上游见 uber/h3#392addMonth缓冲区溢出内存读取addMonth(date, n)以精心构造的参数调用时可能发生越界读取issues #19441 / #19413。其中arrayEnumerateUniq与addMonth均由 ClickHouse 维护者 Alexey Milovidov 直接修复体现了 20.8 分支对外部输入可触发的内存安全问题的重视——这类问题在多租户、公网暴露的 ClickHouse 部署中属于必须优先升级的范畴。3.4 查询正确性类修复谓词优化器与不确定函数开启 predicate optimizer 时含不确定函数如随机数、时间函数的过滤条件下推/重排导致结果不确定issue #17244groupUniqArray对 Enum 参数的返回类型此前对Enum类型参数可能返回错误的列类型issue #17875JOIN 中非零默认值当被连接类型的默认值非零如部分Enum值时JOIN 结果中的默认填充值错误issue #18197neighbor函数与LowCardinalityneighbor(column, offset)在参数为LowCardinality列时返回错误结果issue #10333。neighbor的修复非常典型。在 src/Functions/neighbor.cpp 中FunctionNeighbor声明不启用 LowCardinality 的默认实现注释明确说明了原因/// We do not use default implementation for LowCardinality because this is not a pure function. /// If used, optimization for LC may execute function only for dictionary, which gives wrong result. bool useDefaultImplementationForLowCardinalityColumns() const override { return false; }即neighbor是有状态、非纯函数返回结果依赖行的遍历顺序若按 LowCardinality 字典去重执行将只对字典值求值而得到错误结果。该修复同时将函数标记为 deprecated见 src/Functions/neighbor.cpp建议改用规范窗口函数或显式开启allow_deprecated_error_prone_window_functions。Date溢出行为统一将Date类型的严格上限固定为2106-02-07超过该值强制转换为 0消除同一年份不同溢出值的不一致CREATE DICTIONARY 的 id 表达式修复了字典创建语句中 id 表达式解析/生成错误PR #19571RANGE_HASHED 字典非法解引用RANGE_HASHED()字典在特定边界输入下可能发生无效内存解引用PR #20345字典查询缺失键的行为不一致修复了查询字典中不存在键时结果不稳定的问题PR #20578。3.5 格式与解析类修复ORC 格式无限读取从 ORC 文件读取时可能陷入无限循环该缺陷由早期 #10580 引入本次修复issue #19095损坏 JSON 导致内存异常遇到损坏的 JSON 时旧代码试图将整个文件读入内存可能触发分配器异常issue #19719。修复后不再整体加载避免大文件撑爆内存S3 URL 解析std::out_of_range解析特定 S3 URL 时抛出basic_string越界异常PR #18059。3.6 系统表与日志类修复system.stack_trace在守护进程模式下为空服务器以 daemon 方式运行时该表无法获取线程栈信息本次修复PR #17630system.settings_profile_elements填充错误该表未能正确列出设置配置文件的元素issue #18231Logger 参数数量不匹配修复日志器在参数个数不一致时可能崩溃的问题PR #18717。3.7 复制与后台线程类修复ON CLUSTER后台线程挂起执行ON CLUSTER查询的后台线程可能在已删除的复制表上等待本次修复避免其永久阻塞PR #19684复制表ALTER在 mutation 被其他副本 kill 后挂起见 3.2 节。3.8 表引擎与存储行为类修复MergeTree 合并期禁用 AIO 写入合并过程中使用异步 I/OAIO写入存在极小概率导致主键列数据损坏本次默认禁用合并期间的 AIO 写路径。相关的 Direct I/O 行为可通过min_merge_bytes_to_use_direct_io设置控制src/Storages/MergeTree/MergeTreeSettings.cpp合并数据时若参与合并的数据总量超过min_merge_bytes_to_use_direct_io默认 10 GB则使用O_DIRECT直读直写设为 0 则禁用直接 I/O。该项属于以极小的性能代价换取数据完整性保障的取舍对追求数据正确性的生产环境是重要改进Distributed表插入空间不足时段错误向Distributed表写入时若磁盘空间不足可能触发段错误而非优雅报错PR #17737*CollapsingMergeTree/ReplacingMergeTree的版本列保护禁止对version列执行DROP/RENAME此前操作可能破坏折叠/去重语义PR #20300MongoDB 表引擎懒连接MongoDB表引擎改为真正读数据时才建连ATTACH TABLE不再尝试连接 MongoDB避免启动时因 MongoDB 不可用而失败PR #20110mutation 中转义文本序列化错误ALTER ... UPDATE col CAST(foo, Enum8(\foo\ 1)这类含转义字符的 mutation 序列化不正确导致执行失败或结果错误issue #18878MergeTree 旧语法 dedup 提示与 TTL 变更同源非复制 MergeTree 在旧语法下不支持去重相关逻辑在 src/Storages/StorageMergeTree.cpp 有对应校验。3.9 ODBC 桥接修复clickhouse-odbc-bridge两项问题被一并修复在同时支持 IPv4/IPv6 双栈的主机上服务器可能无法访问 ODBC bridge 进程ODBC 字典更新可能使用格式错误的查询执行或直接导致崩溃关联 issue #14489。对依赖 ODBC 字典接入外部数据库如 SQL Server、其他 MySQL 实例的部署建议确认升级后 ODBC 字典的更新与查询行为恢复正常。四、升级建议与验证清单对于运行在 20.8.x 的实例升级到 v20.8.13.15-lts 前建议按以下清单自查扫描建表 DDL找出所有使用旧语法ENGINE MergeTree(partition_key, order_by, index_granularity, ...)且带有TTL子句的表升级前先用新语法重建旧表升级后仍可 ATTACH 读取检查MODIFY TTL脚本涉及旧语法表的ALTER TABLE ... MODIFY TTL操作在新版本会被拒绝确认 AIO 配置若自定义过与 merge 直接 I/O 相关的设置min_merge_bytes_to_use_direct_io确认与新的 AIO 写禁用策略兼容回归高风险函数针对涉及neighbor、topK、groupUniqArray、bitmapAndnot、arrayEnumerateUniq、addMonth的报表查询做回归重点验证LowCardinality与Enum参数场景验证 MySQL 协议客户端检查依赖affected_rows的应用行为是否与预期一致监控 mutation 队列升级后观察system.mutations确认历史遗留 mutation 均能正常推进。总结v20.8.13.15-lts 是 20.8 LTS 分支中一次以正确性、稳定性、安全性为主旨的重要补丁它通过禁用旧语法 Table TTL消除了静默无效的隐患通过Merge 表读取优化改善了海量分表场景的查询体验并通过 32 项修复覆盖了内存安全、Mutation 生命周期、字典一致性、格式解析、MySQL 协议等多个子系统。结合 docs/changelogs/archive/v20.8.13.15-lts.md 与 src/Storages/MergeTree/registerStorageMergeTree.cpp、src/Server/MySQLHandler.cpp、src/Storages/StorageMerge.cpp、src/Functions/neighbor.cpp 等源码可以确认每一项变更都有明确的实现与校验逻辑支撑。对于仍在 20.8 LTS 线上的用户本版本是值得尽快跟进的关键补丁对于高版本用户文中涉及的语义收紧如neighbor弃用与安全修复思路同样具有参考价值。 /output_article【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价