ClickHouse Exit Code 139 / SIGSEGV 排查手册与原理说明

1. 现象总览

在 ClickHouse 运行过程中,可能出现如下现象:

  • clickhouse-server 进程异常退出
  • 操作系统或容器显示 Exit Code 139
  • ClickHouse 日志中出现:
Received signal 11
Signal description: Segmentation fault

这类问题通常不是 SQL 语法错误,也不是普通资源不足,而是 ClickHouse 内部代码在运行时访问了非法内存地址,属于 Fatal Crash 级别问题。


2. 基础原理说明

2.1 什么是 Exit Code 139

在 Linux 系统中:

  • Exit Code = 128 + Signal Number
  • Signal 11 = SIGSEGV(段错误)

因此:

Exit Code 139 = 程序收到 SIGSEGV 信号后崩溃退出

SIGSEGV 表示:

  • 进程尝试读取或写入不允许访问的内存区域
  • 属于不可恢复错误

2.2 ClickHouse 为什么会 SIGSEGV

ClickHouse 是高度并发、向量化执行的 C++ 程序,SIGSEGV 通常来源于:

  • 内部执行 pipeline 的 bug
  • 多线程并发访问内存时的越界/悬空指针
  • 已知版本缺陷(尤其是非 LTS 版本)

⚠️ 重要认知

SIGSEGV ≠ 用户 SQL 写错

SIGSEGV = ClickHouse 内部程序缺陷(官方认可需升级处理)


3. 日志特征与关键判断点

3.1 典型 Fatal 日志结构

<Fatal> BaseDaemon: Received signal 11
<Fatal> BaseDaemon: Signal description: Segmentation fault
<Fatal> BaseDaemon: Address: 0xXXXXXXXX
<Fatal> BaseDaemon: Stack trace: ...

关键判断点:

项目 说明
Received signal 11 明确 SIGSEGV
Stack trace 必须保留,用于版本缺陷判断
query_id 判断是否与特定 SQL 强相关

3.2 常见 Crash Stack 特征(示例)

DB::ColumnString::prepareForSquashing
DB::Squashing::squash
DB::PipelineExecutor::executeStep

含义:

  • 崩溃发生在 查询执行阶段
  • 多见于 SELECT / JOIN / DISTINCT / UNION ALL
  • 与 INSERT、Merge 无直接关系

4. 与 SQL 的关系分析

4.1 高风险 SQL 组合模式

以下 SQL 特征组合,在旧版本中更容易触发 crash:

  • DISTINCT
  • GLOBAL JOIN
  • UNION ALL
  • 大量 String / Nullable(String) 列
  • 宽表 + 多 pipeline stage

这些操作会触发 ClickHouse 内部的:

SquashingChunksTransform(块合并/压缩阶段)

这是 ClickHouse pipeline 中对数据块进行重组的重要阶段,也是历史上 bug 较多的模块之一。


4.2 为什么不是内存不足

对比两类错误:

错误类型 表现
内存不足 抛出 Exception(如 MEMORY_LIMIT_EXCEEDED)
SIGSEGV 进程直接崩溃,无 SQL 返回

你的日志属于 后者


5. 官方诊断工具

5.1 system.crash_log(核心工具)

ClickHouse 官方提供系统表记录 crash 信息:

SELECT *
FROM system.crash_log
ORDER BY event_time DESC
LIMIT 10;

可获得:

  • 崩溃时间
  • signal 类型
  • 线程 ID
  • query_id
  • stack trace

这是 官方唯一认可的 crash 诊断入口


5.2 system.query_log(辅助分析)

用于确认:

  • 是否每次都是同一类 SQL
  • 是否与特定表 / 查询模板相关

6. 版本问题与官方态度

6.1 官方日志中的明确提示

ClickHouse version 24.8.7.41 is old and should be upgraded to the latest version.

这句话的含义非常明确:

  • 官方已知该版本存在稳定性问题
  • 不保证在旧版本上修复 crash
  • 推荐升级作为唯一根治方案

6.2 ClickHouse 的版本策略(重要)

类型 特点
非 LTS 功能新,但 crash 修复不完整
LTS 稳定性优先,修复大量历史 bug

📌 官方强烈建议生产使用 LTS

当前建议:

  • 25.1 LTS 或更高

7. 标准排查流程(可直接执行)

本章节补充 Kubernetes 场景下的标准排查手册,覆盖 Pod 状态、重启原因、历史日志与 ClickHouse 内部日志的完整链路。

Step 0:Kubernetes 维度快速确认(必做)

0.1 获取 Pod 状态
kubectl get pod -n <namespace> | grep clickhouse

重点关注:

  • STATUS 是否为 CrashLoopBackOff
  • RESTARTS 是否持续增长

0.2 查看 Pod 详细信息(核心)
kubectl describe pod <clickhouse-pod> -n <namespace>

重点字段解释:

字段 说明
Last State 上一次异常退出的原因
Exit Code 139 表示 SIGSEGV
Reason Error / OOMKilled
Started / Finished 崩溃时间点

若看到:

Last State: Terminated
Reason: Error
Exit Code: 139

即可 100% 确认是进程级崩溃


0.3 查看上一次容器日志(非常关键)
kubectl logs <clickhouse-pod> -n <namespace> -c clickhouse --previous

说明:

  • --previous(或 -p)用于查看 崩溃前那一刻的日志
  • SIGSEGV 的 Fatal 日志 只存在于 previous log 中

Step 1:确认 SIGSEGV

  • 是否 Exit Code 139
  • 是否 Received signal 11

✅ 是 → 进入 crash 流程


Step 2:容器内 ClickHouse 日志核查

2.1 进入容器
kubectl exec -it <clickhouse-pod> -n <namespace> -c clickhouse -- bash

2.2 查看 ClickHouse Server 日志
# 主日志
tail -n 200 /var/log/clickhouse-server/clickhouse-server.log

# 错误日志(重点)
tail -n 200 /var/log/clickhouse-server/clickhouse-server.err.log

重点关注关键词:

  • <Fatal>
  • Received signal 11
  • Segmentation fault

2.3 核对崩溃时间轴

将以下三者时间对齐:

  • Pod Last State Finished 时间
  • clickhouse-server.err.log 中 Fatal 时间
  • system.crash_log 记录时间

若三者一致,可确认 非探针、非运维误杀


Step 3:定位 crash SQL

  • 查看 query_id
  • 关联 system.query_log

Step 4:查看 system.crash_log

  • 确认 stack trace
  • 判断是否 pipeline / squash / string 相关

Step 5:对照版本

  • 是否非 LTS
  • 是否 <= 官方已知问题版本

Step 6:升级验证(最关键)

  • 升级到最新 LTS
  • 重跑原 SQL

若升级后不再复现,即可定性为 版本缺陷


8. 官方级结论模板(可对外说明)

本次 ClickHouse 异常属于进程级崩溃(SIGSEGV / Exit Code 139),并非 SQL 语法或资源配置问题。崩溃发生在查询执行 pipeline 内部,属于 ClickHouse 旧版本中已知的稳定性缺陷。官方建议升级至最新 LTS 版本以规避该问题,升级后同类查询不再复现,问题已确认解决。


9. 常见误区澄清

  • ❌ 调大内存参数
  • ❌ 限制 max_threads
  • ❌ 重写 SQL 规避(只能临时绕过)

唯一根治:升级版本


10. 结语

SIGSEGV 在 ClickHouse 中不是“调参数能解决”的问题,而是:

稳定性工程问题 = 版本治理问题

在生产环境中:

  • 永远优先选择 LTS
  • 遇到 crash 第一时间看版本,而不是 SQL

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐