ClickHouse v24.5 版本全解析:从 Dynamic 类型、UUIDv7 到全文本索引迁移的实践指南
【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse
导读
本文基于 ClickHouse v24.5.1.1763-stable 的官方 Changelog 整理而成。v24.5 是 ClickHouse 2024 年度的重要稳定版本,带来了Dynamic 动态类型、UUIDv7 时间戳型 UUID 函数族、嵌入式 RocksDB 批量导入、S3 归档文件查询等一批影响深远的新特性,同时通过"inverted indexes"更名"full-text indexes"引入了必须人工介入的向后不兼容变更。读完本文,你将系统掌握 v24.5 的升级注意点、新函数与新增配置的使用方法、性能优化手段,以及该版本修复的关键 Bug 清单,可直接用于升级评估与生产实践。
一、升级必读:向后不兼容变更(Backward Incompatible Change)
v24.5 引入了三项影响既有集群行为的变更,升级前必须逐条核对。
1.1 "inverted indexes" 更名为 "full-text indexes"
将面向开发者的技术术语inverted indexes(倒排索引)更名为更友好的full-text indexes(全文索引)。由于内部表元数据随之改变,该变更会破坏所有已存在的实验性 inverted indexes 表。官方要求:
- 升级前:
DROP INDEX删除此类索引; - 升级后:重新创建索引。
1.2 四个函数被标记废弃
neighbor、runningAccumulate、runningDifferenceStartingWithFirstValue、runningDifference这四个函数因易用错、语义容易产生误导而被废弃(deprecated)。官方建议改用标准窗口函数(window functions)实现同类需求。若确有兼容需要,可显式设置allow_deprecated_functions=1恢复使用。注意:该设置在后续版本中进一步更名为allow_deprecated_error_prone_window_functions(参见 changelog 中的Rename allow_deprecated_functions to allow_deprecated_error_prone_win...条目)。
1.3 system.columns 权限语义收紧
当列数量很多、且大量数据库/表未授予SHOW TABLES权限时,system.columns查询会更快。但行为上有重要变化:
- 旧版本:对单个列授予
SHOW COLUMNS(即使未对对应表授予SHOW TABLES),system.columns仍会显示这些列; - 新版本:将整体跳过整张表。
同时移除了拖慢查询的 trace 日志 "Access granted" / "Access denied"。
二、新特性(New Feature)深度解读
2.1 Dynamic 动态类型:一张表装下任意类型
v24.5 引入Dynamic数据类型,允许在不知道全部类型的情况下存储任意类型的值,相当于列级别的多态容器。该类型需通过设置allow_experimental_dynamic_type开启(源码中可见其随版本演进为MAKE_OBSOLETE状态,即新版默认放开的实验特性)。该特性为后续 JSON 类型、Variant 类型等灵活 schema 能力奠定了基础,尤其适合半结构化日志、动态事件数据的存储场景。
2.2 UUIDv7 函数族与 UUID 工具函数
这是本版本最受关注的函数类新特性,实现在 src/Functions/generateUUIDv7.cpp 中,新增函数包括:
| 函数 | 说明 |
|---|---|
generateUUIDv7() | 生成标准版本 7 UUID(基于 RFC 9562),带单调计数器 |
generateUUIDv7ThreadMonotonic() | 线程内单调版本,性能与单调性折中 |
generateUUIDv7NonMonotonic() | 非单调版本,性能优先 |
UUIDToNum() | 提取 UUID 的原始字节 |
UUIDv7ToDateTime() | 提取 UUIDv7 中的时间戳分量 |
从源码看实现细节非常值得注意:
- 位布局(见 src/Functions/UUIDv7Utils.h):UUIDv7 由 48 位
unix_ts_ms时间戳 + 4 位版本号ver+ 42 位计数器(counter_high_bits 12 位 + counter_low_bits 30 位)+ 2 位 variant 标记 + 62 位随机分量rand_b组成; - 性能技巧:
clock_gettime(CLOCK_REALTIME, ...)按数据块(chunk)而非每条记录调用一次,在满足 UUID 标准的前提下减少系统调用开销; - 并发保证:通过
SharedMutex+ 静态计数器字段(CounterFields)保证同一时间戳内跨线程生成的 UUID 计数器单调; - 确定性:
isDeterministic()返回false,并且支持传入一个可选表达式参数(generateUUIDv7(expr))以绕过公共子表达式消除(CSE),避免查询中多次调用返回相同值。
典型用法:
SELECT generateUUIDv7(number) FROM numbers(3); -- ┌─generateUUIDv7(number)───────────────┐ -- │ 019947fb-5766-7ed0-b021-d906f8f7cebb │ -- ... -- 提取时间戳 SELECT UUIDv7ToDateTime(generateUUIDv7());2.3 StorageEmbeddedRocksDB 批量导入(SST Bulk Loading)
为嵌入式 RocksDB 存储引擎引入批量加载:通过直接创建并摄入 SST 文件,绕开 RocksDB 内置 memtable,显著提升导入速度,尤其对长时运行的 INSERT效果明显。同时新增了StorageEmbeddedRocksDB表级设置项。注意该特性在 v24.5 开发期间经历过一次 Revert 后重新合入(changelog 的 NO CL ENTRY 部分可见Revert "Introduce bulk loading to StorageEmbeddedRocksDB"及其后续合并),最终以 #63324 的版本正式发布。
2.4 S3 存储与归档文件查询
S3 磁盘和s3表函数现在支持直接遍历 S3 上的归档文件(如 tar 等格式)内部的文件进行查询,解决了此前无法从归档中选数的痛点,对日志归档分析场景价值明显。
2.5 非等值 JOIN 条件
支持涉及左右两表列的非等值连接条件,例如t1.y < t2.y。启用方式:
SET allow_experimental_join_condition = 1;该设置在源码 src/Core/SettingsChangesHistory.cpp 中也有记录,属于实验性开关。
2.6 新的输入/输出格式与解析能力
- Form 格式:支持读写单条
application/x-www-form-urlencoded编码记录; - npy 输出格式:支持输出 NumPy
.npy格式(相关测试覆盖了不同字节序); - TSV 解析 CRLF:新增设置
input_format_tsv_crlf_end_of_line(定义于 src/Core/FormatFactorySettings.h),解决 Windows 风格 CRLF 行结束符的 TSV 解析问题; - 强制 NULL 填充:新增设置
input_format_force_null_for_omitted_fields(同样定义于 FormatFactorySettings.h),对省略字段强制写入 NULL 而非默认值; - Raw 格式别名:
Raw成为TSVRaw的同义词。
2.7 CROSS JOIN 优化与压缩
- 支持在 CROSS JOIN 中进行压缩,新增
cross_join_min_rows_to_compress(默认 10000000 行)与cross_join_min_bytes_to_compress(默认 1 GiB)两个设置,定义于 src/Core/Settings.cpp,当结果规模超过阈值时启用压缩; - CROSS JOIN 结果超出内存限制时,可溢出到临时文件继续执行。
2.8 新增 clamp 条件函数
支持条件函数clamp(将值限制在 [min, max] 区间内),实现位于src/Functions目录。
2.9 STDOUT 重定向自动压缩
在 Linux/macOS 上,若程序 STDOUT 被重定向到带压缩扩展名的文件,将自动采用对应压缩方法(行为与INTO OUTFILE一致),例如clickhouse-client --query "SELECT 1" > out.gz会直接产出 gzip 压缩文件。
2.10 Azure Workload Identity 认证
s3/AzureBlobStorage 相关表函数与配置支持use_workload_identity参数,可直接使用 Azure Workload Identity 对 Azure Blob Storage 进行认证,适配 Azure 托管应用场景。
三、性能改进(Performance Improvement)
v24.5 的性能优化覆盖面广,值得在生产环境中验证收益:
| 优化点 | 内容 | 备注 |
|---|---|---|
| 投影(Projection)块合并跳过 | INSERT 期间跳过新创建投影块的合并 | 提升写入吞吐 |
| UTF8 字符串函数 ASCII 快路径 | 输入全为 ASCII 时按"asciily"处理,整体提速 1.07x~1.62x,部分场景峰值内存下降 | 实现于src/Functions |
| StorageS3 选择 glob 性能 | 改进{}选择通配符的处理 | |
| 新排序合并配置 | 新增prefer_merge_sort_block_bytes,控制多列合并排序时的内存与速度,最多可提速 2 倍 | |
| clickhouse-local 启动加速 | 修复此前未删除临时目录的问题,启动更快 | |
| 新分析器微优化 | 针对 analyzer 的微优化 | |
| DateTime 与 DateTime64 索引分析 | DateTime与DateTime64比较时索引分析生效 | 对应修复 #63441 / #63532 |
| set 类型索引加速 | 去掉垃圾数据后 set 索引约提速 1.5 倍 | |
| 文件系统缓存 | 减少缓存竞争(第 4 部分),允许通过keep_free_space_size(_elements)_ratio做后台额外驱逐 |
其中prefer_merge_sort_block_bytes特别适合列数多、内存受限的合并排序场景;system.columns的权限检查优化则在大集群运维中收益明显。
四、常规改进(Improvement)
4.1 数据类型与函数
- Map 键类型扩展:
Float32、Float64、Array(T)、Map(K,V)、Tuple(...)均可作为 Map 的键; - groupArray 大小限制:新增
aggregate_function_group_array_has_limit_size设置,可在特定场景丢弃部分数据以避免内存膨胀(后续版本更名为group_array_has_limit_size); - Keyed hashing 函数:修复 Array 与 Map 配合 Keyed 哈希函数及物化键的支持。
4.2 配置与运维
- YAML Merge Key 支持:配置可引用 YAML 锚点合并(
<<:),并支持从 YAML 文件进行配置替换(substitution); - Replicated 库自动恢复:若某个 DDL 任务连续失败超过
max_retries_before_automatic_recovery(默认 100 次)且错误相同,自动将该副本标记为 lost 并启动恢复,同时修复了早期异常可能跳过 DDL 条目的问题; max_block_size=0自动纠正为默认值;- plain_rewritable 元数据:本地与 Azure 对象存储启用
plain_rewritable元数据格式,S3 场景可通过endpoint_subpath设置共享同一 endpoint; - 对象存储磁盘支持 TRUNCATE;
- MaterializedMySQL:允许在未连接 MySQL 的情况下创建数据库;
- INSERT 尾随逗号:
INSERT INTO test (a, b, c, ) VALUES ...现在合法; - Values 格式尾随逗号:
VALUES (4, 5, 6,)现在合法; - Pretty 格式:stdout 非 TTY 时禁用
output_format_pretty_max_rows/output_format_pretty_max_value_width限制;多行字符串边框保留、列宽正确计算(忽略 ANSI 转义序列); - Unicode 引号支持:查询中出现英文风格 Unicode 引号(如 “Hello”、‘world’)时自动兼容,方便从 Word 等文档复制 SQL。
4.3 查询与客户端体验
- clickhouse-local 位置参数:
clickhouse/ch可直接把查询或查询文件作为位置参数,例如ch "SELECT 1"、ch --param_test Hello "SELECT {test:String}"、ch query.sql; - 客户端建议:
os_user与client_hostname现在能在命令行建议中正确设置; - skim 建议:选择建议后保留终端原有数据;
- 进度条:
system.zeros/system.zeros_mt与generateRandom表函数的简单 LIMIT 查询也有进度条,且总记录数超过max_rows_to_read时提前抛异常。
4.4 存储与对象存储
system.parts_columns增加 TTL 信息;trace_log增加build_idALIAS 列,便于检测二进制变更后自动改名;- Azure Blob 备份改用 multi-copy,并支持跨容器原生 copy(native copy);
System.remote_data_paths相关并发删除场景的健壮性增强。
五、构建/测试/打包改进(Build/Testing/Packaging)
- 编译器升级:ClickHouse 改由clang-18构建,启用大量 clang-tidy-18 新检查;
- 新平台:实验性支持loongarch64;重新启用 s390x CI 构建;aarch64 Linux 交叉编译启用 gRPC;
- Apache Datasketches 库更新;
- CI 符号数据库:每个构建的每个编译单元的符号信息收集到 CI 数据库(
binary_symbols表),便于二进制问题定位; - Dockerfile 通过 docker 官方镜像库审查(对应 upstream docker-library 的 #15846)。
六、Bug 修复与稳定性(Bug Fix & Critical Bug Fix)
6.1 关键修复(数据正确性 / 崩溃类)
- 多分片备份修复:修复多分片场景下备份失败的问题(#56566);
- FINAL 查询错误结果:表未使用自适应粒度时
FINAL查询给出错误结果; - FINAL 与分布式查询:修复非 MergeTree 表远程查询带
final=true时错误抛出 "Storage doesn't support FINAL"; - Window 函数与优化器:
query_plan_remove_redundant_distinct在新分析器下破坏 WINDOW 函数查询(#62820);新分析器禁止 WINDOW 重定义(#63539); - GROUPING SETS:
GROUPING SETS+WHERE+group_by_use_nulls=true组合的逻辑错误(#60538); - 并行副本:并行副本读取物化视图导致错误查询结果;
skip_unused_shards=1+LIMIT BY+ 新分析器时的 "Not found column"; - 分布式查询:修复罕见分布式查询结果缺数据、递归 CTE 分布式查询、常量 CTE 在 GROUP BY 键中报 "Cannot find column" 等问题;
- 查询缓存权限绕过:查询缓存现在区分不同数据库中的相同查询,避免绕过缺表读取权限(安全修复,backported);
- enable_vertical_final 默认关闭:该设置因存在数据错误 Bug(#64543)被默认禁用(Critical Bug Fix,backported #64591);
- 并行读缓冲卡死:
max_download_thread > 0时线程无法分配导致查询卡死; - SIGSEGV 修复:CPU/Real profiler(
query_profiler_real_time_period_ns/query_profiler_cpu_time_period_ns)自 2022 年以来的偶发崩溃(尤其在分布式引擎下);aarch64 上 SIGSEGV 信号栈过小的 unwind 崩溃。
6.2 格式与解析修复
- Parquet:分析器下 Parquet filter pushdown 失效修复;
- KQL 表函数:交互模式下客户端中止问题修复;
- 二进制反序列化加固:不可信二进制输入以更安全方式反序列化;
- HTTP 无效压缩数据:改抛
CANNOT_DECOMPRESS而非CORRUPTED_DATA; - Regexp 格式:异常信息更友好。
6.3 存储与复制修复
- MergeTree 转 Replicated 校验:若 zookeeper 中该表路径已存在则禁止转换(该修复后续曾 Revert,见 NO CL ENTRY 条目,需以最终发布版本行为为准);
- 部分相交处理:DROP range 重启后相交 part 修复;
- cgroups v2 检测:异常位置的 cgroups v2 内存控制器检测改进;
- Lazy 数据库 DROP:确保 DROP 后所有磁盘数据被清理,避免孤儿文件;
- Buffer 表 PREWHERE:修复
Logical error: Bad cast(#64172)。
6.4 Keeper / 客户端修复
- keeper-client 的
find_super_nodes/find_big_family修复(ZNONODE 处理、超节点内查找、子树节点计数); - Keeper 忽略
text_log配置。
七、v24.5 升级与验证清单
综合以上变更,给出面向生产的升级建议清单:
- 检查 inverted indexes:升级前
SHOW INDEX排查并删除实验性倒排索引,升级后按新语法重建为 full-text index; - 审计废弃函数:全局搜索
neighbor、runningAccumulate、runningDifference等调用,替换为窗口函数(lag、runningAccumulate替代方案等);若短期无法替换,临时SET allow_deprecated_functions = 1; - 核对权限模型:确认依赖
system.columns且未授予SHOW TABLES的账户是否有查询依赖,避免升级后列不可见; - 评估新特性收益:对 S3 归档、RocksDB 批量导入、UUIDv7 主键、Dynamic 类型等新能力做小规模验证后再推广;
- 关注回归风险点:
enable_vertical_final已默认关闭,若此前手动开启需评估数据正确性影响;query_plan_remove_redundant_distinct对 window 查询的破坏已修复,但升级后建议跑一遍涉及 WINDOW 的回归测试; - 跟踪 backport:本 changelog 中多个修复标注了 "Backported in #xxxxx",说明在后续补丁版(如 v24.5.x 后续 patch)中继续跟进,生产环境应升级到包含这些 backport 的最新补丁版。
八、从 Changelog 到源码的阅读指引
- UUIDv7 完整实现与文档示例:src/Functions/generateUUIDv7.cpp、位布局与计数器并发控制见 src/Functions/UUIDv7Utils.h;
- 格式相关设置定义:src/Core/FormatFactorySettings.h(
input_format_tsv_crlf_end_of_line、input_format_force_null_for_omitted_fields); - CROSS JOIN 压缩阈值设置:src/Core/Settings.cpp(
cross_join_min_rows_to_compress默认 10000000、cross_join_min_bytes_to_compress默认 1 GiB); - 实验特性开关演进:src/Core/SettingsChangesHistory.cpp(
allow_experimental_join_condition、allow_experimental_dynamic_type等); - 服务端配置模板:programs/server/config.xml,客户端配置参考 programs/client/config.xml;
- 完整历史 Changelog 归档:docs/changelogs/ 目录,可对照查看 v24.4、v24.3 LTS 等相邻版本的行为差异。
总而言之,ClickHouse v24.5 是一个"新能力密集、升级动作明确"的版本:Dynamic 类型与 UUIDv7 为 schema-less 与分布式 ID 生成提供了官方级方案,S3 归档查询与 RocksDB 批量导入显著降低了特定场景的 IO 成本,而全文本索引更名与四函数废弃则要求升级前做好索引重建与 SQL 改写规划。结合本仓库的源码与配置实现,可以快速验证并落地这些能力。
【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考