如何修复完整的 systemd 日志
11 分钟阅读 - 2026年5月20日

使用 vacuum 命令、journald.conf 大小限制、自动清理计时器和日志转发,诊断并修复 systemd 日志满的问题。
如何修复已满的 systemd 日志
systemd 日志(journal)会存储服务器生成的每一条日志信息,在根分区较小的 VPS 上,它可能会悄无声息地耗尽可用磁盘空间。一旦发生这种情况,服务将无法启动,写入操作会停滞,而您恰恰会因此失去用于排查故障的关键诊断信息。本指南将介绍如何诊断该问题、立即释放空间,以及如何配置 journald 以防止此类情况再次发生。
问题诊断
首先检查日志文件占用了多少空间:
journalctl --disk-usage此处报告的是所有活动日志文件和归档日志文件的总大小。请将其与您的可用磁盘空间进行对比,使用 df -h。在 20 GB 的根分区上,即使 2 GB 的日志也占用了超过 10% 的总磁盘空间,这足以引发问题。
接下来,找出哪些服务产生的日志最多。以下这行命令可列出过去 24 小时内日志量排名前 10 的来源:
journalctl --since "24 hours ago" | awk '{print $5}' | cut -d'[' -f1 | sort | uniq -c | sort -rn | head -10使用 journalctl -p err -b 来筛选错误,以查看是否有某个服务陷入崩溃循环并导致日志泛滥。您还可以检查 journald 是否对某些服务进行了速率限制:
journalctl -u systemd-journald | grep -i "suppressed"被抑制的消息意味着某项服务在 30 秒内超过了 10,000 条条目的默认阈值。这就是罪魁祸首。
在 VPS 实例上,有几个问题特别常见。如果 Storage=auto 已设置且 /var/log/journal/ 文件存在,journald 会使用持久化存储,其默认上限约为 4 GB。在较小的根分区上,该空间会很快被填满。非正常关机还可能留下带有 .journal~ 后缀。这些文件无法正常轮换,会持续占用空间。
安全清除日志
在删除任何内容之前,请先轮换活动日志文件,以确保保留当前日志:
journalctl --rotate随后清理归档日志。您可以按时间、大小或文件数量进行筛选:
sudo journalctl --vacuum-time=1d
sudo journalctl --vacuum-size=100M
sudo journalctl --vacuum-files=5第一种操作将删除超过 24 小时的日志。第二种操作将日志总大小缩减至 100 MB。第三种操作仅保留最近的五个归档文件。请根据实际情况选择合适的操作。
如果磁盘已完全满且 journalctl 命令无响应,您可能需要手动删除日志文件:
sudo rm -rf /var/log/journal/*
sudo systemd-tmpfiles --create --prefix /var/log/journal这是最后的手段。此操作将清除所有存储的日志,并以正确的权限重新创建目录。清理完成后,请重启守护进程并进行验证:
sudo systemctl restart systemd-journald
journalctl --disk-usage配置 Journald 大小限制
默认的 journald 设置较为宽松。在 VPS 上,这些设置过于宽松。请编辑配置文件,为日志存储设置硬性上限。建议创建覆盖文件而非直接修改主配置文件,以确保您的更改在软件包更新后依然有效:
sudo mkdir -p /etc/systemd/journald.conf.d/
sudo nano /etc/systemd/journald.conf.d/size-limits.conf关键指令:
| 参数 | VPS(20-40 GB 磁盘) | 独立服务器 | 作用 |
|---|---|---|---|
| SystemMaxUse | 500M 至 1G | 2G 至 5G | 日志总大小的硬性上限 |
| SystemKeepFree | 1G | 磁盘空间的10% | 为操作系统预留的可用空间 |
| 最大保留秒数 | 7天至14天 | 30天至90天 | 自动删除超过此时间的日志 |
| 系统最大文件大小 | 20M 至 50M | 100M | 每个日志文件的最大大小 |
同时设置 SystemMaxUse 和 SystemKeepFree 可实现双重保障:日志大小受固定上限限制,且无论磁盘上还有什么内容,系统总能保留出足够的缓冲空间。
持久化存储与易失性存储
通过 Storage= 指令控制日志的存储位置。将 Storage=persistent 将日志写入 /var/log/journal/ 。这是生产服务器的理想选择,因为日志在重启后依然存在,您可以在事后调查崩溃情况。如果目录不存在,则创建它:
sudo mkdir -p /var/log/journal另一种选择, Storage=volatile,则将日志保存在内存中的 /run/log/journal/。重启后日志将消失。这适用于临时容器或将所有日志转发至外部系统的服务器。
在高流量服务器上禁用压缩
Journald 默认会对大于 512 字节的数据对象进行压缩。在处理大量日志吞吐量的服务器上,这会增加 CPU 开销。若您将日志转发至外部且无需最小化本地存储空间,请将 Compress=no ,若您将日志转发至外部且无需最小化本地存储空间。同时请在 ForwardToConsole=no 。控制台转发是同步的,如果虚拟串行控制台卡住,可能会完全阻塞 journald 守护进程。
配置更改后,请重启服务:
sudo systemctl restart systemd-journald日志维护自动化
手动清理无法满足大规模需求。请创建一个 systemd 定时器,按计划清理日志。在 /etc/systemd/system/journal-vacuum.service:
[Unit]
Description=Vacuum old journal logs
[Service]
Type=oneshot
ExecStart=/usr/bin/journalctl --vacuum-time=7d --vacuum-size=500M然后在 /etc/systemd/system/journal-vacuum.timer:
[Unit]
Description=Weekly journal vacuum
[Timer]
OnCalendar=Sun 02:00
Persistent=true
[Install]
WantedBy=timers.target通过以下命令启用该定时器 sudo systemctl enable --now journal-vacuum.timer。该定时器每周日凌晨2点运行,一次执行基于时间和基于大小的双重保留策略。
定时器无法处理的一类情况是:损坏的日志文件。在非正常关机后,journald 会通过在文件名后附加 ~ 。这些 .journal~ 文件仍会占用磁盘空间,但不会被自动清理。请定期检查并删除旧文件:
find /var/log/journal/ -name "*.journal~" -mtime +30 -delete将日志转发至外部
对于需要长期保留日志但又不希望本地存储空间不断扩大的服务器,请将日志转发至集中式系统。最简单的方法是在 journald.conf:
ForwardToSyslog=yes对于包含完整元数据(PID、UID、单元名称)的结构化日志,请使用 systemd-journal-remote 将 JSON 格式的日志条目发送至日志管理平台。外部日志存储还能在本地磁盘故障或服务器遭入侵时保护您的审计记录。

Linux 服务器加固清单
15 分钟阅读 - 2026年5月8日