/dev/sdb2分区磁盘占用显示异常,如何排查缺失的30GB空间?
兄弟,这种“空间明明没占满却提示用尽”的情况我碰过好多次,别慌,咱们一步步捋,肯定能揪出那消失的30GB!
先确认基础状态
先把当前的磁盘和inode使用情况摸清楚,跑这两个命令:
df -h /dev/sdb2:查看空间总大小、已用、可用的具体数值df -i /dev/sdb2:查看inode的使用情况(有时候inode被占满,哪怕磁盘空间还有剩余,也会提示空间不足)
如果inode使用率接近100%,那问题大概率是大量小文件耗尽了inode,可以直接跳到最后一步排查小文件。
排查1:被进程“抓着不放”的已删除文件
Linux里有个常见的坑:如果文件被删除,但还有进程在打开它,那磁盘空间不会被释放。这时候用df看已用空间很大,但du统计的实际文件大小却小很多。
跑这个命令找出这类“隐形”占用的文件:
lsof | grep deleted
在结果里找对应/dev/sdb2挂载路径的条目,看看哪个进程占用了已删除的大文件。解决办法要么重启对应的进程,要么用kill命令终止(注意:系统关键进程别乱杀,先确认进程用途),处理完之后空间就会自动释放。
排查2:隐藏的大文件/目录
有时候大文件藏在你看不到的地方,比如隐藏目录、系统临时文件,或者被忽略的日志文件。
- 先找到
/dev/sdb2的挂载点,用df -h | grep /dev/sdb2就能看到,比如挂载在/data下。 - 统计挂载点下所有目录的大小:
du -sh /data/*
看哪个目录异常大,然后逐层往下钻(比如du -sh /data/logs/*),直到定位到大文件。
3. 直接找挂载点下的超大文件(比如大于1GB的):
find /data -type f -size +1G
- 别忘了查看隐藏文件/目录,用
ls -la /data就能看到.开头的项目,有些隐藏的备份文件或者缓存文件可能占了大量空间。
排查3:挂载点被覆盖导致的“隐形文件”
如果后来在/dev/sdb2的挂载目录下又挂载了其他分区,那原来挂载目录里的文件会被“盖住”,看不到但依然占用空间。
比如假设/dev/sdb2挂载在/data,后来你把/dev/sdb3挂载到了/data/temp,那原来/data/temp里的文件就看不到了,但还占着/dev/sdb2的空间。
解决办法:
- 先卸载覆盖的挂载点:
umount /data/temp - 然后用
du -sh /data/temp看这个目录的大小,如果确实有文件,处理完之后再重新挂载。
排查4:文件系统预留空间或快照占用
- ext系列文件系统预留空间:ext2/ext3/ext4默认会给root用户预留5%的空间,用来在磁盘满的时候让root还能操作。如果你的分区很大(比如600GB),5%就是30GB,刚好对应你缺失的空间!可以用这个命令查看预留大小:
tune2fs -l /dev/sdb2 | grep Reserved
如果确实是这个原因,你可以调整预留比例,比如改成1%:tune2fs -m 1 /dev/sdb2(注意:调整前确认不需要这么多预留空间)。
- 快照占用:如果用的是btrfs、zfs这类支持快照的文件系统,快照会占用额外空间。可以用对应命令查看:
- btrfs:
btrfs filesystem df /data或者btrfs subvolume list /data - zfs:
zfs list -t snapshot
如果快照占了空间,可以清理掉不需要的快照。
- btrfs:
排查5:inode耗尽的情况(如果之前df -i显示inode满了)
如果inode使用率接近100%,说明你的分区里有大量小文件,比如缓存文件、日志碎片等。找这些小文件的方法:
find /data -type f | wc -l
先看总文件数,然后找文件最多的目录:
for dir in /data/*; do echo "$(find $dir -type f | wc -l) $dir"; done | sort -nr
找到文件最多的目录后,清理掉不需要的小文件就行。
备注:内容来源于stack exchange,提问作者manaclan

