Linux服务器磁盘清理
前言
“No space left on device”——这个错误信息是每个Linux系统管理员的噩梦。不仅仅是一个警告,更是一个预示:系统即将罢工,服务中断,甚至可能无法远程登录。
本文将通过一次真实的“磁盘100%”救援案例,为你呈现一套从紧急诊断、全面清理到长效预防的完整操作指南。无论你是新手还是老兵,这篇指南都将成为你工具箱中的利器。
磁盘爆满
故事始于一个再熟悉不过的命令:
1 | $ df -h |
根分区 (/) 占用率100%,系统已处于瘫痪边缘。
侦查与诊断
在删除任何文件之前,我们必须精准定位空间的消耗者。以下是我们的侦查三板斧。
du 命令,逐层深入
du (disk usage) 是我们定位问题的核心工具。
1. 锁定顶级目录:
从根目录开始,查找哪个顶级目录是问题的根源。使用 -x 参数确保我们只在当前文件系统内统计,避免统计到其他挂载的数据盘。
1 | # -h: 人类可读格式, -x: 仅限当前文件系统, -d 1: 扫描深度为1层 |
2>/dev/null用于忽略 “Permission denied” 错误,让输出更干净。
很快,结果会指向几个常见的“嫌疑犯”,在我们的案例中,/var 目录以绝对优势胜出。
2. 深入嫌疑目录:
继续对 /var 目录进行分析:
1 | sudo du -hxd 1 /var 2>/dev/null | sort -hr |
/var/lib (应用数据) 和 /var/log (日志) 是两大元凶。
ncdu,交互式神器(推荐)
如果你想获得更直观的体验,ncdu 是一个无与伦-比的工具。
1 | # 如果未安装,先安装 |
ncdu 会提供一个可交互的、按大小排序的目录树,你可以用方向键轻松地在目录间穿梭,一目了然地找到最大的文件和目录。
find 命令,定位巨型文件
有时候,罪魁祸首可能不是大量的小文件,而是几个被遗忘的巨型文件(如数据库备份、ISO镜像等)。
1 | # 查找根目录下所有大于1GB的文件 |
全面清理
诊断完毕,现在开始我们的清理行动。
日志文件 (/var/log)
日志是系统最容易失控增长的部分,也是最安全的清理目标。
1. Systemd Journal 日志 (主要元凶)
- 问题:
systemd-journald服务默认不限制日志大小,长期运行的服务器上,/var/log/journal目录可达数GB甚至数十GB。 - 立即清理: 保留最近200MB的日志。
1
sudo journalctl --vacuum-size=200M
- 永久性修复: 编辑配置文件,给戴上“紧箍咒”。在
1
sudo nano /etc/systemd/journald.conf
[Journal]部分,修改或添加以下配置,将最大空间限制在500MB。重启服务使其生效:1
SystemMaxUse=500M
1
sudo systemctl restart systemd-journald
2. 传统日志 (syslog, kern.log, etc.)
- 问题: 旧的、轮转的日志文件 (
.log.1,.log.gz) 堆积。 - 清理:
1
2
3
4
5
6# 删除所有已归档的旧日志
sudo find /var/log -name "*.gz" -o -name "*.1" -delete
# 清空当前活跃的大日志文件内容(比rm更安全,服务无需重启)
sudo truncate -s 0 /var/log/syslog
sudo truncate -s 0 /var/log/kern.log
包管理器缓存
包管理器在安装软件时会下载大量缓存文件。
1. APT (Debian/Ubuntu)
1 | # 清理所有已下载的.deb包文件 |
2. YUM/DNF (CentOS/RHEL/Fedora)
1 | # 清理所有缓存,包括元数据、软件包等 |
Docker
Docker是 /var/lib 目录下最常见的空间消耗者。
1. 快速诊断
1 | sudo docker system df |
这个命令会清晰地列出镜像、容器、数据卷和构建缓存各占用了多少空间。
2. 一键清理
1 | # 清理所有已停止的容器、未被任何容器使用的网络、悬空的镜像和构建缓存 |
Snap 包 (Ubuntu 特有)
Snap应用在更新后会保留旧版本,日积月累,占用空间相当可观。
1 | # 1. 查看所有snap包,包括已禁用的旧版本 |
用户家目录 (/home)
不要忘记检查用户目录,特别是 ~/.cache 和 ~/Downloads。
1 | # 查看当前用户缓存目录大小 |
自动化与预防
清理是一次性的,建立长效机制才能一劳永逸。
1. 迁移 Docker 数据目录(终极方案)
如果你的根分区本身很小,最好的策略是将Docker的“家”搬到一个更大的分区(如挂载的数据盘 /data)。
1 | # 1. 创建新目录 |
2. 配置 logrotate
logrotate 是Linux管理日志轮转的标准工具。检查 /etc/logrotate.conf 和 /etc/logrotate.d/ 下的配置,确保日志文件能被定期压缩、轮转和删除。
3. 建立 Cron 自动化清理任务
让系统每周为你自动“打扫卫生”。
1 | # 编辑 root 用户的 crontab |
警告:
docker system prune的自动化需要谨慎,特别是--volumes参数,请确保你了解其后果。
附:Linux 系统清理命令速查表
这张速查表汇集了日常维护中最常用、最高效的清理命令,建议收藏备用。
| 目标 (Target) | 命令 (Command) | 描述 (Description) |
|---|---|---|
| 诊断工具 | ncdu -x / |
强烈推荐。交互式磁盘空间分析工具,快速定位空间占用大户。 |
| 诊断工具 | sudo find / -xdev -type f -size +1G |
查找并列出系统中所有大于1GB的单个文件,用于定位“巨型文件”。 |
| APT 缓存 (Debian/Ubuntu) | sudo apt clean |
删除所有缓存在 /var/cache/apt/archives/ 下的 .deb 安装包文件。 |
| APT 缓存 (Debian/Ubuntu) | sudo apt autoclean |
仅删除仓库中已不存在的(过时的).deb 包文件,比 clean 温和。 |
| 无用依赖 (Debian/Ubuntu) | sudo apt autoremove -y |
卸载为满足依赖而自动安装,但现在已不再需要的软件包。 |
| YUM/DNF 缓存 (CentOS/RHEL) | sudo yum clean all 或 sudo dnf clean all |
清理所有仓库缓存,包括元数据、软件包等。 |
| Systemd Journal 日志 | sudo journalctl --vacuum-size=200M |
将日志文件清理到指定大小(例如200MB)。立即见效。 |
| Systemd Journal 日志 | sudo journalctl --vacuum-time=2d |
仅保留指定时间段内的日志(例如最近2天)。 |
| 传统日志文件 | sudo truncate -s 0 /var/log/syslog |
安全地清空一个正在被使用的日志文件内容,无需重启服务。 |
| Docker (综合清理) | sudo docker system prune -f |
清理所有已停止的容器、悬空的镜像、无用的网络和构建缓存。 |
| Docker (彻底清理) | sudo docker system prune -a -f |
在上述基础上,额外删除所有未被任何容器使用的镜像。慎用! |
| Docker 数据卷 | sudo docker volume prune -f |
清理所有未被任何容器使用的本地数据卷。警告:数据会丢失! |
| Snap 包 (Ubuntu) | sudo snap list --all | grep disabled | awk '{print $1, $3}' | while read p r; do sudo snap remove "$p" --revision="$r"; done |
一键清理所有已禁用的旧版本Snap包,能释放大量空间。 |
| 用户缓存 | rm -rf ~/.cache/* |
清理当前用户的应用缓存。可能会导致应用首次启动变慢,但通常是安全的。 |
| 回收站 (桌面环境) | rm -rf ~/.local/share/Trash/* |
清空用户的回收站。 |