随着Linux实例上应用服务的持续运行,日志、缓存、业务数据等文件会不断累积,逐渐耗尽磁盘可用空间。一旦空间不足,新的数据将无法写入,会直接导致服务中断或功能异常。
故障现象
在Linux实例中创建文件或运行应用时,出现错误提示No space left on device
,表明存储资源已耗尽。
问题诊断和解决方案
在操作前请创建快照备份数据,防止误操作导致数据丢失,影响业务运行。
场景一:磁盘空间耗尽
查看磁盘使用率。
系统下执行
sudo df -h
,查看各挂载点的磁盘使用情况,若Use%
为100%,则说明对应空间已满。清理无用的文件或目录。
使用
sudo du -sh <目录名称>/*
,查看指定目录下的文件及子目录的大小。若有需要,可进入目录,逐级查看占用情况。例如使用
sudo du -sh /mnt/*
,查看/mnt
目录下文件及子目录占用空间的大小。若清理后仍空间不足,可扩容云盘。
场景二:Inode资源耗尽
每个文件都会占用一个Inode。如果磁盘上存在大量小文件,即使磁盘空间有剩余,Inode 也可能被耗尽,导致无法新建文件。
查看Inode使用率。
执行命令
sudo df -i
,若IUse%
达到100%,则表示Inode资源已耗尽。清理无用的文件或目录。
可使用
sudo du -sh --inodes <目录名称>/*
,查看指定目录下的文件及子目录占用的Inode数量。若有需要,可进入目录,利用此命令逐级查看占用情况。例如使用
sudo du -sh --inodes /mnt/*
查看/mnt
目录下文件及子目录占用空间的大小。若清理后Inode数仍不足,可扩容云盘。
场景三:存在已删除未释放空间的文件
即使一个文件被删除,只要仍有进程正在使用(即持有其文件句柄),系统就不会释放其占用的磁盘空间,直至进程终止或主动关闭文件后才会被真正回收。
安装
lsof
工具。已删除但未释放空间的文件无法通过
df
或du
指令查看,需要利用lsof
工具将其列出。Alibaba Cloud Linux、CentOS
sudo yum install -y lsof
Debian、Ubuntu
sudo apt install -y lsof
查看已删除文件未被释放的存储空间。
sudo lsof | grep delete | sort -k7 -rn | more
输出第7列为文件大小(单位Byte),累加可计算未释放空间总量。
记录占用进程的名称和PID。
执行
sudo lsof | grep delete
指令,通过COMMAND
和PID
字段获取进程名称和进程PID。重启或停止相关服务。
执行
sudo ps -ef | grep <PID>
,进一步确认进程用途,评估影响后重启或停止相关服务。重要重启或停止服务可能会影响业务,请谨慎评估,选择合适时间进行操作。
场景四:挂载点被覆盖。
非空目录被其他设备挂载后,其下数据虽会被隐藏,但已打开此目录的进程仍可写入覆盖空间。此类“隐藏”空间消耗无法通过df
命令观测,容易造成空间意外耗尽。
查看重复的目录信息。
运行
sudo lsblk
,查看MOUNTPOINT,记录重复挂载目录名称。$ sudo lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT vda 253:0 0 40G 0 disk ├─vda1 253:1 0 2M 0 part ├─vda2 253:2 0 200M 0 part /boot/efi └─vda3 253:3 0 39.8G 0 part / vdb 253:16 0 40G 0 disk └─vdb1 253:17 0 40G 0 part /mnt vdc 253:32 0 40G 0 disk └─vdc1 253:33 0 40G 0 part /mnt
示例中分区
vdb1
和vdc1
的挂载目录均为/mnt
,存在挂载点被覆盖风险。卸载文件系统。
重要卸载文件系统,可能导致依赖该路径的服务中断,请评估风险,选择合适的时间操作。
<重复挂载目录>
可通过上一步获取。sudo umount <重复挂载目录>
示例中
/mnt
为重复挂载目录,执行sudo umount /mnt
,可卸载最后挂载的设备vdc1
。获取被覆盖挂载点的设备名称。
运行
sudo df -h
,定位被覆盖挂载点的设备名称。$ sudo df -h
Filesystem Size Used Avail Use% Mounted on devtmpfs 3.7G 0 3.7G 0% /dev tmpfs 3.7G 0 3.7G 0% /dev/shm tmpfs 3.7G 524K 3.7G 1% /run tmpfs 3.7G 0 3.7G 0% /sys/fs/cgroup /dev/vda3 40G 4.5G 33G 12% / /dev/vda2 200M 5.8M 194M 3% /boot/efi /dev/vdb1 40G 40G 0 100% /mnt tmpfs 747M 0 747M 0% /run/user/0
示例中当前挂载至
/mnt
的分区名称为vdb1
,因此被覆盖挂载点的设备名称为vdb1
。解决磁盘空间满问题。
清理被覆盖空间中无用的文件或目录。
示例中,需要清理
vdb1
挂载的/mnt
目录。若清理后空间仍不足,可扩容云盘后,挂载至其他空目录下使用。
示例中,需要扩容的目标设备名称为
vdb1
。
请勿将多个设备挂载至同一目录。
多个设备挂载至相同目录,先挂载的设备空间会被隐藏,可能导致数据写入错误设备。请在后续使用中确保不同设备挂载至不同的空目录。
场景五:Docker相关文件占用空间较大。
Docker运行过程中会产生大量中间镜像、已停止容器和构建缓存,这些对象长期积累会占用磁盘空间。
查看Docker文件磁盘空间占用率。
执行
sudo df -h
,Filesystem
为overlay
的Use%
达到100%。确定Docker内部资源占用情况。
运行
sudo docker system df
命令,查看Size
和RECLAIMABLE
字段,确定文件占用情况。$ sudo docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 21 9 13.94GB 10.66GB(76%) Containers 9 5 30.09MB 0B(0%) Local volumes 6 6 259.9MB 0B(0%) Build Cache 0 0 0B 0B
示例中,
Docker
镜像占用13.94GB,其中10.66GB可回收,建议优先清理无用镜像。清理无用文件。
若Docker文件无法清理,可尝试依照场景一:磁盘空间耗尽处理问题。
清除所有已停止的容器:执行
sudo docker container prune
。清除所有dangling镜像(即无tag的镜像):执行
sudo docker image prune
。清除不再使用的构建缓存:执行
sudo docker builder prune
。
场景六:inotify watches达到上限。
执行类似sudo tail -f
命令时提示tail: cannot watch '...': No space left on device
,并非磁盘空间不足,而是用来跟踪文件和目录变化的inotify watches达到上限,需要提升。
查看当前inotify watches的上限值。
执行
sudo cat /proc/sys/fs/inotify/max_user_watches
命令,查看inotify watches
当前的上限值。提升inotify watches的上限值。
提升上限值可能导致inotify占用更多系统内存,在修改前请谨慎评估,
<新的上限值>
一般不建议超过524288。sudo sh -c "echo fs.inotify.max_user_watches=<新的上限值> >> /etc/sysctl.conf"
加载新配置。
执行
sudo sysctl --system
加载新配置并使其生效。验证配置结果。
再次执行
sudo cat /proc/sys/fs/inotify/max_user_watches
命令,确认已更新为预期的inotify watches
上限。