恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
ClickHouse v20.9.7.11-stable 发布解析:性能修复、MySQL 协议兼容与 17 项 Bug Fix 源码级解读
首页
资讯中心
/
ClickHouse v20.9.7.11-stable 发布解析:性能修复、MySQL 协议兼容与 17 项 Bug Fix 源码级解读
ClickHouse v20.9.7.11-stable 发布解析:性能修复、MySQL 协议兼容与 17 项 Bug Fix 源码级解读
发布时间:2026/9/11 0:36:48
ClickHouse v20.9.7.11-stable 发布解析性能修复、MySQL 协议兼容与 17 项 Bug Fix 源码级解读【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse导读本文围绕 ClickHouse 官方变更日志 v20.9.7.11-stable 展开逐条解析这一针对 v20.9.6.14-stable 的稳定版补丁发布。读者将了解本次版本包含的 1 项性能改进、17 项 Bug Fix 与 1 项构建/测试改进各自解决的问题、影响场景与修复思路并结合当前仓库中的源码实现如 fuzzBits.cpp、MySQLHandler.cpp 等获得可复现、可验证的底层原理。说明本文所述版本号、修复项均以当前仓库归档的官方 changelog 为准所有源码分析针对当前仓库中的最新实现部分配置项在后续版本中已被标记为废弃文中会特别指出。一、版本背景与定位ClickHouse 的发布遵循 master → 候选版本 → stable 的迭代节奏。v20.9.7.11-stable 是 v20.9 分支上的一个稳定版补丁patch release全部变更均为从 master 反向移植backport而来不包含新特性只包含1 项性能改进Performance Improvement17 项 Bug Fix1 项构建/测试/打包改进Build/Testing/Packaging Improvement这类补丁版本的目标是在不引入破坏性变化的前提下快速修复生产环境中的关键缺陷。升级路径为v20.9.6.14-stable → v20.9.7.11-stable。二、性能改进Merge 表跨海量 MergeTree 表的读取性能2.1 问题描述当Merge表需要读取大量底层MergeTree表时存在明显的性能问题对应 issue #7748。修复由 Anton Popov 提交PR #16988。2.2 背景原理Merge引擎表本身不存储数据而是将查询路由到底层的一组表。当这组表数量巨大时每次查询都需要枚举、初始化并协调所有底层表的读取任务。若初始化阶段存在冗余开销如对每个子表重复做代价较高的准备操作总耗时会随子表数量线性放大导致“表越多、查询越慢”的现象。2.3 修复要点PR #16988 的核心是消除读取路径中的重复性初始化工作使跨多表的读取能够更高效地被调度与执行。对运维人员而言此修复的直接收益是在聚合了成百上千张 MergeTree 表的Merge表上执行SELECT查询耗时显著下降同时降低了为支撑查询而消耗的 CPU 与内存开销。三、Bug Fix 分类解析3.1 MySQL 协议兼容性INSERT 返回受影响行数修复项PR #16715修复 issue #16605通过 MySQL 协议执行INSERT查询时正确返回受影响的行数此前 ClickHouse 始终返回 0。该修复的实际落地可以从当前仓库源码中得到印证PacketsGeneric.cpp 中定义了OKPacket结构其构造函数显式初始化affected_rows并在 writePayload 中通过writeLengthEncodedNumber(affected_rows, buffer)将行数编码进 OK 响应包MySQLHandler.cpp 在查询执行阶段用std::atomicsize_t affected_rows {0}累加progress.written_rows最终通过OKPacket(0x00, client_capabilities, affected_rows, 0, 0)发送给客户端。影响场景依赖 MySQL 驱动返回受影响行数做业务判断的应用如 ORM 的受影响记录数统计、数据同步任务的增量判定此前拿到的一律是 0会导致误判。升级后行数上报与真实写入量一致。注意该行为仅作用于写入型语句非写入查询仍按既有协议路径返回。3.2 可被取消的远程查询不再产生多余网络错误修复项PR #17006对于执行过程中可能被取消的远程查询典型如带LIMIT的查询避免产生不必要的网络错误。带LIMIT的查询在满足行数后即可提前结束此时分布式查询中尚未消费完的远端分片会收到取消信号。修复前这种“预期中的取消”可能被误报为网络层错误污染日志与监控指标修复后取消路径被正确识别并静默处理仅保留真实故障的错误上报。3.3 fuzzBits 函数缺陷修复修复项PR #17051修复 issue #16980修复fuzzBits函数的 bug。fuzzBits是 ClickHouse 的位模糊化随机函数用于按概率翻转字符串的每个二进制位常用于模糊测试、脱敏扰动等场景。其当前实现位于 fuzzBits.cpp函数签名fuzzBits(s, p)s为String或FixedStringp为每个位被翻转的概率取值必须在[0.0, 1.0]之间fuzzBits.cpp 对越界值抛出ARGUMENT_OUT_OF_BOUND核心算法getXorMaskfuzzBits.cpp基于pcg64_fast伪随机数生成器逐位产生掩码再执行ptr_out[i] ptr_in[i] ^ maskfuzzBits.cpp函数被标记为isDeterministic() falsefuzzBits.cpp因此每次执行的随机结果不同它同时支持ColumnString与ColumnFixedString两类输入列fuzzBits.cpp。v20.9 时代该函数的已知缺陷与本次修复相关当前源码中还保留了清晰的边界约束文档例如第二参数必须是常量浮点数且翻转概率超出范围会直接报错——这些约束正是为了避免此前版本中参数校验不严导致的错误输出。使用示例来自源码内嵌文档SELECT fuzzBits(materialize(abacaba), 0.1) FROM numbers(3) -- 可能的输出 ┌─fuzzBits(materialize(abacaba), 0.1)─┐ │ abaaaja │ │ a*cjab │ │ aeca2A │ └───────────────────────────────────────┘3.4 CREATE TABLE ... AS table_function() 崩溃修复修复项PR #17072修复 issue #16944当执行CREATE TABLE ... AS some_table且some_table本身是通过AS table_function()方式创建时会触发崩溃。修复后此类嵌套引用可以正确解析并建表不再崩溃。3.5 ColumnConst 比较导致崩溃的修复修复项PR #17135修复 issue #17088修复ColumnConst常量列参与比较运算时的崩溃问题。ClickHouse 中常量列是重要的列式存储优化——单值列不重复存储而是以ColumnConst包装共享同一份数据。当常量列直接参与比较运算而未先展开为完整列时内部对“物理行数”与“逻辑行数”的假设不一致就可能触发越界访问。本次修复针对该路径确保常量列在比较前被正确处理。在 fuzzBits.cpp 中可以看到同类问题的典型处理范式通过convertToFullColumnIfConst()将常量列展开后再按行独立运算。3.6 clickhouse-copier 处理非分区表时的段错误修复修复项PR #17248修复 issue #15235clickhouse-copier表数据拷贝工具在处理非分区表时抛出段错误segfault。修复后非分区表可以正常完成数据拷贝任务。3.7 子查询含常量列时 Set 索引失效修复修复项PR #17249修复 issue #17246修复子查询中存在常量列时Set 索引失效的问题。Set 索引SET类型的跳数索引依赖对子查询结果构建集合、并在主查询过滤时做快速成员判断。当子查询结果中存在常量列时索引构建方与查询方的列语义不再对齐导致索引命中失效、无法裁剪数据块。修复后常量列被正确归一化索引可以正常生效。3.8 JOIN 表 LowCardinality 读取崩溃修复修复项PR #17397修复 issue #17228修复从JOIN引擎表读取LowCardinality类型列时的崩溃。LowCardinality通过“字典 编码索引”压缩基数较低的列在连接Join场景中会频繁进行字典映射与转换。崩溃源于特定读取路径下字典未能被正确同步或转换。修复后JOIN引擎表可以安全地读取LowCardinality列。3.9 DISTINCT 因错误优化产生重复行的修复修复项PR #17296 补充 PR #17439修复 issue #17294修复因不正确的优化导致DISTINCT之后仍出现重复行的问题。去重是数据正确性的底线。该缺陷源于查询优化阶段对某些表达式做了等价变换而该变换在特定数据形态下并不保真从而破坏了DISTINCT的语义。本次修复同时涉及优化器PR #17296与执行层的补充修正PR #17439确保DISTINCT输出严格唯一。3.10 ORDER BY 在 optimize_redundant_functions_in_order_by 下出错修复项PR #17471修复开启optimize_redundant_functions_in_order_by设置时ORDER BY查询结果错误的问题。该设置会尝试移除ORDER BY中冗余的函数包装例如ORDER BY toString(x)可能被优化为ORDER BY x以减少排序计算量。修复前的缺陷在于某些情况下函数移除后改变了实际排序语义。当前仓库中该优化在分析器侧由 OptimizeRedundantFunctionsInOrderByPass.cpp 实现并在 TreeOptimizer.cpp 中作为查询优化 pass 被调度对应设置项可在 Settings.cpp 中查询默认值。修复后该优化在保证结果正确的前提下保留其性能收益。3.11 Mark 缓存大小被低估的修复修复项PR #17496修复 ClickHouse 对mark 缓存mark cache大小估计偏低的问题典型场景是存在大量带 mark 的小文件。mark标记是 MergeTree 数据部分中记录每个 granule 偏移的关键索引信息读取时会被加载进MarkCache相关实现见 MergeTreeMarksLoader.cpp 等。当数据部分数量多且单个部分很小如高频写入产生的大量小 parts时mark 数量远大于按“部分数量 × 平均大小”估算的模型缓存容量被低估后频繁驱逐重载造成额外 I/O。修复后缓存占用按实际 mark 规模更准确地核算。3.12 ALTER 查询在副本上 mutation 被 kill 后挂起的修复修复项PR #17499修复 issue #16953修复当某个副本上的 mutation数据变更任务如ALTER ... UPDATE/DELETE被 kill 时对应的ALTER查询在其他副本上挂起的问题。分布式环境下 mutation 由协调方分发给各副本执行。若某副本的 mutation 进程被终止而协调方未及时感知等待该副本确认的ALTER查询会一直处于等待状态。修复后mutation 被杀死的状态会被正确传播ALTER查询得以结束而不再无限挂起。3.13 clickhouse-client 多行模式下单行注释延伸的修复修复项PR #17565修复 issue #13654修复clickhouse-client在交互式多行查询模式下单行注释--或#被错误延伸到查询末尾的问题。多行编辑模式下用户输入SELECT ... -- comment后换行继续输入下一行修复前解析器会把--之后的全部内容包括换行后的真实 SQL都当作注释导致语句被截断或报错。修复后注释按行终止多行输入行为符合直觉。3.14 RENAME 在 WSL 上的 Atomic 库报 Function not implemented 修复修复项PR #17664修复 issue #17661修复 ClickHouse 运行在Windows Subsystem for LinuxWSL上时在Atomic数据库引擎中执行RENAME查询报Function not implemented错误的问题。Atomic引擎通过底层文件系统操作如原子重命名实现 DDL 的原子性。WSL 文件系统对部分 POSIX 调用的支持差异导致重命名失败。修复后该操作在 WSL 环境下可正常工作。3.15 ClickHouse 无法恢复 MySQL 连接的问题修复项PR #17681修复 ClickHouse 在连接中断后无法恢复与 MySQL 服务器的连接的问题典型场景为 MySQL 侧主动断开或网络抖动。该修复保障了 MySQL 表引擎、MySQL 字典等依赖远程 MySQL 连接的组件在连接失效后能够按既有的重连机制恢复而不是持续失败。3.16 禁用 in_memory_parts_enable_wal 时不再从 WAL 恢复 parts修复项PR #17802当in_memory_parts_enable_wal被禁用时ClickHouse 不再从 WALWrite-Ahead Log恢复内存 parts。内存 partsin-memory parts是 MergeTree 中min_bytes_for_compression等阈值下临时驻留内存的小数据块默认由 WAL 保证持久性。该设置在当前的 MergeTreeSettings.cpp 中已被标记为MAKE_OBSOLETE_MERGE_TREE_SETTING默认true说明该机制在后续版本中已被演进或取代但在 v20.9 时代禁用该设置的用户会在重启时错误地从 WAL 恢复 parts与预期不一致。修复后设置关闭即完全跳过 WAL 恢复路径避免数据形态与配置语义不符。3.17 其余修复项速览修复项PR说明RENAME/DDL 相关杂项#16866变更日志中标注为 TODO未给出具体细节远程查询取消相关的网络错误#17006已在 3.2 详述四、构建 / 测试 / 打包改进时区数据升级改进项PR #17204将嵌入式时区数据升级到2020d版本并同步更新 cctz 至最新 master。ClickHouse 在 base/cctz 等路径依赖 cctz 库处理时区转换。时区数据的更新意味着正确处理 2020 年 10 月后生效的全球时区规则变化如部分国家/地区夏令时调整toTimeZone、timeZoneOf、now()等在历史/未来时间戳上的转换结果与权威时区数据库保持一致。对于涉及跨时区报表、调度任务toStartOfHour等按本地时区聚合的生产系统保持时区数据最新是避免“时间错位一小时”类问题的基础。该改进通常随补丁版本自动生效无需额外配置。五、升级建议与验证方式5.1 升级路径当前使用v20.9.x stable 系列的用户可直接升级到本版本v20.9.6.14-stable → v20.9.7.11-stable升级前建议在测试环境先运行一次回归查询重点覆盖本文涉及的场景Merge大表集合查询、MySQL 协议写入、DISTINCT/ORDER BY、LowCardinality关联、fuzzBits调用、Atomic库的RENAME。5.2 验证建议MySQL 协议影响行数使用 MySQL 客户端或驱动执行INSERT检查返回的affected rows是否与写入行数一致fuzzBits 行为执行SELECT fuzzBits(hello, 0.1)多次确认结果随机且第二参数超出[0,1]时返回明确报错DISTINCT 正确性对已知含重复候选行的查询执行SELECT DISTINCT比对去重前后计数时区数据SELECT toTimeZone(toDateTime(2020-11-01 01:30:00), America/New_York)等边界时间戳的转换结果应遵循 2020d 规则。六、小结v20.9.7.11-stable 是 ClickHouse v20.9 分支上一个高质量的低风险补丁版本1 项性能改进显著缓解了Merge表跨海量子表的查询开销17 项 Bug Fix 覆盖了 MySQL 协议兼容影响行数上报、连接恢复、查询正确性DISTINCT重复行、ORDER BY优化、Set 索引失效、稳定性ColumnConst比较、JOINLowCardinality、copier 段错误、WAL 恢复、mutation 挂起以及客户端体验多行注释时区数据同步升级到 2020d。文中涉及的多数修复项在 当前源码 中均可找到对应实现或演进痕迹可供进一步深入阅读。对于正在使用 v20.9 稳定版的部署建议在回归验证后尽快应用本版本以获得上述正确性与稳定性收益。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考