最后更新于

记一次树莓派磁盘占满的排查流程


前段时间,我的树莓派又在角落里默默吃灰了。最近想重新启用它,却发现 VNC 连接不上了,总是提示“远程主机关闭了连接”。下意识地重启大法,然而并没有什么用……

奇怪的是,SSH 居然还能正常登录。正当我一头雾水的时候,随手敲了个 sudo apt-get update,结果却意外地收到了一个磁盘空间已满的错误提示。我当时就震惊了,一块 64GB 的 SD 卡居然能被塞满?

揪出“吃”硬盘的真凶

带着疑问,我开始了“破案”之旅。

首先,我想确认一下磁盘的整体使用情况。Google 了一下,找到了 df -h 这个命令。执行结果果然显示 /dev/root 分区已用 100%。

Terminal window
df -h

df -h 命令确实能让我们看到每个挂载点的磁盘占用情况,但具体是哪个文件夹或文件是“吃”硬盘的元凶呢?这还得进一步排查。

继续求助 Google 大神,发现了一个神器:ncdu。这个工具需要额外安装一下 (sudo apt install ncdu)。安装完毕后,直接在命令行输入 ncdu,它会扫描当前目录(或者你指定的目录,例如 ncdu / 来扫描根目录),然后以交互式的方式列出占用空间最多的文件和目录,一目了然。

Bash

sudo apt install ncdu
ncdu /

不查不知道,一查吓一跳!通过 ncdu 的分析,我发现是 /var/log 目录下的日志文件占用了巨额空间。其中,daemon.log 竟然独自霸占了 22GB,而 syslog 则吞噬了几乎所有剩余的可用空间。我尝试用 vim 打开这些庞然大物,结果可想而知——直接卡死。

面对这种体积的日志文件,直接打开显然是不现实的。再次 Google,学到了新姿势:使用 tail -n <行数> <文件名> 命令可以查看大文件的末尾几行内容。这对于快速定位最新日志中的问题非常有用。

Bash

tail -n 100 /var/log/daemon.log

原来是“自作自受”

通过查看日志尾部的内容,我终于定位到了问题的根源。原来是我之前为了方便,给 sakurafrp(一个内网穿透工具)写了一个 systemd 服务。然而,sakurafrp 的服务端进行了一些升级,导致我旧版本的客户端在连接时不断报错。这些错误日志被疯狂地写入 daemon.logsyslog,日积月累,终于在一个月黑风高的夜晚……把我的磁盘写满了。

找到问题后,解决起来就简单了:更新 sakurafrp 客户端到最新版本,并且在 systemd 服务的配置文件中加入了错误重启的配置,避免类似问题再次把服务搞挂。

温故知新:Systemd 服务管理

这次排错过程,也顺便让我复习了一遍 systemd 相关的常用命令:

  • sudo systemctl daemon-reload: 当你修改了 systemd 服务配置文件后,需要执行此命令来重新加载配置,使其生效。
  • /lib/systemd/system/ (或者 /etc/systemd/system/ 更常见用于用户自定义服务): systemd 服务的配置文件通常存放在这里。
  • sudo systemctl status <服务名>: 这个命令可以查看指定服务的运行状态、最近的日志等信息,非常实用。
  • systemd 配置文件中的 Restart=on-failure 字段是一个很有用的配置项。它可以确保当服务因为某些错误异常退出时,systemd 会自动尝试重启该服务,提高服务的可用性。

日志管理:亡羊补牢,未为晚也

为了避免将来再次发生日志撑爆磁盘的惨剧,我搜索了一下 Linux 下日志管理的最佳实践。发现 systemd 其实自带了一套强大的日志管理工具:journalctl

  • sudo journalctl -u <服务名>: 查看特定 systemd 服务产生的日志。例如,查看 nginx 服务的日志就可以用 sudo journalctl -u nginx.service
  • sudo journalctl --vacuum-size=1G: 这个命令可以设置 journald 管理的日志总大小上限。例如,这里设置为 1GB,当日志超过这个大小时,旧的日志会被自动清理。
  • sudo journalctl --vacuum-time=1years: 这个命令可以设置日志的保留时间。例如,这里设置为自动删除所有一年之前的老日志。

通过配置 journalctl,我们可以有效地控制系统日志的增长,避免它们无限制地消耗磁盘空间。

总结与反思

这次“惊心动魄”的树莓派磁盘排查经历,让我收获了不少实用的 Linux 运维小技巧:

  1. df -h: 快速查看磁盘各分区基本占用情况的利器。
  2. ncdu: 深入分析具体文件和目录占用磁盘空间的“侦探”。
  3. tail -n: 查看大文件尾部内容的实用技巧,尤其适用于排查日志。
  4. journalctl: systemd 环境下管理和控制日志大小的官方解决方案。
  5. 日志规范: 这次经历也给我敲响了警钟——以后自己写程序或者配置服务时,一定要谨慎对待日志输出。要确保日志级别可控,避免无意义的、重复的错误日志疯狂输出,最终把用户的磁盘空间占满,落得个“垃圾程序员”的“美名”。

希望这次的经验分享能对遇到类似问题的朋友有所帮助!

资料