
ClickHouse v22.3.13.80-lts 版本解析Ordinary→Atomic 自动转换机制与 LTS 安全修复全景【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse本文基于官方 changelog 归档文档 docs/changelogs/archive/v22.3.13.80-lts.md逐条解读 ClickHouse 2022.3.13.80 LTS 版本相对于 v22.3.12.19-lts 的全部变更包括Ordinary数据库引擎向Atomic的自动转换机制、Kafka 引擎消费者数量限制开关等新特性以及十余项涉及内存安全、查询正确性、S3 远程存储与数据持久化的修复。读完本文你将理解每项变更背后的源码实现与调用链并据此判断生产环境是否需要升级到该 LTS 补丁版本。一、版本定位一个 LTS 补丁发布包含什么该 changelog 的标题格式为ClickHouse release v22.3.13.80-lts (e2708b01fba) as compared to v22.3.12.19-lts (4a08f8a073b)其中e2708b01fba与4a08f8a073b分别是新旧版本的提交哈希前缀-lts后缀表明这是 22.3 长期支持分支上的一个补丁发布。changelog 中所有条目均带有 “Backported in #XXXXX” 前缀说明这些改动最初合入 master 分支随后被回合backport到 22.3 LTS 分支——这正是 LTS 分支的典型运作方式不引入新功能开发只挑选已验证的修复与少量新特性回移保证补丁发布的稳定性。该版本共包含2 项新特性数据库引擎自动转换、Kafka 消费者数量限制开关1 项函数内存安全修复encrypt/contingency1 项打包改进deb 包source字段15 项“用户可见的 stable 行为 bug 修复”1 项“官方 stable 发布中的用户可见错误行为”修复if函数类型问题一批标注为 “NOT FOR CHANGELOG” 的 CI/构建类内部改动。二、新特性一Ordinary → Atomic 数据库引擎自动转换2.1 特性用法changelog 原文描述Implemented automatic conversion of database engine fromOrdinarytoAtomic. Create emptyconvert_ordinary_to_atomicfile inflagsdirectory and allOrdinarydatabases will be converted automatically on next server start. Resolves #39546. (#39933)操作方式非常直接在 ClickHouse 数据目录path配置项指向的位置下的flags/目录中创建一个空文件convert_ordinary_to_atomic然后重启服务器。下一次启动时所有Ordinary引擎的数据库除system外都会被自动转换为Atomic引擎。之所以需要这个特性是因为Ordinary引擎存在根本性的缺陷它不使用detached/软链接机制、不支持数据库级别的DROP DATABASE级联删除、元数据以单个.sql文件平铺存放无法安全支撑ATTACH/DETACH等运维操作而Atomic引擎通过 UUID 软链接管理元数据是此后 ClickHouse 推荐的默认引擎。该特性为存量用户提供了“一次重启完成迁移”的通道无需手工逐库逐表RENAME。2.2 源码级实现解析从当前仓库源码结构看该机制在后续版本中延续并演进核心逻辑集中在 src/Interpreters/loadMetadata.cpp1启动流程中的转换入口。loadMetadata.h 中声明了convertDatabasesEnginesIfNeed注释明确其职责“如果convert_ordinary_to_atomic标志存在就把所有数据库除 system 外从 Ordinary 转换为 Atomic并等待load_metadata任务完成后再执行转换”。实现见 loadMetadata.cpp#L593-L615流程为检查flags/convert_ordinary_to_atomic文件是否存在不存在则直接返回打印日志 “Found convert_ordinary_to_atomic file in flags directory, will try to convert all Ordinary databases to Atomic”waitLoad等待所有表加载并启动完毕——这是关键前提转换必须发生在元数据完整加载之后避免半加载状态下改名遍历除system外的所有数据库逐个调用maybeConvertOrdinaryDatabaseToAtomic全部完成后删除标志文件fs::remove(convert_flag_path)并移除DB_ORDINARY_DEPRECATED警告。也就是说标志文件是“一次性触发器”转换成功即被删除若转换中途失败标志文件仍在重启时还会重试同时会触发下文的失败检测逻辑。2转换的原子化手段临时库名。转换并非原地改名而是先把Ordinary库重命名为带前缀的临时名ORDINARY_TO_ATOMIC_PREFIX前缀的tmp库再在新建Atomic库上逐表RENAME TABLE迁移。这一设计使得即使中途崩溃原始数据也不会丢失。3不完整转换的检测。loadMetadata.cpp#L149-L185 的checkIncompleteOrdinaryToAtomicConversion负责识别“上一次转换中断”的现场若发现带特殊前缀的数据库名残留说明转换被打断会抛出NOT_IMPLEMENTED异常并给出手工补救指引——在config.xml中添加allow_reserved_database_name_tmp_convert强制启动然后手动RENAME TABLE迁移剩余表、DROP DATABASE临时库并RENAME DATABASE恢复原名。同样的兜底提示也出现在单库转换失败的异常信息中loadMetadata.cpp#L574-L581。4system 库的特殊处理。maybeConvertSystemDatabaseloadMetadata.cpp#L584-L591会在未开启allow_deprecated_database_ordinary设置时无条件尝试把system库也转为Atomicsystem数据库因此成为首个完成迁移的库为后续全库转换提供验证。2.3 使用建议执行前先备份元数据目录metadata/下的.sql文件转换过程涉及大量RENAME选择低峰期重启转换期间数据处于已加载状态但转换任务在启动阶段同步执行若启动失败并报“Found a database with special name”按异常提示的RENAME TABLE/DROP DATABASE/RENAME DATABASE三步手动收尾切勿直接删除临时库。三、新特性二关闭 kafka_num_consumers 上限的开关3.1 特性用法changelog 描述Add setting to disable limit on kafka_num_consumers. Closes #40331. (#40670)该特性引入会话级/表级设置kafka_disable_num_consumers_limit布尔值默认false允许用户突破kafka_num_consumers与 CPU 核心数挂钩的上限约束。3.2 源码级实现在 src/Core/Settings.cpp 中可以看到该设置的声明Settings.cpp#L6406-L6408DECLARE(Bool, kafka_disable_num_consumers_limit, false, R( Disable limit on kafka_num_consumers that depends on the number of available CPU cores. ), 0)与之配合的 Kafka 引擎侧逻辑位于 src/Storages/Kafka/StorageKafkaUtils.cpp其中定义了“无论kafka_disable_num_consumers_limit如何设置都会强制生效的绝对上限”说明该开关解除的是与 CPU 核心数挂钩的软限制而非无约束放大消费者数。Kafka 表引擎的设置项kafka_num_consumers默认1声明于 src/Storages/Kafka/KafkaSettings.cpp官方用法文档说明总消费者数不应超过 topic 分区数每个分区只能分配一个消费者也不应超过服务器物理核心数——这正解释了为何默认要有核心数上限以及为何高吞吐场景需要显式解除该限制。适用场景当单表 Kafka 消费吞吐不足、且分区数与机器核数都远大于默认消费者数时可为该表设置kafka_disable_num_consumers_limit 1并配合较大的kafka_num_consumers提升消费并行度。需要注意消费者数量增大带来的 Kafka broker 端连接压力与 ClickHouse 侧内存开销。四、安全与内存安全类修复这一组修复全部涉及 C 层的内存安全对长期运行的分析集群尤其重要encrypt/contingency的 Nullable Array 内存安全#40195当ArrayofNullable作为参数时这两个函数存在内存安全问题。以encrypt为例其实现位于 src/Functions/encrypt.cpp支持aes-128-ecb/cbc/ofb/gcm/ctr/cfb等模式调用签名为encrypt(mode, plaintext, key[, iv, aad])。若你的业务涉及对可空数组列做批量加解密升级该版本是必要的。恶意 Native 格式数据可致崩溃#41441Native 格式反序列化未充分校验的恶意输入可能触发崩溃。凡是 ClickHouse 实例会读取不受信任来源的 Native 流如跨实例数据搬运、外部服务投递的场景务必升级。categorialInformationValue空指针解引用#41449该聚合函数属性定义不正确运行时可能空指针解引用。Apache ORC 写出的缓冲区越界#41458以 ORC 格式导出数据时可能发生 buffer overrun。聚合函数组合器combinators的段错误与 use-after-free#41083关闭 #40848-State/-Merge等组合器实现的内存泄漏与 use-heap-after-free 修复重聚合函数使用较多的管道建议升级验证。五、查询正确性修复这一组直接影响查询结果的正确性属于“必须升级”类别if函数的类型推断错误#35476关闭 #35367归类为 stable 版本用户可见错误当if的结果列类型与结果数据类型不一致时会抛出类似Logical error: Bad cast from type DB::ColumnVectorint to DB::ColumnVectorlong的逻辑错误。凡依赖if(cond, a, b)做多分支返回且分支类型不完全一致的 SQL 都应受影响。子查询OFFSET 外层WHERE返回错误结果#41280修复 #40416OFFSET子句位于子查询、WHERE位于外层查询的组合可能返回错误行集——这是典型的分页过滤语义错误影响报表类查询的准确性。WITH语句引入未使用的未知列#39131修复 #37812WITH ... AS展开时可能把未使用的别名当作未知列处理。JoinSwitcher 中 Nullable 的 LowCardinality 强制转换错误#37453关闭 #37385Join 执行器JoinSwitcher对可空低基数列的 cast 修复影响涉及LowCardinality(Nullable(...))键列的 Join 查询。带OFFSET查询的pipeline stuck异常#41588修复 #41383当enable_optimize_predicate_expression 0且WHERE条件恒为 false 时OFFSET查询可能触发 pipeline stuck升级后消除该边界组合的挂起风险。Merge表 optimize_monotonous_functions_in_order_by崩溃#41740修复 #41269对该设置开启状态下SELECTfromMerge表的潜在崩溃修复。MsgPack 格式 UUID 插入前缺少列类型检查#41309向 UUID 列插入 MsgPack 数据前先做类型校验避免错误数据落库。simdjson依赖更新#38838修复 #38621JSON 解析库升级带来 JSON 解析正确性修复。六、存储引擎与远程存储S3修复这组修复集中解决可靠性问题对使用对象存储或高频合并的部署尤为关键MergeTree 列级 TTL 垂直合并竞态#40346重复的 vertical merge 场景下可能报Cannot unlink file ColumnName.bin ... No such file or directory.。这是列 TTLALTER TABLE ... MODIFY COLUMN ... TTL与垂直合并并发操作数据文件的竞态升级后可避免合并报错与 Part 损坏风险。WriteBufferFromS3任务调度失败时的潜在死锁#40070写入 S3 的缓冲管道在任务调度失败分支上可能死锁表现为写 S3 表长时间无响应。AWS SDK 缺陷导致的数据丢失#40506对应 aws/aws-sdk-cpp#658仅在使用 S3 作为存储后端时可能触发。这是上游 SDK 的 bugClickHouse 侧通过升级/规避修复——任何 S3 后端部署都应把此项视为最高优先级。无查询上下文的 Materialized View 写入内存泄漏#40732从 Kafka 等引擎 push 数据到无 query context 的 MV 时存在内存泄漏Kafka → MV 管道长跑场景必须升级。Proxy resolver 首次成功即停止#40353多 endpoint 场景下代理解析器在首个成功请求后即固定该 endpoint减少故障探测的重复开销。七、构建、测试与打包改进deb 包新增source字段并更新nfpm#41531打包链路从nfpm工具生成 deb 时补充source字段改善包管理系统对源码关联的识别。“NOT FOR CHANGELOG” 内部改动#40067、#40421、#40502、#40831、#41256、#41328、#41431、#41457、#41474、#41567、#41769包括 CI token 使用方式、DNSResolver 移除AI_V4MAPPED/AI_ALL标志、Artifactory 迁移、Docker 镜像版本号、backport 构建复用 ccache、代码清理移除-WithTerminatingZero方法与Field冗余代码、日志脱敏Mask some information in logs以及 latest 镜像仅从 master 构建等。这些条目不面向终端用户但其中日志脱敏#41474与 DNS 解析行为变化#40502会间接影响线上日志与域名解析行为排障时值得留意。八、升级决策清单结合 changelog 内容与上述源码佐证给出面向生产环境的判断依据场景是否建议升级到 v22.3.13.80-lts关键条目S3 对象存储作为数据盘强烈建议AWS SDK 数据丢失修复#40506、WriteBufferFromS3 死锁#40070Kafka 接入 物化视图管道强烈建议MV 内存泄漏#40732、消费者限制开关#40670存量Ordinary引擎数据库建议Ordinary→Atomic 自动转换#39933对外暴露、读取外部 Native/JSON 数据强烈建议Native 恶意数据崩溃#41441、simdjson 更新#38838使用if/OFFSET/WITH的复杂报表查询建议查询正确性修复组#35476、#41280、#39131、#41588使用列级 TTL 的 MergeTree 表建议垂直合并竞态#40346所有条目的原始依据以 docs/changelogs/archive/v22.3.13.80-lts.md 为准文中引用的源码文件为当前仓库中该机制的延续实现可用于理解各修复的落点模块数据库加载与转换见 src/Interpreters/loadMetadata.cpp设置定义见 src/Core/Settings.cppKafka 引擎见 src/Storages/Kafka/StorageKafkaUtils.cpp加密函数见 src/Functions/encrypt.cpp。由于当前仓库源码对应的是更新的主线版本行号与具体实现细节可能已演进但模块归属与机制设计保持一致。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考