Linux 系统日志磁盘写满问题排查与解决笔记

1. 问题现象

  • 系统每天凌晨 00:00 左右,/var/log 目录所在分区磁盘空间被写满。
  • 系统日志(/var/log/syslog/var/log/daemon.log 等)出现大量如下错误:

    cat: write error: No space left on device
    rsyslogd: file '/var/log/syslog' write error - No space left on device
  • 系统为 Armbian 定制版,运行在 1核1G ARM 开发板(如 Orange Pi、Banana Pi 等)上,内核版本 5.4.65-sunxi

2. 问题初步分析

2.1 磁盘空间检查

df -h
df -i

发现 /var/log 分区使用率接近 100%,且存在大量 systemd journal 的僵尸文件(以 .journal~ 结尾)。

2.2 日志目录分析

du -sh /var/log/*
ls -la /var/log/journal/*/

发现 /var/log/journal/ 下存在大量类似以下文件:

system@xxx.journal~

这些文件是 journald 轮转后未能自动清理的残留文件,占用了几十 MB 甚至更多空间。


3. 根本原因定位

3.1 定时任务排查

查看系统定时任务:

cat /etc/crontab
ls -la /etc/cron.d/
ls -la /etc/cron.daily/

发现关键定时任务:

  • /etc/cron.d/pbsbc01h3-truncate-logs
    每 15 分钟执行一次
  • /etc/cron.d/pbsbc01h3-updates
    每天和重启时执行
  • /etc/cron.daily/pbsbc01h3-ram-logging
    每天执行一次

3.2 问题脚本内容分析

查看 pbsbc01h3-truncate-logs 脚本:

cat /usr/lib/pbsbc01h3/pbsbc01h3-truncate-logs

脚本逻辑如下:

  1. 检查 /var/log 磁盘使用率是否 ≥ 75%。
  2. 如果超过阈值:

    • 调用 pbsbc01h3-ramlog write 将内存中的日志同步到磁盘。
    • 强制运行 logrotate
    • 暴力截断所有日志文件内容(truncate --size 0
    • 删除旧的压缩日志(*.gz*.[0-9])。

3.3 问题机制总结

  • 该脚本与 systemd-journald 同时操作日志文件,产生冲突。
  • 冲突导致 journald 轮转时无法正确清理旧文件,遗留大量 .journal~ 僵尸文件。
  • 僵尸文件不断累积,最终在凌晨触发日志同步时占满磁盘空间。

4. 解决方案

4.1 立即清理僵尸文件

# 停止 systemd-journald
sudo systemctl stop systemd-journald

# 删除所有 journal 僵尸文件
sudo find /var/log -name "*.journal~" -type f -delete

# 强制 journald 遵守 80MB 大小限制
sudo journalctl --vacuum-size=80M

# 重启 systemd-journald
sudo systemctl start systemd-journald

4.2 禁用问题定时任务(推荐)

# 禁用每15分钟执行的日志截断任务
sudo mv /etc/cron.d/pbsbc01h3-truncate-logs /etc/cron.d/pbsbc01h3-truncate-logs.disabled

# 禁用每日执行的 ramlog 写入任务(可选,减少冲突)
sudo mv /etc/cron.daily/pbsbc01h3-ram-logging /etc/cron.daily/pbsbc01h3-ram-logging.disabled

4.3 保持 ramlog 启用(可选)

如果希望继续保护 SD 卡写入寿命,可以保持 ramlog 启用:

# 编辑 /etc/default/pbsbc01h3-ramlog
sudo nano /etc/default/pbsbc01h3-ramlog

确保配置如下:

ENABLED=true
SIZE=128M
USE_RSYNC=true

注意:不要添加 XTRA_RSYNC_OPTS=(--delete) 等额外参数,否则可能产生冲突。


5. 验证与监控

5.1 验证清理效果

# 检查磁盘使用率
df -h

# 检查僵尸文件是否还存在
find /var/log -name "*.journal~" | wc -l

# 检查 journal 实际占用
journalctl --disk-usage

5.2 监控凌晨执行情况

第二天凌晨检查日志:

journalctl --since="2026-05-25 00:00:00" --until="2026-05-25 00:10:00"
df -h

正常情况下,磁盘空间应保持稳定,不再被写满。


6. 长期优化建议

6.1 配置 journald 大小限制(已完成)

sudo nano /etc/systemd/journald.conf

推荐配置:

[Journal]
SystemMaxUse=80M
SystemMaxFileSize=10M
SystemMaxFiles=4
MaxRetentionSec=2day

重启服务:

sudo systemctl restart systemd-journald

6.2 可选:配置自动清理僵尸文件

创建定时清理脚本(提前到 23:55 执行):

sudo nano /usr/local/bin/clean-journal-zombie.sh
#!/bin/bash
find /var/log -name "*.journal~" -type f -delete
journalctl --vacuum-size=80M

配置 systemd timer 在 23:55 执行,避免与凌晨任务冲突。


7. 总结

问题现象根本原因解决方案
每天 00:00 磁盘写满pbsbc01h3-truncate-logs 脚本与 journald 冲突,产生僵尸 journal 文件禁用问题定时任务 + 清理僵尸文件 + journald 限制大小
系统日志写入失败磁盘空间被 .journal~ 文件占满清理僵尸文件并重启 rsyslog

核心结论

  • ✅ 禁用 pbsbc01h3-truncate-logs 定时任务不会影响系统正常运行
  • ✅ journald 自带的日志管理机制完全可以替代暴力截断脚本。
  • ✅ 清理后系统日志功能恢复正常,磁盘空间稳定在安全范围内。

8. 附录:关键命令速查

# 查看磁盘使用率
df -h

# 查看僵尸文件数量
find /var/log -name "*.journal~" | wc -l

# 强制清理 journal 到指定大小
sudo journalctl --vacuum-size=80M

# 查看 journal 实际占用
journalctl --disk-usage

# 查看定时任务
systemctl list-timers
cat /etc/crontab
ls -la /etc/cron.d/

适用系统:Armbian / Debian-based Linux (ARMv7l)
问题标签:磁盘满 / journald / ramlog / 定时任务冲突

标签: none

添加新评论