
ClickHouse v20.9.1.4585-prestable 版本深度解析TTL 合并控制、view 表函数与 20.9 新特性全览【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse本文基于 ClickHouse 仓库中的 v20.9.1.4585-prestable 发布说明 展开逐条拆解这一预发布版本中引入的向后不兼容变更、新特性、性能优化、改进与缺陷修复并结合仓库源码验证其底层实现。读完本文你将掌握 20.9 中 TTL 合并并发控制、view表函数、apply语法、微秒级查询起始时间等关键能力的用法、原理与升级注意事项可用于实际的版本评估与平滑升级规划。该版本发布说明以 v20.8.1.4513-prestable 为对比基线是 20.9 系列早期的 prestable预稳定构建。虽然其中部分条目仍以 FIXME 标注、个别条目内容待补充但整体变更清单已经完整覆盖存储引擎、表函数、日志系统、聚合函数、集成组件与构建体系等多个层面是观察 20.9 系列演进方向的良好切入点。一、向后不兼容变更TTL 合并的并发控制20.9 系列最重要的兼容性信号是新增了两个用于控制后台 TTL 合并并发度的 MergeTree 设置max_replicated_merges_with_ttl_in_queueReplicatedMergeTree 复制队列中允许同时存在的 TTL 合并任务数。max_number_of_merges_with_ttl_in_pool后台合并池中 TTL 合并条目数超过该值时不再分配新的 TTL 合并以便为常规合并保留空闲线程、避免 Too many parts 问题。这两个设置定义在 MergeTreeSettings.cpp 中类型均为UInt64默认值分别为1与2。从源码注释可以确认其设计意图前者约束 How many tasks of merging parts with TTL are allowed simultaneously in ReplicatedMergeTree queue复制队列中同时允许的 TTL 合并任务数后者则说明 When there is more than specified number of merges with TTL entries in pool, do not assign new merge with TTL当池中 TTL 合并条目超过指定数量时不再分配新的 TTL 合并。在 StorageReplicatedMergeTree.cpp 中可以看到实际判断逻辑只有当前队列中已排队的 TTL 合并数小于max_replicated_merges_with_ttl_in_queue时复制副本才会允许新的 TTL 合并任务入队从而在复制场景下对 TTL 合并的并发度做统一收敛。兼容性影响与升级建议发布说明明确指出仅当使用 delete TTL删除型 TTL时该变更才会与旧版本产生复制协议不兼容否则复制保持兼容。换句话说如果表只使用 TTL 做数据过期删除那么新老版本之间可能出现复制队列中的 TTL 合并条目无法被旧版本识别/执行的情况。官方给出的规避手段有两种一次性升级全部分片副本使集群内所有节点处于同一协议版本无法一次性升级时先在所有副本上执行SYSTEM STOP TTL MERGES暂停 TTL 合并直到全部副本升级完成。如果在升级过程中复制队列中已经出现不兼容的 TTL 合并条目发布说明给出的恢复步骤是SYSTEM STOP TTL MERGES; ALTER TABLE ... DETACH PARTITION ...; -- 摘除被分配了不兼容 TTL 合并的分区 -- 在单个副本上重新 ATTACH 该分区 ALTER TABLE ... ATTACH PARTITION ...;即先停掉 TTL 合并将包含不兼容 TTL 合并任务的分区 DETACH 后在单个副本上 ATTACH 回来以消除队列中的坏条目。这条操作路径在实际生产升级中具有直接参考价值。二、新特性从查询书写到统计能力的全面扩展1.view表函数把子查询变成可传递的表对象20.9 新增表函数view其作用是把一个子查询包装成表参与后续查询便于把查询当作对象四处传递。发布说明给出的典型用法是嵌套在remote/cluster表函数中使用SELECT * FROM cluster(cluster_name, view(SELECT ...));从源码看该功能注册于 TableFunctionView.cpp 与 registerTableFunctions.cppregisterTableFunctionView与registerTableFunctionViewIfPermitted被同时注册。TableFunctionView::parseArguments通过ASTFunction::tryGetQueryArgument()从函数参数中取出SELECT子查询并克隆保存若缺少查询参数则抛出BAD_ARGUMENTS异常Table function view requires a query argument。getActualTableStructure则根据是否启用新分析器分别调用InterpreterSelectQueryAnalyzer::getSampleBlock或对应的旧解释器路径推导视图的结果结构从而让view(...)在任何需要表对象的位置都可以完成列结构推导。在 StorageDistributed.cpp 中也能看到该表函数被用于构建分布式查询引用说明view从一开始就面向remote/cluster/distributed等跨节点查询场景设计。2.apply语法对整列集合批量应用函数发布说明引入了apply高阶语法允许对多列统一应用某个函数并支持链式叠加。原文示例SELECT * apply(length) apply(max) FROM wide_string_table;该语句会先对wide_string_table的所有字符串列逐一执行length再对结果集做max从而一次性求出所有字符串列的最大长度。发布说明同时提示该语法还提供另外两种变体形式可通过后续文档与测试进一步确认具体形式这一语法显著简化了对宽表所有列做同一种变换的书写成本也减少了需要手写多列表达式的样板代码。3.system.query_log与system.query_thread_log新增微秒级起始时间system.query_log与system.query_thread_log系统表新增query_start_time_microseconds字段将查询起始时间精确到微秒。在 QueryLog.cpp 中可以看到该列被定义为DateTime64(6)类型Start time of query execution with microsecond precision并在 QueryLogElement.h 中与time_t query_start_time秒级并列存储Decimal64 query_start_time_microseconds。日志落盘时QueryLog.cpp 会将秒级起始时间写入ColumnUInt32、微秒级时间写入ColumnDateTime64。这一字段的价值在于当同一秒内并发查询较多、需要精确排序或进行亚秒级耗时分析时微秒级时间戳可以避免秒级精度造成的排序歧义查询线程日志query_thread_log同步获得该字段也便于将线程级事件与查询级时间线精确对齐。4. 聚合函数RankCorrelationSpearman斯皮尔曼秩相关系数新增聚合函数RankCorrelationSpearman用于计算两列样本的斯皮尔曼秩相关系数是 Issue #11769内部继承StatisticalSampleFloat64, Float64核心算法流程为分别对两组样本调用computeRanksAndTieCorrection计算秩rank及并列校正取两样本数量的较小值作为有效样本量size因为 NaN 会被跳过两侧样本量可能不等计算秩差平方和d^2套用公式1 - 6 * Σd² / (n * (n² - 1))得到最终系数。该函数在 registerAggregateFunctions.cpp 中完成注册适用于相关性分析、特征筛选等统计场景与既有的corr皮尔逊形成互补。5. 按查询生成数据库的工具发布说明还提到新增了database generation by query util按查询生成数据库的工具这是 Issue #10973 的延续。该工具面向需要依据查询模式反推/构造数据库结构的测试与基准场景与仓库中的查询生成、模糊测试设施配合使用。三、性能优化分布式查询的 LIMIT / ORDER BY 下推本次性能改进聚焦分布式查询在同时开启optimize_skip_unused_shards与optimize_distributed_group_by_sharding_key的前提下对使用GROUP BY sharding_key的分布式查询优化了LIMIT、LIMIT BY、ORDER BY的处理使得这类查询可以更早地在分片侧完成排序与裁剪减少传输到协调节点的数据量。这一优化对基于分片键做聚合 排序 限量取数的典型报表查询有明显收益。四、改进项从集成组件到内部机制1. 流式/集成引擎的健壮性与能力增强StorageRabbitMQ大幅重构包括连接与通道故障处理、正确的提交commit语义、插入失败处理、更完善的 exchange 配置、队列持久化与队列恢复resume能力并新增队列相关设置同时修复了相应测试。Kafka 引擎为每个 consumer 提供独立线程并为 Kafka 等流式引擎引入独立的线程池以提升消费吞吐与并行度。Redis 引擎/字典新增 Redisrequirepass授权支持允许连接启用密码保护的 Redis 实例。2. 数据类型与类型系统DateTime 精度参数为DateTime类型增加精度precision参数支持与DateTime64对齐了声明方式便于统一表达亚秒精度时间。宽整数实现替换将 wide integers 从 boost multiprecision 替换为 cerevra/int 的实现对应 PR #14229减少对 boost 的依赖并改善 Int128/Int256 等类型的编译与运行效率。MaterializeMySQL 主键隐式非空与 MySQL 行为保持一致隐式将主键列转换为 NOT NULL修复 Issue #14114 中主键可为空导致的问题。3. 系统表与观测性system.part_log新增default_compression_codec列记录 data part 的默认压缩编码codec便于排查各 part 实际使用的压缩配置。新设置system_events_show_zero_values控制system.events以及相关事件表是否展示值为 0 的事件默认关闭可保持输出精简开启后可完整看到全部事件计数。该设置已在 StorageSystemEvents.cpp 与 Settings.cpp 中实现。obfuscator 支持 UUID 类型脱敏工具programs/obfuscator现在可以处理 UUID 类型数据解决 Issue #13163。4. 查询执行细节并行构建多组 JOIN / IN 集合为包含多个不同IN subquery的查询并行创建集合可略微提升此类查询的性能。TTL 在合并时物化如果 TTL 此前未被物化materialize现在会在合并过程中应用 TTL减少后台独立 TTL 任务的排队压力也与第一节的 TTL 并发控制形成配套。MySQL 协议处理SET var valueMySQL 处理端对SET var value语句直接返回OK并忽略执行。这是因为部分 MySQL 驱动在握手后会用SET 查询做环境初始化Issue #9336此前会导致兼容性问题。禁止toStartOf*系列函数使用空时区参数空time_zone参数现在会直接报错避免静默产生错误结果。S3 请求关闭加速存在进行中的 S3 请求时服务关闭流程提速缩短停机时间。ConfigProcessor 路径拼接改用std::filesystem::path跨平台拼接配置文件路径更稳健PR #14558。五、Bug 修复亮点20.9.1.4585-prestable 修复了一批涉及执行引擎与存储安全的问题其中几个值得特别关注arrayJoin()在 lambda 中被捕获导致 LOGICAL_ERROR修复了arrayJoin在 lambda 表达式内部使用时的错误捕获问题。GRANT ALL非全局层级执行错误修复了在非全局non-global层级执行GRANT ALL时的行为涉及权限系统 PR #13987。禁止在ALIAS列上声明CODEC明确拒绝在 ALIAS 列上指定压缩编码避免无效配置修复 Issue #13911。SSD cache 复合键外部字典的元组大小校验对 SSD cache 场景下 complex key 外部字典的 tuple 大小做更严格的检查修复 Issue #13981。EXPLAIN PIPELINE graph1的 QueryPlan 生命周期修复嵌套解释器场景下 QueryPlan 提前析构导致的问题。ALTER LIVE VIEW ... REFRESH异常修复执行该语句时抛出的异常。对AS table_function创建的表执行ALTER崩溃修复对由表函数创建的表执行 ALTER 时的崩溃修复 Issue #14212。PipelineExecutor自身异常导致查询挂起当异常发生在 PipelineExecutor 内部时立即停止查询执行防止偶发的查询挂起PR #14334 及后续补全 PR #14402。单 part 分区的错误合并分配修复表存在单 part 分区时合并任务分配错误的问题避免产生错误的数据 part 组合。SysVinit 服务指令代理到 systemd若系统使用 systemd则 SysVinit 的 restart/start/stop/reload 会代理到 systemd保证服务管理行为一致。topK聚合函数数组大小溢出检查增加topK的数组大小溢出校验。发布说明特别提示此前用户可构造精心设计的参数导致服务崩溃Issue #14452这是一个安全隐患修复。六、构建 / 测试 / 打包改进集成测试改用默认基础配置集成测试不再依赖隐式配置所有配置变更通过main_configs、user_configs、dictionaries参数显式声明测试环境与生产环境的行为差异更可控。backport 脚本逻辑修正修复了此前对任何 100% 红色 label 都会触发的异常逻辑。修复缺失的#include atomic消除特定编译环境下因头文件缺失导致的编译失败。为 clang 11 构建做准备提前适配新编译器。降低 debug 构建体积移除Functions目录的调试信息以减小 debug 二进制体积该调整主要服务于使用旧链接器的内部项目。cmake 默认启用 ccache系统检测到 ccache 时默认开启显著加速重复构建。七、升级与验证建议综合该发布说明升级到 20.9 系列从 20.8 基线时建议按以下顺序规划确认 TTL 使用情况若存在 delete TTL 表优先安排全分片一次性升级否则先在升级窗口执行SYSTEM STOP TTL MERGES升级完成后恢复。验证新字段与设置升级后抽查system.query_log.query_start_time_microseconds是否为合法的DateTime64(6)数据确认system_events_show_zero_values、system.part_log.default_compression_codec等新观测能力按预期工作。回归流式引擎若使用 Kafka/RabbitMQ/Redis 集成重点回归消费、提交与断线重连路径因为这些组件在 20.9 中改动较大Kafka 独立消费者线程、RabbitMQ 连接/提交重构、Redis 授权。关注安全性修复topK溢出、GRANT ALL权限、PipelineExecutor挂起等修复涉及安全与稳定性建议优先跟进。八、参考资源v20.9.1.4585-prestable 发布说明原文MergeTree 设置定义含 TTL 合并并发设置ReplicatedMergeTree TTL 合并入队判断view 表函数实现 与 表函数注册query_log 微秒级起始时间字段RankCorrelationSpearman 实现system_events_show_zero_values 相关实现说明发布说明中标注为 FIXME 的标题与以 ... 占位的条目如 PR #14523 与 PR #14368在正式版发布时会有更完整的描述本文所引用的设置默认值、字段类型与算法细节均以当前仓库源码为准。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考