No space left on device是Linux系统里最让人头疼的报错之一,它意味着写入操作已经没有可用空间。但奇怪的是,很多时候用df命令一看,磁盘明明还有大量剩余空间,报错却依然存在。这篇文章就来把这个错误拆开讲清楚:它到底是谁报的、空间去哪了、以及怎么彻底解决。

一、为什么磁盘没满还是报错:理解错误背后的两种空间
这个错误信息的本质是文件系统在分配存储资源时失败了。而Linux文件系统里存在两种会被耗尽的资源:一种是数据块,也就是通常理解的磁盘空间;另一种是inode,负责存储文件的元信息。每个文件无论大小,至少占用一个inode。如果系统中存在海量的小文件,比如邮件队列、session缓存文件、消息队列的分片数据,inode就可能先于数据块被耗尽,此时df显示磁盘还有空闲,但任何新建文件的请求都会失败。
除了inode问题,还有一种更隐蔽的情况:某些大文件已经被删除,但由于仍有进程持有它的文件句柄,内核不会真正释放这些空间。表面上文件不存在了,df却显示磁盘满载。这类问题在高频写入日志的场景中非常常见,比如用rm直接删除了正在被写入的日志文件。
理解了这两种机制,排查思路就清晰了:先用df确认数据块是否耗尽,再用df -i确认inode是否耗尽,最后用lsof检查被删除但仍被占用的文件。
二、标准排查流程:从df到具体目录定位
第一步执行df -h查看整体磁盘使用情况。注意观察两个地方:一是使用率是否达到100%,二是挂载点列表。有时磁盘本身没满,而是某个独立的挂载点(比如/tmp、/var单独分区)满了,报错只影响部分目录的写入。
# 查看各分区使用情况 df -h # 查看 inode 使用情况 df -i
如果确认某分区满了,接下来用du逐层定位大目录。这里有个实用技巧:直接用sort排序找出当前层级下最大的目录。
# 查看根分区下各目录占用,按大小排序取前10 du -h --max-depth=1 / 2>/dev/null | sort -rh | head -n 10 # 进入可疑目录后继续逐层下钻 cd /var && du -h --max-depth=1 | sort -rh | head -n 10
定位到具体目录后,通常能发现几类典型的大文件:膨胀的应用日志、core dump文件、Docker镜像与容器日志、yum或apt的缓存包。清理时优先使用应用自带的清理机制,例如日志系统本身的轮转配置,而不是简单地rm掉文件。
针对inode耗尽的情况,du的定位方式要反过来:问题不在于哪个目录占用空间大,而在于哪个目录文件数量多。可以用下面的命令统计各目录的文件数。
# 统计指定目录下的文件总数 find /var -xdev -printf . | wc -c # 找出当前目录下文件数最多的子目录 for d in */; do echo "$(find "$d" -type f | wc -l) $d"; done | sort -rn | head
三、处理已删除但未释放的文件句柄
当df显示磁盘100%满,但du统计所有目录加起来却对不上时,几乎可以断定存在被删除但仍被进程占用的文件。这种情况的典型来源是:日志文件被rm删除,但Nginx、Java应用等进程依然持有写句柄,空间无法回收。
# 查找已删除但仍被进程占用的文件,按大小排序
lsof -nP | grep '(deleted)' | sort -k7 -rn | head -n 10
# 按进程查看打开的大文件
lsof -p $(pgrep -f java) | awk '$7 > 100000000 {print}'解决这类问题有两种方式。温和的方式是通过kill -HUP给进程发送信号,让日志类的守护进程重新打开日志文件(前提是进程支持该行为)。直接的方式是重启对应进程,内核随即释放句柄和空间。切记以后清理正在写入的日志时,推荐用truncate -s 0 文件名清空内容而非删除文件,这样句柄不受影响,空间立即回收。
四、进阶场景与预防措施
有几个容易被忽略的场景值得一提。一是挂载点被数据覆盖:如果新磁盘挂载到/opt之前,/opt下已写入了大量文件,挂载后这些文件被新分区遮盖,看似消失却仍占着底层空间,需要临时挂载到其他位置后再清理。二是文件系统预留空间:ext4默认为root预留5%的空间,普通用户在磁盘用到95%时就会遇到报错,可以用tune2fs -m 1 /dev/sda1调低预留比例。三是根分区确实不够用的情况,需要通过LVM扩容或新增磁盘挂载来解决,而不是反复删文件。
预防永远比救火省事。建议在监控体系中加入两项指标:磁盘使用率阈值告警(一般设置80%警告、90%严重)和inode使用率告警,后者常被遗漏却是小文件场景的致命项。同时为所有日志配置logrotate策略,限制单个文件大小和保留份数,对Docker环境定期执行镜像清理。把这套流程固化成运维规范后,No space left on device基本不会再在深夜把你叫醒了。
No space left on deviceLinux磁盘空间inode耗尽修改时间:2026-09-06 09:58:32