遇到 /var/log/journal 目录占用空间过大的问题时,许多人的第一反应是直接删除那些 .journal 文件。但这样做往往引发更多麻烦。正确的解决思路其实非常清晰:先使用安全命令立即释放空间,再修改配置文件以杜绝后患。

核心结论先行:千万不要手动删除文件,请使用 journalctl --vacuum-* 命令进行清理;要想长期有效,必须修改 /etc/systemd/journald.conf 并重启 systemd-journald 服务。
为什么不能直接删除 .journal 文件?
直接运行 rm -rf /var/log/journal/*.journal 看似痛快,实则后患无穷。原因在于 systemd-journald 服务并非简单地将日志写入文件,它同时维护着活跃的文件句柄和内部索引。粗暴删除会引发一系列问题:
- 命令报错:执行
journalctl查看日志时,很可能遇到Failed to open journal files: Invalid argument这类错误,导致部分历史日志无法读取。 - 服务异常:正在写入的日志文件被删除,可能导致
systemd-journald服务拒绝写入新日志,甚至异常退出或持续占用高 CPU。 - 空间未释放:最棘手的是,即使删除了文件,磁盘空间也可能并未真正释放。因为被删除的文件如果仍被进程打开,其占用的空间只有在进程关闭后才会回收。更麻烦的是,服务在下一次日志轮转或系统重启时,可能会重建旧的日志结构,问题依然存在。
所以,手动删除是一条“死胡同”。
立即释放空间:使用 journalctl --vacuum-* 命令
既然不能删文件,那该怎么清理?答案是使用 journalctl 自带的 --vacuum-* 系列参数。这个操作是原子且安全的,journald 会据此重写索引、压缩归档,并安全地删除过期文件。
最常用的两种清理方式:
- 按大小清理(推荐首选):
sudo journalctl --vacuum-size=500M。这条命令会确保所有日志(包括活跃和归档的)总大小不超过 500MB,优先删除最旧的日志。 - 按时间清理:
sudo journalctl --vacuum-time=7d。这条命令会删除所有早于 7 天的日志条目。
你可以组合使用这两个参数,例如同时设置 --vacuum-size=100M 和 --vacuum-time=30d。系统会执行更严格的那个条件,即最终保留的日志既要小于 100MB,也要在 30 天之内。
执行后,如何验证效果?运行 journalctl --disk-usage 查看当前日志占用的总磁盘空间,输出类似 Archived and active journals take up 420.1M,就说明清理成功了。
永久限制:修改 journald.conf 配置文件
通过 vacuum 命令清理只是临时手段。如果不修改配置,随着系统运行,日志很快又会膨胀到原来的大小。因此,必须修改 journald 的配置文件来设定长期规则。
关键步骤是编辑 /etc/systemd/journald.conf 文件,确保以下几个核心参数生效(需要去掉行首的注释符号 #):
SystemMaxUse=500M
SystemMaxFileSize=100M
MaxRetentionSec=1month
这三个参数分别代表:
SystemMaxUse:整个/var/log/journal目录可以使用的最大磁盘空间(注意,不是单个文件)。SystemMaxFileSize:单个日志文件达到此大小时,会自动进行轮转(rotate)。MaxRetentionSec:日志的最大保留时间。可以写成7d(7天)、1month(1个月)等形式。
修改完成后,至关重要的一步是重启服务:sudo systemctl restart systemd-journald。否则,新配置不会生效。
你可以通过命令 sudo systemd-analyze cat-config systemd/journald.conf | grep -E "(MaxUse|MaxFileSize|Retention)" 来验证配置是否已成功加载。
脚本化定期清理(备用方案)
在某些特殊环境下,比如容器化的宿主机或临时的 CI/CD 节点,可能无法直接修改系统级的 journald.conf 配置。这时,可以退而求其次,使用定时任务脚本作为兜底方案。
但切记,脚本里依然不要使用 find ... -delete 来删除 .journal 文件,原因同上。正确的做法是将 vacuum 命令封装进脚本。
例如,创建一个脚本 /opt/scripts/vacuum-journal.sh,内容如下:
#!/bin/bash journalctl --vacuum-size=200M >/dev/null 2>&1 echo "$(date): vacuumed to 200M" >> /var/log/journal_vacuum.log
然后通过 crontab -e 添加定时任务,比如每天凌晨3点执行:
0 3 * * * /opt/scripts/vacuum-journal.sh
务必在脚本中添加日志记录(如上例中的 echo 到日志文件),并将命令输出重定向到 /dev/null,否则 cron 执行中的任何错误都可能被静默忽略,导致你以为脚本在运行,实则早已失效。
最后,分享两个最常见的“坑”:第一,修改了 /etc/systemd/journald.conf 后,忘记重启 systemd-journald 服务,导致配置始终未生效。第二,将 SystemMaxUse 设置得过小(例如 16MB),这可能导致系统启动过程中的关键日志被截断,一旦后续出现故障,你将失去最重要的排查线索。设置一个合理的上限,平衡空间占用与可追溯性,才是运维的艺术。
