
ClickHouse CI 集成测试排障指南logs.tar.gz 产物包结构、按失败类型定位日志与精准解包方法【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse本文基于 ClickHouse 仓库investigate-ci技能中的集成测试产物文档完整解析 CI 集成测试失败时的日志产物包logs.tar.gz它的生成机制、压缩包内的目录布局、pytest_parallel.jsonl的结构化结果查询方法以及按失败类型断言错误、服务端异常、容器启动失败、执行轨迹选取正确日志文件的实操流程。读完后你将掌握从一份 CI 集成测试报告中快速下载产物包、只解压需要的成员、并用grep/jq精确定位失败根因的完整工作流理解这些产物在 集成测试作业脚本 中是如何被收集和上传的。一、产物包从哪里来logs.tar.gz 的生成与上传机制集成测试失败时的首要证据来源是logs.tar.gz产物包在.claude/tools/fetch_ci_report.js使用--links参数时会列在 Artifact Links 小节下。下载它有两种方式用fetch_ci_report.js --download-logs path参数直接下载到指定文件路径或直接用curl抓取--links输出中的 URL。注意压缩格式取决于文件大小。产物包本身始终是 tar 归档但内部成员文件的压缩可能各不相同更重要的是产物包 URL 可能是logs.tar.gz也可能是logs.tar.zst取决于大小。应以--links输出的实际 URL 为准并统一使用tar -xf自动探测压缩格式来解包而不是写死tar -xzf。产物包由 on_error_hook 在作业出错时打包从 集成测试作业脚本 的源码可以看到main()一开始就为作业注册了一个on_error_hookci/jobs/integration_test_job.py#L1494-L1512在硬性超时或作业出错时收集现场dmesg -T ./ci/tmp/dmesg.log sudo chown -R $(id -u):$(id -g) ./tests/integration tar -czf ./ci/tmp/logs.tar.gz \ ./tests/integration/test_*/_instances*/ \ ./ci/tmp/*.log \ ./ci/tmp/*.jsonl || :也就是说产物包内容正好是三类每个测试模块下 pytest 工作实例目录_instances*/含各节点的 ClickHouse 服务器日志、ci/tmp/下的全部.log各 pytest 输出与作业日志和全部.jsonl结构化测试结果。随后set_files()将./ci/tmp/logs.tar.gz、./ci/tmp/dmesg.log、dmesg 跟随日志和 docker-in-docker 日志 声明为要上传的附件strictFalse缺失不致命。这解释了产物包为什么以相对仓库根的路径ci/tmp/...、tests/integration/...组织成员——tar 就是以相对路径./ci/tmp/...打进去的。脚本中还有一处细节与排障相关作业在收尾阶段会把失败测试的独立日志文件与logs.tar.gz一起附加上报ci/jobs/integration_test_job.py#L2169因此--links中除整包外可能还有零散的日志文件可直接抓取。二、完整归档布局Archive Layout解包后logs.tar.gz的内部布局如下来自 产物文档ci/tmp/ pytest_parallel.jsonl # 结构化逐测试结果每行一个 JSON 对象 pytest_parallel.log # 人类可读的合并输出 pytest_parallel-gw0.log # 逐 worker 输出完整的 docker/cluster 调用 DEBUG 日志 pytest_parallel-gw1.log ... parallel.log # 顶层并行运行器日志 job.log # CI 作业脚本执行日志 docker-in-docker.log # Docker 守护进程输出 tests/integration/test_module/ _instances-conftest.py-gwN/ docker.log # 本 worker 的 docker compose up/down 输出 node1/logs/ clickhouse-server.log # node1 的 ClickHouse 服务器日志 clickhouse-server.err.log node2/logs/ clickhouse-server.log ...各成员文件的来源可以在源码中找到对应关系ci/tmp/pytest_parallel.jsonl/pytest_parallel.log由并行阶段调用run_pytest_and_collect_results(command..., report_nameparallel, ...)产生ci/jobs/integration_test_job.py 中并行批次以report_nameparallel运行 pytestreport_name决定了ci/tmp/下pytest_report_name.*系列文件的命名。pytest_parallel-gwN.logpytest-xdist 为每个 workergw0、gw1、…生成的独立日志。worker 数量由--distloadfile -n {workers}决定而workers在脚本中按“每 worker 最多 5 核、11 GiB 内存”的预算模型推导MAX_CPUS_PER_WORKER/MAX_MEM_PER_WORKER见 ci/jobs/integration_test_job.py#L114-L115。所以产物包里gwN的下标上限与作业跑在多大的 runner 上直接相关。tests/integration/test_module/_instances-conftest.py-gwN/pytest 为每个 worker 在测试模块目录下创建的 conftest 实例目录目录名含conftest.py与 worker 编号其中docker.log记录该 worker 的docker compose启停输出nodeM/logs/clickhouse-server.log及.err.log则是该集群每个节点上 ClickHouse 服务进程的完整日志。ci/tmp/docker-in-docker.logCI 容器内嵌套启动 dockerd 的输出。脚本中常量DOCKER_IN_DOCKER_LOG ./ci/tmp/docker-in-docker.logci/jobs/integration_test_job.py#L66声明了它的路径start_docker_in_docker()把docker_in_docker.sh的全部 stdout/stderr 重定向写入该文件若 daemon 20 次docker info探测后仍无响应会直接抛出 Docker daemon didnt responded after 20 attempts 并指向这个文件。三、按失败类型选取关键文件3.1 断言 / 结果错误AssertionError、行数不对等首选pytest_parallel.jsonl——它是结构化的逐测试结果每个失败一行 JSON。按测试名nodeid查询并抽取关键信息grep -F test_name tmp/investigate/$SHA/ci/tmp/pytest_parallel.jsonl \ | jq select(.outcome failed) | { crash: .longrepr.reprcrash.message, lines: [.longrepr.reprtraceback.reprentries[].data.lines[]?], stderr: (.sections[] | select(.[0] Captured stderr call) | .[1])?, captured: (.sections[] | select(.[0] Captured log call) | .[1])? }两个关键的字段陷阱longrepr是 JSON 对象不是字符串。断言文本在.longrepr.reprcrash.message回溯逐行内容在.longrepr.reprtraceback.reprentries[].data.lines[]。pytest 捕获的输出在.sections[]中形如[标题, 内容]二元组其中Captured stderr call与Captured log call两类标题分别包含 docker 调用、ClickHouse 查询、Spark 协议交互等测试期间捕获的 stderr 与日志。另外若只想粗看失败详情可先拉出 longrepr 原文grep -F -- test_name tmp/investigate/$SHA/ci/tmp/pytest_parallel.jsonl \ | jq -r select((.longrepr // ) ! ) | .longrepr必须使用grep -F固定字符串匹配参数化测试名如test_foo[a]含有正则元字符普通grep不会按字面匹配。3.2 服务端异常 / 数据错误目标文件是各节点的服务器日志tests/integration/test_module/_instances-conftest.py-gwN/nodeM/logs/clickhouse-server.log这是纯文本位于归档内部。先只解压该成员再 greptar -xf tmp/investigate/$SHA/logs.tar.gz -C tmp/investigate/$SHA/ \ tests/integration/test_module/_instances-conftest.py-gw1/node1/logs/clickhouse-server.log grep -i error\|exception\|fatal \ tmp/investigate/$SHA/tests/integration/test_module/_instances-conftest.py-gw1/node1/logs/clickhouse-server.log \ | tail -50注意Nworker 编号和M节点编号都要替换成实际值一次失败的集群往往有 node1/node2 等多个节点跨节点问题如分布式表、副本同步需要对照多个节点的日志时间戳。3.3 Docker / 容器启动失败看_instances-conftest.py-gwN/docker.log——这是该 worker 上docker compose up/down的原始输出镜像拉取失败、端口冲突、compose 语法问题都会体现在这里。结合 集成测试作业脚本 的源码可以推断出这类失败在 CI 侧的自动归类逻辑脚本维护了一份基础设施错误模式表INFRASTRUCTURE_ERROR_PATTERNSci/jobs/integration_test_job.py#L639-L652包括Cannot connect to the Docker daemon、Error response from daemon、Connection reset by peer、No space left on device、OCI runtime create failed等以及超时模式timed out after/TimeoutExpired。_mark_infrastructure_errors()ci/jobs/integration_test_job.py#L796-L809会扫描每个测试结果命中这些模式的失败会被打上INFRA标签并改判为SKIPPED——也就是说如果你在 CI 报告里看到失败被标记为基础设施错误而状态是 SKIPPED真正的证据仍在产物包的docker.log与docker-in-docker.log里而不是测试断言本身。3.4 详细测试轨迹哪些查询、以什么顺序执行定位执行该测试的 worker 日志grep -l test_name tmp/investigate/$SHA/ci/tmp/pytest_parallel-gw*.log打开对应的pytest_parallel-gwN.log它是该 worker 的完整 DEBUG 级输出包含所有 docker/cluster 调用、下发的 SQL 及其顺序适合回答测试到底执行到了哪一步这类问题。四、只解压需要的成员不全量解包产物包可能很大源码注释中提到一次普通归档约为 413 MiB 量级的日志ci/jobs/integration_test_job.py#L75-L78且部分上传可能被截断因此推荐按成员名精确解压。例如只取 JSONL 和一个节点的服务器日志# 只解压 JSONL 和某个节点的 server 日志 tar -xf tmp/investigate/$SHA/logs.tar.gz -C tmp/investigate/$SHA/ \ ci/tmp/pytest_parallel.jsonl \ tests/integration/test_module/_instances-conftest.py-gw1/node1/logs/clickhouse-server.log配套的最佳实践解压失败本身就是一个发现。tar报错产物过期、包损坏、缺少zstd支持、成员不存在应当作为结论上报而不是让后续grep | jq静默产出空结果、被误判为查无实据。可以在解压后加一道校验test -f tmp/investigate/$SHA/ci/tmp/pytest_parallel.jsonl \ || { echo extraction FAILED — report the artifact problem; false; }统一用tar -xf自动探测格式。如前所述URL 可能是.tar.zst成员内容即使名为.log也可能实际是 zstd 压缩的遇到二进制乱码时可用file命令确认。工作目录按 SHA 隔离。技能文档约定所有调查文件放在tmp/investigate/sha/下sha为报告 commit 的前 7 位同一调查可重复访问而无需重新下载不同 PR 的产物互不覆盖。五、延伸与整个 investigate-ci 工作流的关系本文覆盖的产物包属于 investigate-ci 技能 中第 4 步按需下载 harness 产物的内容。该技能的完整流程是从 PR / S3 报告 URL / flaky-test issue 出发先抓取失败测试列表node .claude/tools/fetch_ci_report.js url --failed --cidb再对每个失败测试检索既有跟踪 issue 与修复 PR然后用play.clickhouse.com的checks表查询 master 历史来区分 flaky 与真实回归最后只对 REAL / UNCERTAIN / INFRA/BUILD 三类失败才下载并解压本文描述的产物包做根因分析。同一技能目录下还有按作业家族划分的兄弟文档可按需对照artifacts-stateless.md —— 无状态 / Fast 测试产物是独立文件而非整包clickhouse-server.log[.zst]、clickhouse-server.err.log[.zst]、stderr.log、job.log等按--links列出的 URL 逐个抓取artifacts-stress.md —— 压力测试关注clickhouse-server.initial.log、fatal.log、hung_check.log等fetch_ci_report.js —— 提供--failed、--links、--download-logs path、--binary、--report N等参数的报告/产物抓取工具集成测试作业脚本 —— 产物包生成on_error_hook打包、worker 预算模型、基础设施错误自动标注INFRA/SKIPPED等实现所在。掌握以上内容后面对任何一次 ClickHouse 集成测试 CI 失败你都可以按下载产物包 → 看归档布局 → 按失败类型选文件 → 精确解包 grep/jq定位的路径在不需要全量解压的情况下拿到根因证据。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考