
ClickHouse v26.1.12.23-stable 版本深度解读HTTP 预认证加固、S3 请求可观测性与 15 项稳定性修复【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse本篇文章基于 docs/changelogs/v26.1.12.23-stable.md 官方变更日志围绕 ClickHouse 2026 年 1 月发布的稳定版 v26.1.12.23-stablecommite5aa07a1b9a相对 v26.1.11.9-stable/1784404a5ac展开。文章将完整解析该版本引入的 1 项向后不兼容变更、1 项新特性、2 项改进与 15 项用户可见 Bug 修复并逐条结合仓库源码与配置实现帮助运维与开发人员评估升级风险、合理配置新参数并理解底层修复原理。一、版本总览一次以安全加固 可观测性为主题的稳定版v26.1.12.23-stable 是 26.1 分支的补丁稳定版改动可归纳为三条主线安全与资源保护收缩 HTTP 预认证阶段的头部解析上限、新增头部读取总时限、限制 TCP 握手中 Hello 包字符串长度并新增handshake_timeout_milliseconds服务端配置从 HTTP 与 TCP 两侧共同压缩未认证连接即可占用内存/线程的攻击面可观测性为 S3 GET 请求新增两个直方图指标接入system.histogram_metrics系统表与 Prometheus 端点正确性与稳定性覆盖合并算法、JSON 列 min-max 索引、S3Queue、ClusterDiscovery、Dynamic 类型序列化、轻量删除后的查询优化、Parquet 统计信息等多个模块的缺陷修复。整体上该版本以修复与加固为主不引入新的 SQL 语法或存储格式变更适合在充分回归后平滑升级。二、向后不兼容变更HTTP 预认证内存占用加固升级必读这是本版本中唯一标注为Backward Incompatible Change的改动对应 PR#103285直接关系到所有通过 HTTP 接口访问 ClickHouse 的客户端。2.1 默认值变化配置项旧默认值新默认值说明http_max_fields1,000,0001,000HTTP 请求头部、查询参数与表单数据中允许的最大字段数量http_max_field_name_size128 KB4 KB单个字段名的最大长度http_max_field_value_size128 KB128 KB不变单个字段值的最大长度http_max_request_header_size无新增10 MB所有 HTTP 请求头部名称与值合计的总大小上限http_headers_read_timeout无新增30 秒读取全部 HTTP 请求头部的总时限新默认值在源码中可查证src/Core/Settings.cpp 中的定义DECLARE(UInt64, http_max_fields, 1000, R( Maximum number of fields in HTTP request headers, query parameters, and form data.), 0) DECLARE(UInt64, http_max_field_name_size, 4 * 1024, R( Maximum length of a field name in HTTP request headers, query parameters, and form data.), 0) DECLARE(UInt64, http_max_field_value_size, 128 * 1024, R( Maximum length of a field value in HTTP request headers, query parameters, and form data.), 0) DECLARE(UInt64, http_max_request_header_size, 10 * 1024 * 1024, R( Maximum total size of all HTTP request headers (names and values combined) in bytes.), 0) DECLARE(Seconds, http_headers_read_timeout, 30, R( Maximum time in seconds to read all HTTP request headers. This is a total deadline for the entire header parsing phase, not a per-read timeout. Protects against slowloris-style attacks where a client trickles header data slowly to hold connections open.), 0)2.2 变更动机与实现该改动的核心目的是限制预认证阶段的内存占用。在 HTTP 连接完成认证之前服务端必须先解析请求头部与表单字段旧默认值允许单个连接携带高达 100 万字段、单字段名 128 KB恶意或异常客户端可以用极小的网络流量触发服务端为其分配数百 MB 内存。从实现上看头部解析会构造 src/Server/HTTP/HTMLForm.cpp 中的表单对象并分别读取三个上限: max_fields_number(settings[Setting::http_max_fields]) , max_field_name_size(settings[Setting::http_max_field_name_size]) , max_field_value_size(settings[Setting::http_max_field_value_size])与之配套http_max_request_header_size从总量维度兜底http_headers_read_timeout总时限而非单次读超时则专门防御slowloris 式慢速攻击——攻击者以极低速率逐字节发送头部长期占用连接与线程。2.3 如何恢复旧行为官方变更日志明确指出Users who rely on the previous higher limits can restore them via settings. 若你的客户端如自定义 HTTP 长连接、携带大量 URL 查询参数或超大 Cookie 的网关触发新限制可通过三种方式恢复旧值方式一查询级别SET 语句SET http_max_fields 1000000; SET http_max_field_name_size 131072; SET http_max_request_header_size 10485760;方式二HTTP 请求 URL 查询参数单次请求生效curl http://localhost:8123/?querySELECT%201http_max_fields1000000http_max_field_name_size131072方式三服务端配置文件全局生效在config.xml的profilesdefault段中profiles default http_max_fields1000000/http_max_fields http_max_field_name_size131072/http_max_field_name_size http_max_request_header_size10485760/http_max_request_header_size http_headers_read_timeout30/http_headers_read_timeout /default /profiles⚠️ 运维提示恢复高上限会重新暴露该版本试图修复的预认证内存风险建议仅在确认客户端确实需要且配合网关层头部白名单的情况下执行并优先考虑收紧http_headers_read_timeout以保留 slowloris 防护。三、新特性S3 GET 请求直方图指标本次新增两个直方图指标对应 PR#102058用于观测 S3 GET 请求的连接生命周期与字节消耗s3_read_request_duration_microsecondsS3 读请求连接从发起请求到连接关闭的持续时间微秒s3_read_request_bytes每个 S3 读请求连接上读取的字节数。3.1 指标定义与桶bucket设置指标在 src/Common/HistogramMetrics.cpp 中注册预置桶如下Metric S3ReadRequestDuration Factory::instance().registerMetric( s3_read_request_duration_microseconds, Duration of S3 read request connections, from request initiation to connection close, in microseconds., {1000, 10000, 50000, 200000, 500000, 1000000, 2000000, 5000000, 10000000, 60000000}); Metric S3ReadRequestBytes Factory::instance().registerMetric( s3_read_request_bytes, Bytes read per S3 read request connection., {4096, 65536, 262144, 1048576, 4194304, 8388608, 16777216, 33554432, 67108864, 268435456});3.2 查询与接入方式指标可通过两个入口观测入口一system.histogram_metrics系统表SELECT metric, buckets, values FROM system.histogram_metrics WHERE metric IN (s3_read_request_duration_microseconds, s3_read_request_bytes);入口二Prometheus 端点默认http://host:9363/metrics或/metrics自定义路径直方图以_bucket累加计数、_sum与_count的形式暴露可直接用于 Grafana 面板或告警通过s3_read_request_duration_microseconds判断 S3 GET 连接耗时分布定位慢请求或连接复用异常通过s3_read_request_bytes观察单连接读取量辅助评估缓冲/预取策略与带宽占用。3.3 适用场景该指标面向使用 S3 作为冷热分层存储DiskS3、s3()表函数或 S3Queue 引擎的部署。结合已有的S3ReadRequestsCount、S3ReadRequestsErrors、S3ReadRequestsThrottling、S3ReadRequestsRedirects等 ProfileEvents见 src/IO/S3/PocoHTTPClient.cpp可以建立请求量 错误量 耗时分布 字节量的完整 S3 观测矩阵。四、常规改进线程内存与网络带宽4.1system.stack_trace暴露每线程 untracked_memorysystem.stack_trace系统表现在额外展示每个线程的untracked_memory未被跟踪器统计的堆内存字段对应 PR#103065。该字段能帮助定位实际内存占用与MemoryTracker统计偏差的场景——例如某些第三方库或裸malloc分配未计入查询级配额排查内存超限与 OOM 时可直接按线程维度对比跟踪值。4.2 带宽限制扩展至远程文件系统读写max_network_bandwidth_for_user与max_network_bandwidth_for_all_users现在同样作用于远程文件系统的读取与写入对应 PR#103080。此前这两个设置主要约束网络传输如分布式查询的中间结果而本次将其语义扩展到 S3/对象存储等远程存储的 I/O 路径使多租户场景下可以对用户/全局的远程存储吞吐进行统一限速避免单一用户占满存储带宽影响其他查询。五、Bug 修复全解15 项用户可见缺陷以下 15 项修复全部为 user-visible misbehavior in an official stable release 级别的回归修复按主题归类如下。5.1 查询正确性类JSON 列 min-max 索引使用错误极值PR#101918关闭 issue#101700JSON 列上创建的 min-max 索引使用了错误的 extremas导致查询返回错误结果。修复后索引极值计算与列语义一致涉及 JSON 列的过滤查询应重新验证结果一致性。时区调整溢出导致日期类型推断错误PR#102674关闭 issue#102601时间戳在时区调整后发生溢出时Date类型被错误推断。修复涉及日期类型的自动推断路径受影响的是跨时区的DateTime/Date混用查询。min-max count 投影与COUNT(*)优化在轻量删除后永久失效PR#102900执行一次轻量删除lightweight delete后即使所有带删除掩码的 part 都已 merge 完成minmax_count_projection与平凡COUNT(*)优化仍被永久禁用性能损失持续存在。修复后当带掩码的 part 全部合并消失相关优化自动恢复。5.2 稳定性与崩溃类合并算法在懒列复制下崩溃PR#101036当enable_lazy_columns_replication开启且ColumnReplicated列进入带迟到输入的 merge-sort 管道时触发Logical error: isConst/isSparse/isReplicated assertTypeEquality崩溃。合并OPTIMIZE/后台合并期间可能触发修复涉及合并管道的列类型断言逻辑。并发建表导致 S3Queue LOGICAL_ERRORPR#102610Shared database 上多个并发CREATE TABLE IF NOT EXISTS指向同一 S3Queue 表时抛出LOGICAL_ERROR。修复后并发 DDL 行为符合IF NOT EXISTS语义。ClusterDiscovery 在静态集群无存活节点时抛服务端异常PR#102661配置中定义的静态集群短暂无存活节点时ClusterDiscovery 逻辑抛出未处理的服务器异常可能导致发现线程异常退出。5.3 S3 / 对象存储类S3 请求以ios_base::clear: unspecified iostream_category error失败且不重试PR#102894根因是 Poco 的BufferedStreamBuf::flushBuffer未处理 socket 层的短写short write导致请求直接报错而非走重试路径。修复后短写被正确识别S3 请求恢复自动重试能力对网络抖动场景的韧性明显提升。5.4 安全与防护类HMAC SQL 函数隐藏密钥PR#102997修复 issue#102927HMAC函数的密钥不再在错误消息/日志中明文泄露避免敏感凭据通过查询错误信息外泄。TCP 预认证 Hello 包加固PR#103284未认证客户端发送的 Hello 包中各字符串client name、default db、user、password、signature、quota key 等长度上限被限制为64 KB同时新增服务端配置handshake_timeout_milliseconds。源码见 src/Server/TCPHandler.cppstatic constexpr size_t MAX_HELLO_STRING_SIZE 64 * 1024; // ... readStringBinary(client_name, *in, MAX_HELLO_STRING_SIZE); readStringBinary(default_db, *in, MAX_HELLO_STRING_SIZE); readStringBinary(user, *in, MAX_HELLO_STRING_SIZE); readStringBinary(password, *in, MAX_HELLO_STRING_SIZE);配套的handshake_timeout_milliseconds默认 30,000 ms即 30 秒定义在 src/Core/ServerSettings.cpp它是整个 TCP 握手阶段Hello Addendum的墙钟总时限限制未认证连接占用线程的时间设置为0可关闭DECLARE(UInt64, handshake_timeout_milliseconds, 30000, R( Wall-clock timeout in milliseconds for the entire TCP handshake phase (Hello Addendum). Limits how long an unauthenticated connection can hold a thread. Set to 0 to disable.), 0)在 src/IO/ReadBufferFromPocoSocket.cpp 中实现超时判定握手耗时超过阈值即抛出异常断开连接。这项修复与 HTTP 侧收紧遥相呼应共同封堵未认证即可消耗服务端资源的攻击路径。5.5 内存与资源管理类重新引入 ArrowMemoryPool 以避免内核 OOMPR#102999恢复 Arrow 内存池的接入使 Arrow 格式处理在内存超限时抛出MEMORY_LIMIT_EXCEEDED而不是放任分配直至触发内核 OOM。对使用format: Arrow/Parquet导入导出大文件的场景服务端内存管理更加可控。普通 INSERT 不再过度申请 ConcurrencyControl 槽位PR#102961没有物化视图的普通 INSERT 此前会按max_threads而非max_insert_threads申请并发控制槽位与线程在高吞吐 INSERT 集群上造成 CC 槽位饥饿与线程数激增。修复后按max_insert_threads申请显著改善并发写入场景的资源调度。5.6 格式与类型处理类Dynamic 类型扁平化序列化修复PR#102692关闭 issue#101911修复扁平化flattenedDynamic 类型在使用二进制编码数据类型时的序列化错误。Native 格式中畸形扁平化 Dynamic 数据检查PR#103392读取 Native 格式时对畸形扁平化 Dynamic 数据增加校验避免解析异常。Parquet ColumnIndex 字符串列统计 min_value max_valuePR#103334修复 ParquetColumnIndex统计信息中 String 列出现min_value大于max_value的问题此前可能导致基于统计的谓词下推产生错误结果。url表函数填充_time列PR#103437url()表函数现在会正确填充虚拟列_time取自 HTTP 响应的 Last-Modified 等时间信息使 URL 数据源可以直接按时间过滤。六、构建 / 测试 / 打包改进升级 xz 至 5.8.3PR#102607打包依赖xz更新到 5.8.3涉及压缩/解压库的版本同步官方构建产物二进制包、压缩包均基于新版本生成。CI禁用 backport 分支的自动合并PR#103160属于 NOT FOR CHANGELOG 的内部改进backport 分支不再自动合并减少 CI 对 backport 流程的干扰提升补丁分支管理的可控性。七、升级与运维建议升级前重点回归 HTTP 客户端http_max_fields1,000,000 → 1,000与http_max_field_name_size128 KB → 4 KB是本次唯一的兼容性风险点。升级前统计线上请求的字段数量与字段名长度分布若存在超限按 2.3 节方式在 profile 或网关层恢复上限并设置http_headers_read_timeout兜底。关注 TCP 客户端握手使用原生 TCP 协议clickhouse-client、官方驱动的部署确认客户端 Hello 包各字段均在 64 KB 内正常客户端远低于此值handshake_timeout_milliseconds默认 30 秒一般无需调整仅在特殊网络环境高延迟链路下按需放宽。开启 S3 可观测性使用 S3 存储的部署升级后立即验证system.histogram_metrics中两个新指标是否产生数据并接入 Prometheus 建立耗时/字节量的基线告警。回归测试清单结合 5.1–5.6 的修复点建议回归以下场景——JSON 列过滤查询、跨时区日期推断、轻量删除后COUNT(*)性能、S3Queue 并发 DDL、format: Arrow/Parquet 大文件读写、url()表函数查询、以及使用HMAC()的错误日志检查确认密钥不再出现。八、参考文件索引变更日志原文docs/changelogs/v26.1.12.23-stable.mdHTTP 新设置定义与默认值src/Core/Settings.cppHTTP 表单解析上限的读取src/Server/HTTP/HTMLForm.cppHTTP 设置说明注释src/Server/HTTPHandler.hS3 直方图指标注册与桶定义src/Common/HistogramMetrics.cppTCP 握手超时设置src/Core/ServerSettings.cppTCP Hello 字符串 64 KB 上限src/Server/TCPHandler.cppS3 ProfileEvents 事件定义src/IO/S3/PocoHTTPClient.cpp【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考