systemd-coredump 如何设置保留完整 core 文件且压缩存储

9次阅读

systemd-coredump 默认将完整 core 文件以 zstd 无损压缩存于 /var/lib/systemd/coredump/,完整性取决于 ProcessSizeMax=0、LimitCORE=infinity、Storage=external 及合理 MaxUse=/KeepFree= 设置,而非禁用压缩。

systemd-coredump 如何设置保留完整 core 文件且压缩存储

coredump 存储路径和保留策略由 systemd-coredump.conf 控制

默认情况下,systemd-coredump 会将 core 文件写入 /var/lib/systemd/coredump/,并自动压缩(zstd)、限制数量和大小。要保留完整未截断的 core 文件(即不被 ProcessCoreDump 信号处理截断、也不被 ulimit -c 限制),关键不是改压缩行为,而是确保内核生成完整 core,且 systemd 不丢弃或裁剪它。

  • 确认内核允许生成完整 core:sysctl kernel.core_pattern 应为 |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h %e(即走 systemd-coredump 管道),且 kernel.core_pipe_limit 未设为 0
  • 关闭 ulimit 截断:应用启动前确保 ulimit -c unlimited;若用 systemd service,需在 unit 文件中加 LimitCORE=infinity
  • 检查 /proc/sys/kernel/core_uses_pid 是否为 1(避免覆盖,非必需但推荐)

启用 zstd 压缩但保留原始完整内容

systemd-coredump 默认就用 zstd 压缩存储,且压缩是「无损」的——解压后就是原始内存镜像,不会丢失任何字节。所谓“保留完整 core 文件”,本质是确保没被截断、没被过滤、没被提前删除,而不是禁用压缩。

  • 压缩行为由 Compress=yes(默认)控制,无需关闭;禁用它反而浪费磁盘空间,且不解决“是否完整”的问题
  • 真正影响完整性的是:Storage=external(存文件系统)+ MaxUse=KeepFree= 设置过小会导致旧 core 被删,但不会损坏当前保存的 core
  • 验证是否完整:用 file /var/lib/systemd/coredump/core.*.zst 看是否识别为 “zstd compressed data”;再用 zstd -dcq /path/to/core.zst | head -c 128 | hexdump -C 检查开头是否含 ELF magic(7f 45 4c 46

修改 /etc/systemd/coredump.conf 实现长期保留

核心配置项集中在 /etc/systemd/coredump.conf,改完需运行 sudo systemctl kill --signal=SIGUSR2 systemd-coredump 或重启 systemd-coredump.socket 生效(后者更稳妥)。

  • Storage=external:必须设为 external(默认),才能落地为文件;nonejournal 会丢弃原始 core
  • MaxUse=2G:调大,例如 MaxUse=10G,防止因空间不足触发自动清理
  • KeepFree=5G:留足缓冲,避免磁盘写满导致新 core 写入失败
  • ProcessSizeMax=0:设为 0 表示不限制 core 大小(默认是 2G,超限会被丢弃)
  • ExternalCompression=zstd:保持默认即可,zstd 比 gzip 压缩率高、解压快,且 coredumpctl debug 原生支持

调试时如何还原和使用压缩后的 core

不需要手动解压:所有标准工具gdbcoredumpctleu-stack)都直接支持 .zst 后缀的 core 文件,底层自动调用 zstd 解压流式读取。

  • coredumpctl debug your-program 直接进 gdb,无需解压
  • coredumpctl info your-program 查看元数据和路径,路径里显示的就是 .zst 文件
  • 若非要解压出来(如给其他工具用):zstd -dcq /var/lib/systemd/coredump/core.*.zst > core.full,注意确保磁盘空间足够(可能数 GB 到数十 GB)
  • 常见误操作:把 Compress=no 当作“更完整”,其实只是省了压缩步骤,对内容完整性零影响,反而更快占满磁盘导致后续 core 被丢弃

最容易被忽略的是 ProcessSizeMax=0LimitCORE=infinity 的配合——前者管 systemd 层接收上限,后者管内核层生成上限,缺一不可。只调大一个,另一个仍会截断。

text=ZqhQzanResources