适用:所有 Linux 耗时:约 25 分钟 前置:E3(会看日志)
磁盘满是最常见的故障,也是最容易搞砸的——很多人为了腾空间,删错了东西,把系统搞坏了。
这一篇只讲两件事:怎么找到谁在吃空间,怎么安全地清。
一、先理解 Linux 的"盘"是怎么组织的
没有 C 盘 D 盘,只有一棵树
Windows:C:\ D:\ 各是一棵树
Linux:只有一棵树,从 / 开始。所有磁盘都"挂"在这棵树的某个目录上。
/ ← 根,"整棵树"
├── home/ ← 用户文件(最占地方,也最能清)
├── var/ ← 日志、数据库、网站(第二占地方)
├── usr/ ← 程序本体(别手删)
├── etc/ ← 配置(别手删)
├── tmp/ ← 临时文件(可以清)
├── boot/ ← 内核和引导(**动了开不了机**)
└── mnt/ media/ ← 外接盘、U 盘挂在这
关键概念:
- 分区(partition)= 硬盘上的一块
- 挂载(mount)= 把某个分区"接"到树上某个目录
- 挂载点(mount point)= 那个目录
# 看谁挂在哪
findmnt
# 或
mount | column -t
为什么"加硬盘"不等于"空间变大"
新手常问:“我加了一块 1T 硬盘,为什么 /home 还是满的?”
因为硬盘还没挂到 /home 上。 装了硬盘 ≠ 用了硬盘,必须挂载。
二、df:全局视角,谁满了
df -h
输出:
文件系统 容量 已用 可用 已用% 挂载点
/dev/vda1 49G 35G 13G 74% /
/dev/vdb1 100G 20G 75G 21% /data
tmpfs 1.8G 1.2M 1.8G 1% /run
只看四列:容量 已用% 挂载点 文件系统
关键判断:
/到 85% 以上就该处理 —— 到 100% 系统会出各种怪问题(连图形界面都可能起不来)tmpfs是内存盘,不用管- 加到 90% 以上,日志可能写不进去,服务会开始报错
只关心真实磁盘:
df -h -x tmpfs -x devtmpfs
三、du:找到具体是谁在吃
df 告诉你"哪个盘满了",du 告诉你"哪个目录占的"。
从根开始逐层下钻
sudo du -sh /* 2>/dev/null | sort -h | tail -10
sort -h 是按人类可读的大小排序(自动识别 K/M/G),这是关键——用普通 sort 会按字符串排,9G 会排在 10G 前面。
然后进最大那个继续:
sudo du -sh /var/* 2>/dev/null | sort -h | tail -10
sudo du -sh /var/log/* 2>/dev/null | sort -h | tail -10
三步之内,一定找到元凶。
一次看到底(不用逐层下钻)
sudo du -h --max-depth=2 / 2>/dev/null | sort -h | tail -20
--max-depth 控制深度。2 层一般够,3 层太慢。
找大文件(不是大目录)
sudo find / -type f -size +500M -exec ls -lh {} \; 2>/dev/null | awk '{print $5, $9}'
列出所有大于 500M 的文件。 有时候是一个巨大的日志文件或镜像文件。
四、Linux 最坑的一个现象:df 满了,du 加起来却很少
这是新手最容易卡死的地方。
现象
df -h
# / 100% 已用
sudo du -sh /*
# 加起来才 20G,但盘有 49G
差了 30G,找不到。
原因
有个文件被删了,但还有进程开着它。
Linux 的规则:文件被 rm 时,如果还有进程持有它的句柄,文件不会真正释放——空间继续占着,但 du 看不到(因为目录项已经没了)。只有进程关闭句柄,空间才真正释放。
怎么找
sudo lsof +L1
或者:
sudo lsof | grep deleted
输出里 SIZE/OFF 那列就是占的空间。
怎么修
重启那个进程(不是删文件——文件已经删了):
sudo systemctl restart 那个服务
或者找到 PID 直接停:
kill -15 PID
空间立刻释放。
典型场景:nginx 的
access.log被rm了,但 nginx 还在往里写 → 磁盘满但找不到文件。 正确做法:日志不要rm,要清空:> /var/log/nginx/access.log(这个操作不改变 inode,进程句柄仍然有效)。
五、安全清理:按这个顺序
从最安全的开始,一步步往下。任何时候停下来都不影响系统。
第 1 级:完全安全,随时可清
# apt 缓存(Debian 系)
sudo apt clean
# dnf 缓存(RPM 系)
sudo dnf clean all
# 用户缓存
rm -rf ~/.cache/*
# 缩日志到 500M
sudo journalctl --vacuum-size=500M
# 清 /tmp 里超过 7 天的
sudo find /tmp -type f -atime +7 -delete
这五条清完,一般能腾出几 G,且零风险。
第 2 级:安全,但要先看
# 旧内核(占几百 M 到几 G)
sudo apt autoremove --purge
# 看有多少旧内核
dpkg --list | grep linux-image
# 你自己下载的东西
du -sh ~/下载/* | sort -h | tail -10
du -sh ~/.local/share/Trash/* # 回收站
第 3 级:需要判断
# Docker(如果装了)
docker system df # 先看占多少
docker system prune -a # 清掉没用的镜像和容器
⚠️
docker system prune -a会删掉所有没在运行的容器和镜像。有在用的会保留,但会删掉你 pull 过但暂时没用的镜像——下次用要重新下载。
⚠️ 绝对不要动的
| 目录 | 为什么 |
|---|---|
/boot | 删了开不了机 |
/usr | 系统程序本体 |
/etc | 配置 |
/lib /lib64 | 系统库,删了什么都跑不起来 |
/var/lib | 数据库、包管理器状态(乱删会导致系统无法更新) |
这些地方出了问题,正确做法是重装或从备份恢复,不是手删。
六、挂载:接一块新硬盘
临时挂载(重启失效)
# 1. 看系统认到新盘没
lsblk
# 输出里多出一个 sdb(没有挂载点)
# sdb
# └─sdb1
# 2. 建挂载点
sudo mkdir -p /data
# 3. 挂上去
sudo mount /dev/sdb1 /data
# 4. 验证
df -h | grep data
永久挂载(写进 /etc/fstab)
必须先拿到分区 UUID(比 /dev/sdb1 稳定,因为设备名可能变):
sudo blkid /dev/sdb1
# /dev/sdb1: UUID="a1b2c3d4-..." TYPE="ext4"
编辑 fstab:
sudo cp /etc/fstab /etc/fstab.bak-$(date +%Y%m%d) # ⚠️ 先备份!
sudo nano /etc/fstab
加一行:
UUID=a1b2c3d4-... /data ext4 defaults,nofail 0 2
关键参数 nofail:如果这块盘坏了或没插,开机不会卡住。 不加这个,盘一坏系统就起不来。
测试(不要直接重启!):
sudo mount -a
没报错 = 配置正确。报错就赶紧改回来,否则下次开机会进紧急模式。
⚠️
fstab写错会导致系统开不了机。 这是新手最容易造成"系统损坏"的操作。 改了 fstab,一定要先sudo mount -a验证,再重启。
七、动手:四个练习
练习 1:看清自己的磁盘布局
df -h -x tmpfs -x devtmpfs
sudo lsblk
findmnt | head -20
把「哪个分区挂在哪」搞清楚。
练习 2:找出前 3 个最占地方的目录
sudo du -sh /* 2>/dev/null | sort -h | tail -3
只看,不动。
练习 3:安全清理一次
# 先记录清理前
df -h /
sudo apt clean
sudo journalctl --vacuum-size=200M
rm -rf ~/.cache/*
# 再看清理后
df -h /
对比一下腾出了多少。
练习 4:验证 fstab 配置(不改,只验证)
sudo mount -a
echo "退出码: $?"
退出码 0 = 当前 fstab 配置正确。 养成改完就跑一下的习惯。
八、验证:你过关了吗
- 会用
df -h看哪个分区满了 - 会用
du -sh * | sort -h逐层下钻 - 知道
df和du对不上时用lsof +L1 - 知道日志要用
>清空而不是rm - 知道哪些目录绝对不能删
- 会挂载新磁盘,会用 UUID 写 fstab,知道
nofail的作用 - 改完 fstab 会先
mount -a验证
九、不行怎么办
Q1:df 和 du 都算不出空间去哪了
可能是被删除但被打开的文件(见第四节),也可能是inode 用完了:
df -i # 看 inode 使用率
inode 满了也是"磁盘满"的一种——表现为无法创建新文件,但 df -h 显示还有空间。
原因:某个目录里有几百万个小文件(常见于日志目录、缓存目录、邮件队列)。
修法:找出小文件最多的目录,批量清理:
sudo find /var -type f | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -10
Q2:mount 报 unknown filesystem type 'ntfs'
sudo apt install ntfs-3g # Debian 系
sudo dnf install ntfs-3g # RPM 系
Q3:挂载后目录里是空的 / 原来的文件不见了 挂载会"遮住"挂载点原来的内容。 卸载后就回来了:
sudo umount /data
所以挂载点应该用空目录。
Q4:umount 报 target is busy
有进程在用这个目录:
sudo lsof +D /data # 看谁在用(大目录会慢)
sudo fuser -mv /data # 更快
先退出来,或者杀掉进程,再卸载。
Q5:权限问题,普通用户挂不了盘
挂载需要 root。日常用图形界面会自动处理;命令行一律 sudo。
Q6:扩容了云盘,但 df 还是老大小
扩容分两步:① 云控制台扩大磁盘 ② 系统内扩展文件系统。
# 先看分区
sudo lsblk
# ext4 扩展(分区已经是新的,只需扩文件系统)
sudo resize2fs /dev/vda1
# xfs
sudo xfs_growfs /
如果分区本身也没扩,还需要 growpart:
sudo growpart /dev/vda 1
sudo resize2fs /dev/vda1
十、一句话总结
df看哪个盘满,du找谁占的,sort -h排序,逐步下钻。
df满但du找不到 →lsof +L1(文件被删但进程还开着)。清理从
apt clean开始,/boot和/usr永远别碰。
← 上一篇 E4|网络排查 下一篇 → E6|Shell 脚本:把重复操作变成一条命令