解决Linux实例磁盘空间满问题

随着Linux实例上应用服务的持续运行,日志、缓存、业务数据等文件会不断累积,逐渐耗尽磁盘可用空间。一旦空间不足,新的数据将无法写入,会直接导致服务中断或功能异常。

故障现象

Linux实例中创建文件或运行应用时,出现错误提示No space left on device,表明存储资源已耗尽。

问题诊断和解决方案

重要

在操作前请创建快照备份数据,防止误操作导致数据丢失,影响业务运行。

场景一:磁盘空间耗尽

  1. 查看磁盘使用率。

    系统下执行sudo df -h,查看各挂载点的磁盘使用情况,若Use%100%,则说明对应空间已满。

  2. 清理无用的文件或目录。

    使用sudo du -sh <目录名称>/*,查看指定目录下的文件及子目录的大小。若有需要,可进入目录,逐级查看占用情况。

    例如使用sudo du -sh /mnt/*,查看/mnt目录下文件及子目录占用空间的大小。
  3. 若清理后仍空间不足,可扩容云盘

场景二:Inode资源耗尽

每个文件都会占用一个Inode。如果磁盘上存在大量小文件,即使磁盘空间有剩余,Inode 也可能被耗尽,导致无法新建文件。

  1. 查看Inode使用率。

    执行命令sudo df -i,若IUse%达到100%,则表示Inode资源已耗尽。

  2. 清理无用的文件或目录。

    可使用sudo du -sh --inodes <目录名称>/*,查看指定目录下的文件及子目录占用的Inode数量。若有需要,可进入目录,利用此命令逐级查看占用情况。

    例如使用sudo du -sh --inodes /mnt/*查看/mnt目录下文件及子目录占用空间的大小。
  3. 若清理后Inode数仍不足,可扩容云盘

场景三:存在已删除未释放空间的文件

即使一个文件被删除,只要仍有进程正在使用(即持有其文件句柄),系统就不会释放其占用的磁盘空间,直至进程终止或主动关闭文件后才会被真正回收。

  1. 安装lsof工具。

    已删除但未释放空间的文件无法通过dfdu指令查看,需要利用lsof工具将其列出。

    Alibaba Cloud Linux、CentOS

    sudo yum install -y lsof

    Debian、Ubuntu

    sudo apt install -y lsof
  2. 查看已删除文件未被释放的存储空间。

    sudo lsof | grep delete | sort -k7 -rn | more

    输出第7列为文件大小(单位Byte),累加可计算未释放空间总量。image

  3. 记录占用进程的名称和PID。

    执行sudo lsof | grep delete指令,通过COMMANDPID字段获取进程名称和进程PID。

  4. 重启或停止相关服务。

    执行sudo ps -ef | grep <PID>,进一步确认进程用途,评估影响后重启或停止相关服务。

    重要

    重启或停止服务可能会影响业务,请谨慎评估,选择合适时间进行操作。

场景四:挂载点被覆盖。

非空目录被其他设备挂载后,其下数据虽会被隐藏,但已打开此目录的进程仍可写入覆盖空间。此类“隐藏”空间消耗无法通过df命令观测,容易造成空间意外耗尽。

  1. 查看重复的目录信息。

    运行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

    示例中分区vdb1vdc1的挂载目录均为/mnt,存在挂载点被覆盖风险。

  2. 卸载文件系统。

    重要

    卸载文件系统,可能导致依赖该路径的服务中断,请评估风险,选择合适的时间操作。

    <重复挂载目录>可通过上一步获取。

    sudo umount <重复挂载目录>
    示例中/mnt为重复挂载目录,执行sudo umount /mnt,可卸载最后挂载的设备vdc1
  3. 获取被覆盖挂载点的设备名称。

    运行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

  4. 解决磁盘空间满问题。

    1. 清理被覆盖空间中无用的文件或目录。

      示例中,需要清理vdb1挂载的/mnt目录。
    2. 若清理后空间仍不足,可扩容云盘后,挂载至其他空目录下使用。

      示例中,需要扩容的目标设备名称为vdb1
重要

请勿将多个设备挂载至同一目录。

多个设备挂载至相同目录,先挂载的设备空间会被隐藏,可能导致数据写入错误设备。请在后续使用中确保不同设备挂载至不同的空目录。

场景五:Docker相关文件占用空间较大。

Docker运行过程中会产生大量中间镜像、已停止容器和构建缓存,这些对象长期积累会占用磁盘空间。

  1. 查看Docker文件磁盘空间占用率。

    执行sudo df -hFilesystemoverlayUse%达到100%。

  2. 确定Docker内部资源占用情况。

    运行sudo docker system df命令,查看SizeRECLAIMABLE字段,确定文件占用情况。

    $ 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可回收,建议优先清理无用镜像。

  3. 清理无用文件。

    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达到上限,需要提升。

  1. 查看当前inotify watches的上限值。

    执行sudo cat /proc/sys/fs/inotify/max_user_watches命令,查看inotify watches当前的上限值。

  2. 提升inotify watches的上限值。

    提升上限值可能导致inotify占用更多系统内存,在修改前请谨慎评估,<新的上限值>一般不建议超过524288。

    sudo sh -c "echo fs.inotify.max_user_watches=<新的上限值> >> /etc/sysctl.conf"
  3. 加载新配置。

    执行sudo sysctl --system加载新配置并使其生效。

  4. 验证配置结果。

    再次执行sudo cat /proc/sys/fs/inotify/max_user_watches命令,确认已更新为预期的inotify watches上限。

相关文档

  • 对于海量静态文件(如图片、视频、归档)的存储需求,推荐使用对象存储OSS

  • 若需要高性能、高并发的文件共享,建议使用文件存储NAS来存储文件。

  • 针对大规模日志采集和分析的场景,可将日志存储到日志服务SLS,便于查询日志的同时,减少存储空间占用。