ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

ClickHouse v21.6.1.6891-prestable 版本解析:新特性、性能优化与关键修复全览

2026/9/12 16:37:56 拓冰建站 浏览量
ClickHouse v21.6.1.6891-prestable 版本解析:新特性、性能优化与关键修复全览 ClickHouse v21.6.1.6891-prestable 版本解析新特性、性能优化与关键修复全览【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse本文以 ClickHouse 官方变更日志 docs/changelogs/archive/v21.6.1.6891-prestable.md 为骨架系统梳理 v21.6.1.6891-prestable 相对 v21.5.1.6601-prestable 的新增功能、性能改进、行为优化、Bug 修复与构建测试改进并结合当前仓库源码逐一佐证实现原理帮助读者理解这些变更背后的设计意图与实战影响。版本概览ClickHouse v21.6.1.6891-prestable 是 2021 年 6 月发布的 prestable预发布版本官方版本号位于 21.6 系列早期对标 v21.5.1.6601-prestable。作为 21.6 系列的开端该版本承载了大量标志性能力MergeTree 投影Projection支持、postgres 风格::类型转换运算符、大整数Big Integers生产就绪、EXPLAIN系列增强等为后续 21.6 正式版奠定了功能基调。从变更日志分类看该版本包含 20 项 New Feature、3 项 Performance Improvement、44 项 Improvement、51 项 Bug Fix、16 项 Build/Testing/Packaging Improvement以及若干杂项变更。下文将按变更日志的原始分类逐一展开。新特性查询能力与存储层的双向拓展MergeTree 家族正式支持投影ProjectionMergeTree*系列表引擎新增投影支持PR #20202这是该版本最重量级的能力之一。投影允许在表内预计算并物化聚合结果或排序视图查询优化器可在命中投影时跳过全表扫描直接读取预聚合数据是 ClickHouse 应对大宽表与聚合查询性能的核心机制之一。从仓库源码看投影相关支持贯穿了解析、存储与优化多个环节例如 src/Storages/MergeTree/registerStorageMergeTree.cpp 中的表引擎注册逻辑以及 src/AggregateFunctions/Combinators/AggregateFunctionDistinct.h 等聚合组合器对投影物化状态的兼容处理。该版本同时修复了投影在分布式处理Fix distributed processing when using projection与 ReplicatedMergeTreeFix add projection to replicated mergetree上的配套问题说明投影功能在 21.6 已进入实质可用阶段。回归函数 indexHint索引调优的调试利器indexHint函数在本版本重新引入PR #21304用于修复此前移除后的回归issue #9540、#21238。该函数忽略其参数并恒返回1参数不会被真正求值。核心用途是索引分析在WHERE indexHint(expr)中优化器按expr进行索引区间选择但不会按该条件逐行过滤。在 src/Functions/indexHint.cpp 的函数文档中明确说明ClickHouse 的索引是稀疏的indexHint会返回比直接指定条件更多的数据因此它不是性能优化手段而是用于调试和理解索引行为——回答我的条件选中了哪些 granule、多少行、索引是否被有效使用这类问题。例如SELECT * FROM t WHERE indexHint(key 123)会返回整个可能含目标行的 granule默认约 8192 行中的所有行而非仅匹配行。新聚合函数 sumCount一次计算同时得到和与计数新增聚合函数sumCountPR #21337接受单参数并返回(sum, count)二元组。其实现位于 src/AggregateFunctions/AggregateFunctionSumCount.cpp类AggregateFunctionSumCount直接继承自AggregateFunctionAvgT复用其累加状态——分子numerator即sum分母denominator即count结果以Tuple(sum, count)形式输出。从源码看该函数支持(U)Int*、Float*、Decimal*等数值类型并且一个重要设计意图是供查询优化器使用当一条查询中同时出现多个sum、count或avg时可通过optimize_syntax_fuse_functions设置将它们融合为单个sumCount以复用计算对应实现见 src/Analyzer/Passes/FuseFunctionsPass.cpp。因此正常情况下用户很少需要显式调用它。函数文档中的示例CREATE TABLE s_table (x Int8) ENGINE Log; INSERT INTO s_table SELECT number FROM numbers(0, 20); INSERT INTO s_table VALUES (NULL); SELECT sumCount(x) FROM s_table; -- ┌─sumCount(x)─┐ -- │ (190,21) │ -- └─────────────┘新聚合函数 deltaSumTimestamp支持乱序合并的差值求和deltaSumTimestampPR #21888用于对按时间戳排序的连续行之间的差值求和负差值被忽略。它比普通deltaSum多接受一个timestamp参数并在聚合状态中记录首尾行的原始时间戳从而在分区part合并时仍能按正确顺序还原差值序列。其实现位于 src/AggregateFunctions/AggregateFunctionDeltaSumTimestamp.cpp状态结构包含sum、first、last、first_ts、last_ts与seen标志。merge逻辑通过before(lhs, rhs)比较两个状态的时间戳区间来决定拼接顺序见源码第 94-104 行从而保证物化视图分区合并后结果一致。该函数的典型场景是按时间桶对齐的物化视图例如数据按toStartOfMinute聚合存储后桶内所有行共享同一时间戳合并时无法还原原始顺序而deltaSumTimestamp通过保留原始未取整时间戳解决了这一问题。函数文档源码第 255-264 行给出了示例SELECT deltaSumTimestamp(value, timestamp) FROM (SELECT number AS timestamp, [0, 4, 8, 3, 0, 0, 0, 1, 3, 5][number] AS value FROM numbers(1, 10)) -- ┌─deltaSumTimestamp(value, timestamp)─┐ -- │ 13 │ -- └─────────────────────────────────────┘该函数同时被标记为is_order_dependent true即对输入顺序敏感因此使用时应确保按时间戳有序输入或依赖其内部时间戳排序机制。arrayProduct 与 splitByRegexp数组与字符串函数的补强arrayProductPR #22242/#23782接受数组参数返回所有元素的乘积对应实现位于 src/Functions/array/arrayAggregation.cpp。splitByRegexpPR #24077按正则表达式将字符串拆分为数组实现见 src/Functions/splitByRegexp.cpp。注意它更适用于re2正则语义与splitByString的纯字符串拆分形成互补。postgres 风格类型转换运算符::新增::运算符PR #23871使类型转换语法更贴近 PostgreSQL 习惯。例如[1, 2]::Array(UInt8)、0.1::Decimal(4, 4)、number::UInt16均合法。其词法与解析支持位于 src/Parsers/Lexer.cpp、src/Parsers/ExpressionElementParsers.cpp 与 src/Parsers/ExpressionListParsers.cpp从源码结构看::与既有的CAST(x AS T)走同一套类型转换管线属于语法糖级别的扩展。EXPLAIN 可视化增强JSON 输出与索引使用情况EXPLAIN PLAN新增json设置默认关闭PR #23082开启后查询输出为单行 JSON官方建议配合TSVRaw格式避免转义噪声。EXPLAIN PIPELINE新增indexes设置默认关闭PR #22352开启后展示每个索引实际使用情况——使用的索引、被过滤的 part 与 granule 数量仅适用于MergeTree*表。这两项能力让执行计划的调试从看文本升级为看结构化数据。字典 DDL 能力的大幅扩展该版本大幅扩展了字典管理能力PR #23436基于 issue #22354DatabaseMemory 支持 DDL 字典新增DETACH DICTIONARY PERMANENTLYAtomic 数据库引擎新增EXCHANGE DICTIONARIES新增RENAME DICTIONARY支持跨数据库移动字典。存储与数据源相关的其他新特性URL 表函数支持{...}通配符类似分片与|分隔的故障转移选项PR #23446issue #17181。insert_null_as_default设置当值为1时INSERT ... SELECT及INSERT ... SELECT ... UNION ALL ...查询中将以默认值替换 NULLPR #23524issue #22832。该设置在 src/Interpreters/InterpreterInsertQuery.cpp 与 src/Core/Settings.cpp 中注册解析。表注释Table Comments支持为表添加注释PR #23548issue #23225。SYSTEM QUERY RELOAD MODEL(S)新增重载 CatBoost/机器学习模型的管理命令PR #23182issue #18722。S3 场景新增安全性较低的 IMDS 凭据提供者解决 Docker 环境下的凭据获取问题PR #21852。system.stack_trace新增thread_name列PR #24124issue #23256便于定位具体线程的堆栈。LocalServer 进度条统一了clickhouse-client与clickhouse local的进度条体验PR #23196。大整数Big Integers生产就绪PR #23631 是 21.6 的重要里程碑新增UInt128数据类型修复Decimal256已知问题并让大整数全面进入生产路径——字典、gcd/lcm函数、数组搜索、条件函数、generateRandom表函数与clickhouse-obfuscator均获得支持同时支持LowCardinality(UUID)并修复标量子查询返回 UUID 的错误。需要注意的是该 PR 包含一个向后不兼容变更UUID类型不再能与整数比较。例如原先的uuid ! 0必须改写为uuid ! 00000000-0000-0000-0000-000000000000。升级涉及 UUID 比较语义的读者应重点核对。性能改进默认开启表达式编译该版本最值得关注的性能变更是默认启用compile_expressions设置PR #8482。开启后简单函数与运算符的组合将在运行时通过 LLVM 编译为原生代码显著降低表达式求值的解释开销。其余性能改进包括ORC 输入按 stripe 读取PR #23102不再一次性将整个文件读入内存降低大文件场景的内存峰值。re2 库升级PR #24196正则匹配性能提升同时带来 gcc-11 编译兼容性。行为改进稳定性、运维与兼容性网络与分布式写入的健壮性S3 增加 HTTP 连接断开重试PR #22988。写入分布式表时跳过不可用副本PR #23152。max_distributed_connections误配为 0 的兜底PR #23348此前会抛出带 logical error 字样的异常并触发 CI 逻辑错误检查现在将其按最小值 1 处理。禁用use_hedged_requests与async_socket_for_remotePR #23261后又于 PR #23683 重新默认启用async_socket_for_remote反映该版本对远程异步套接字的反复调优过程。存储与表引擎改进S3 磁盘支持SYSTEM RESTART DISK命令PR #23429允许运行时修改 S3 磁盘设置而无需重启服务器。S3 磁盘可将 MergeTree part 恢复到detached目录PR #23112。S3 存储与磁盘新增region参数PR #23846。_partition_value虚拟列PR #23673MergeTree 家族新增确定性分区裁剪虚拟列为 mutation 的分区匹配器提供基础实现见 src/Storages/MergeTree/MergeTreeVirtualColumns.cpp。ReplacingMergeTree 支持 DateTime64 版本列PR #23992同时ORDER BY WITH FILL支持DateTime64PR #24016。Buffer 引擎优化PR #24066/#24067/#24068total_bytes/total_rows不加锁关库前先刷 Buffer 表避免底层表已 detached 导致数据块被丢弃字典生命周期延长至存储关闭之后。MySQL 引擎支持空数据库名PR #23319空字符串将回退到默认数据库便于对接 Sphinx 等 MySQL 兼容外部库。MaterializeMySQL 兼容 MySQL 5.7.9PR #23413。查询语义与类型行为保持默认时区PR #23392issue #4854对无时区的DateTime做算术运算后返回类型不再被显式加上默认时区而变为DateTime(...)而保持无时区DateTime类型。prefer_column_name_to_alias扩展PR #24022值为 1 时对GROUP BY、HAVING、ORDER BY同样优先使用列名而非别名。compile_expressions默认开启对结果无影响但需关注执行计划变化。可观测性与日志不同日志通道可配置不同日志级别PR #23857issue #19569对应实现与 programs/server 的日志配置体系一致。system.distribution_queue新增broken_data_files/broken_data_compressed_bytesPR #23885并新增指标BrokenDistributedFilesToInsert统计异步插入被标记为损坏的文件数。字典新增found_rate命中率指标PR #23916记录值在字典中被找到的百分比可从system.dictionaries查看。服务器启动时记录 OS 名称、内核版本与 CPU 架构PR #23988。http字典源支持 HTTP 压缩PR #23946依据Content-Encoding头自动解压。其他行为改进quantile(s)TDigest修复PR #23314按 tdunning/t-digest 3.2 规范特殊处理单例中心点并修复旧版本实现的中心点过度压缩问题。默认禁用min_bytes_to_use_mmap_ioPR #23322降低 mmap I/O 带来的潜在风险。Arrow/Parquet/ORC 格式支持 Array 类型读写PR #21770。Enum名称输入提示PR #23916/#23919issue #17112。hashed/sparse_hashed 字典支持预分配PR #23979。postgresql 字典源支持指定表结构 schemaPR #23980issue #23958。RabbitMQ 表引擎增强PR #23887支持rabbitmq_queue_settings_list表设置、rabbitmq_queue_consume仅连接不建队列/交换机的模式以及删表时的资源清理。zstd 升级至 v1.5.0PR #24135。simdjson 内存分配失败崩溃修复PR #24147。Bug 修复稳定性问题的系统收敛该版本修复的 51 个 Bug 覆盖了崩溃、数据正确性、分布式一致性与外部集成四大类。崩溃与内存安全修复关闭时currentConnections()可能返回 0 而连接仍存活导致的崩溃PR #23154。修复async_socket_for_remote开启时收到未知包导致的崩溃PR #23309issue #21167。修复 HDFS 在查询执行中不可达导致的服务器异常终止PR #24191issue #24117。修复PREWHERE与行级安全策略同时生效且结果为空时的崩溃PR #23763。修复 HDFS 使用Values格式读取时的heap_use_after_freePR #23761。修复MergeJoin崩溃PR #24013issue #24010。修复外部 GROUP BY 与溢出行组合max_bytes_before_external_group_by0、max_rows_to_group_by0、group_by_overflow_modeany、totals_modebefore_having时的 SIGSEGVPR #23962。修复带 const 条件更新嵌套列导致的服务崩溃PR #24183附有min_bytes_for_wide_part 0的复现 DDL。修复 RBAC 高负载下的竞态条件PR #24176issue #24090、#24134。数据正确性修复 ReplacingMergeTree 垂直合并的罕见边界问题PR #23459此前可能触发Incomplete granules are not allowed while blocks are granules size异常。修复MODIFY COLUMN ... DEFAULT修改 ReplacingMergeTree 版本列如ReplacingMergeTree(b) ORDER BY a后ALTER TABLE ... MODIFY COLUMN b DEFAULT now()时因版本列类型检查空指针导致的段错误PR #23483。修复argMin/argMax对单Tuple参数的支持PR #23393该实现存在内存安全问题已被移除。修复deltaSum在计数器重置场景的聚合错误PR #23437。修复空数组字面量到多维数组的 cast 问题PR #23456issue #14476。修复主键列或其单调函数配合COLLATE的ORDER BY在optimize_read_in_order开启时结果错误PR #23375issue #22379旧版本可用关闭该设置规避。修复ORDER BY使用COLLATE时列在主键中的排序错误。修复LOWCardinality在join_use_nulls下的可空性支持PR #23237issue #15101。修复UNION查询在 filter-push-down 优化后可能出现的Block structure mismatchPR #23359issue #23029。修复基于虚拟列做分区裁剪时生成了不兼容常量表达式的问题PR #23366。修复分区裁剪时过度放宽 NOT 条件PR #23310issue #23305、#21539。修复CLEAR COLUMN被物化视图引用时无效PR #23781issue #23764。修复now64()支持可选时区参数PR #24091。修复 WHERE 中 constDateTime与DateTime64列比较的问题PR #24100。分布式与复制一致性修复 ReplicatedMergeTree 创建/删除之间的罕见分布式竞态PR #23294issue #21419可能表现为node doesnt exist。修复背景清理旧块时的罕见竞态导致去重窗口末尾的块未被去重PR #23301。修复 stale 副本在宕机期间错过ALTER元数据更新的恢复问题PR #23742。修复ALTER PARTITION引发的Part A intersects previous part B与Unexpected merged part C intersecting drop range D复制队列错误PR #23997issue #23296。修复分布式插入时可能的Cannot schedule a taskPR #23744。修复distributed_group_by_no_merge2与聚合函数包裹进普通函数时的组合问题并为窗口函数场景抛出异常、禁用optimize_distributed_group_by_sharding_keyPR #23906。修复多磁盘配置下 ReplicatedMergeTree 创建失败时的Cannot unlink filePR #23433issue #21755。修复optimize_skip_unused_shards_rewrite_in的类型转换问题PR #23219。修复可部分初始化却可服务写入请求的表现在此类表会进入只读模式PR #24122。外部集成与格式修复禁用input_format_with_names_use_header时 CSVWithNames 全部输入被丢弃的问题PR #23202issue #22406。修复MaterializeMySQL中键列带条件查询时的Not found columnPR #23200issue #22432。修复columns()函数在多 join 查询中的错误PR #23501issue #22736。修复Join与WITH TOTALS的 bugPR #23549issue #17718。修复dict join在join_algorithm auto下的问题PR #23312issue #23002。修复 JDBC bridge 超时问题PR #23771issue #9609。修复 PostgreSQL 引擎连接池实现PR #23909issue #23897。修复 CACHE() 字典源含重复键时的键指标统计溢出DictCacheKeysRequestedMissPR #23929。修复 HashedDictionary 复合键更新字段的初始加载PR #23824issue #23800。修复简单键 DDL 字典在主键非首属性时的创建问题PR #23262issue #23236。Kafka 存储新增 ParquetPR #23412、Arrow/ArrowStreamPR #23415消息格式支持。修复PocoHTTPClient对含符号 URI 的处理PR #23822并改进 HTTP 错误响应体的处理PR #23844。修复 HTTP 插入触发异常导致的服务器故障PR #23643issue #23512。修复LIKE表达式转义序列的误解析PR #23610。修复mannWhitneyUTest两个样本完全相同时缺少异常处理PR #23654issue #23646。修复重启/停止命令挂起PR #23552issue #20214。修复StorageMemory的拼写错误PR #24193issue #24192。修复带SELECT ... FINAL的EXPLAIN PIPELINE显示错误管线PR #24116。构建、测试与打包改进可复现构建移除构建的非确定性来源PR #23559避免构建对 locale 与文件系统顺序的依赖PR #23600使不同时间点构建产生字节一致的二进制。平台扩展支持 Solaris 衍生系统PR #23746与 IllumosPR #24144构建。显式启用异步展开表asynchronous-unwind-tablesPR #23602可能修复 AArch64 上的 query profiler。TestFlows 并行化支持并行运行所有 TestFlows 模块PR #23942新增 Map 类型PR #21087、DateTime64 扩展范围PR #22729、窗口函数PR #23704测试。keeper-bench新增 [Zoo]Keeper 基准测试工具PR #23038对应仓库中的 programs/keeper-bench。依赖升级librdkafka 1.6.0-RC3 → 1.6.1PR #23874。哈希表基准扩充新增 Google Swiss Table 等更多哈希表基准PR #24111。CMake 修复-DENABLE_CASSANDRAOFF -DENABLE_AMQPCPPON组合下的配置失败PR #22984。杂项与其他变更自动化 backport根据 PR 的release标签判定目标发布分支PR #23363。uniqThetaSketch更名为uniqThetaPR #24019issue #14893Theta Sketch 支持见 PR #22609/#23894此重命名属于 API 收敛。数组函数测试补充为arrayElement新增测试用例PR #23484issue #22765。若干NO CL ENTRY与NOT FOR CHANGELOG类别的杂项合并与回滚包括arrayFold、min_bytes_to_use_mmap_io相关 RFC、uniqThetaSketch等功能的回滚记录以及大量 CMake 清理、代码风格与 PVS-Studio 静态告警修复。升级注意事项小结综合本版本变更升级到 v21.6 系列时建议重点关注以下几点UUID 与整数比较的移除PR #23631uuid ! 0之类的写法必须改为与全零 UUID 字符串比较。argMin/argMax单 Tuple 参数被移除PR #23393若业务依赖该写法需改用替代方案。compile_expressions默认开启PR #8482表达式执行路径发生变化理论上加速但若遇到与 LLVM 编译相关的异常可通过显式关闭该设置规避。min_bytes_to_use_mmap_io默认关闭PR #23322依赖 mmap 读取大文件的场景行为发生变化。use_hedged_requests/async_socket_for_remote在 21.6 系列内经历禁用又启用的反复生产环境建议结合自身网络状况验证。uniqThetaSketch更名为uniqThetaPR #24019若在代码或查询中使用旧名称需同步更新。上述变更的具体 SQL 行为均可在当前仓库的 tests/queries 目录中找到对应回归测试佐证而各功能的实现源码分别位于 src/Functions、src/AggregateFunctions、src/Storages、src/Interpreters 与 src/Parsers 等目录读者可按需深入。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考