Linux服务器磁盘突然告警,进入 /var/log 后发现journal目录占了几十GB,这时最容易做的错误操作,就是直接删除目录里的二进制日志文件。空间可能暂时回来了,但日志索引、正在使用的文件句柄和后续审计都会受到影响。
我更建议先确认到底是systemd journal占用,还是应用日志、容器日志和已删除未释放文件共同造成。只有把异常服务和增长速度找出来,执行vacuum清理才不会过几天再次占满磁盘。

确认磁盘和inode真实状态
先检查容量、inode与挂载关系:
df -hT
df -i
findmnt /var/log
sudo du -xhd1 /var/log | sort -h
journalctl --disk-usage
journalctl --disk-usage给出当前活动日志和归档日志的总占用。它与 du结果明显不一致时,还要检查文件系统快照、挂载覆盖和已经删除但仍被进程打开的文件。
sudo lsof +L1 | head -100
inode耗尽时,即使 df -h还有空间,服务也可能无法创建新日志或临时文件。大量极小文件更可能来自应用目录,不能只清理journal。
判断日志存放在内存还是磁盘
systemd-journald可以把日志保存在 /run/log/journal或 /var/log/journal。前者通常位于内存文件系统,重启后丢失;后者是持久化存储,会长期占用磁盘。
ls -ld /run/log/journal /var/log/journal 2>/dev/null
grep -E '^[[:space:]]*(Storage|SystemMaxUse|RuntimeMaxUse|SystemKeepFree|MaxRetentionSec)=' /etc/systemd/journald.conf
Storage=auto时,是否存在 /var/log/journal会影响保存方式。不要只查看配置文件中的注释值,默认行为还与systemd版本和发行版设置有关。
持久日志对故障追溯很重要,尤其是服务器异常重启后。解决磁盘问题不应简单改成volatile并放弃所有历史记录,而应设置与磁盘容量匹配的上限和保留周期。
找到制造大量日志的服务
journal占用过大通常不是journald自己无故增长,而是某个服务持续打印重复错误。先按最近时间和服务查看:
journalctl --since '1 hour ago' -p warning
journalctl -u SERVICE --since '1 hour ago'
journalctl --since today --no-pager | tail -500
重点观察每秒重复出现的连接失败、认证错误、健康检查异常和重启日志。容器服务可能同时把日志写入journal和Docker日志驱动,形成双份占用,需要确认实际日志链路。
还要检查服务是否陷入重启循环:
systemctl --failed
systemctl show SERVICE -p NRestarts
systemctl status SERVICE
只清理历史日志而不修复重复报错,磁盘会以相同速度再次增长。先记录异常样本和时间范围,再处理服务配置、依赖或重启策略。
使用journalctl安全回收空间
确认可以缩短历史保留后,先轮转活动日志,让旧文件进入可清理状态:
sudo journalctl --rotate
sudo journalctl --vacuum-time=7d
sudo journalctl --vacuum-size=1G
journalctl --disk-usage
--vacuum-time按时间清理归档日志,--vacuum-size把归档集合压到目标大小。两个命令分别执行更容易核对每一步释放了多少空间。它们主要处理归档文件,因此先rotate能让当前文件切换出去。
空间极度紧张时,也不应直接使用通配符删除journal目录。日志文件可能正被journald使用,手工删除后 df未必马上下降,还会让日志完整性难以判断。
设置长期空间上限
清理完成后,在 /etc/systemd/journald.conf中设置适合当前磁盘的上限,例如:
[Journal]
SystemMaxUse=1G
SystemKeepFree=2G
MaxRetentionSec=14day
SystemMaxUse限制持久日志可使用的最大空间,SystemKeepFree要求为其他数据保留空间,MaxRetentionSec限制最长保留时间。三者共同作用时,最先达到的约束会触发清理。
修改后检查配置并重启journald:
sudo systemd-analyze cat-config systemd/journald.conf
sudo systemctl restart systemd-journald
journalctl --disk-usage
不同systemd版本对配置项支持程度不同,先查看本机手册。生产环境还要确认日志是否被远程采集,避免本地保留周期缩短后无法满足审计需求。
为异常增长建立监控
只设置固定上限会阻止journal无限增长,但不能告诉你哪个服务正在疯狂报错。建议同时监控根分区使用率、inode、journal占用和服务重启次数,并在增长速度异常时告警。
排查日志策略时,可以在 萤光云 建立隔离系统复现journald配置,也可以使用按小时计费的 LightNode 比较不同发行版的默认保留行为。测试日志要脱敏,不要复制真实IP、账号和访问令牌。
应用服务还应设置合理的日志级别和限速。生产环境长期保持debug级别,或者在失败循环中每毫秒输出一次错误,即使有空间上限也会快速挤掉真正有价值的历史日志。
清理后怎样验收
完成清理和配置后,至少记录以下结果:
df -hT
df -i
journalctl --disk-usage
journalctl -p err --since '10 minutes ago'
systemctl --failed
观察一段真实业务时间,确认journal占用没有快速反弹、异常服务不再重复输出,应用仍能正常写入日志,并且重启后可以读取需要保留的历史记录。
合格的修复不仅要释放空间,还要留下明确的保留上限,并解决制造大量重复日志的源头。
常见问题
可以直接删除/var/log/journal吗?
不建议。应使用journalctl的rotate与vacuum机制清理,并先确认审计和故障追溯要求。直接删除可能破坏活动文件和日志连续性。
vacuum-size执行后为什么没有降到完全相同的大小?
活动日志不会像归档日志一样立即清理,文件粒度和当前写入也会造成差异。先执行rotate,再查看disk-usage更准确。
限制到1GB后还会超过1GB吗?
活动文件、归档轮转粒度和文件系统占用会让实际值存在少量浮动。重点是长期稳定在可控范围,而不是每一刻都精确等于设定值。


