解决Linux实例磁盘空间满问题
本文主要介绍Linux实例磁盘空间不足问题的调查和对应解决方法。
问题描述
在Linux系统的云服务器ECS实例内创建文件或者应用报错出现如下提示,即表示您的磁盘空间不足: No space left on device 。如果磁盘满是符合您预期的使用,则通过添加新云盘或者扩容云盘的方式即可解决,具体操作请参见 创建云盘 、 挂载数据盘 和 云盘扩容指引 。本文主要介绍当磁盘满是非您预期的使用,则可根据下文判断磁盘满的原因以及对应的解决方案。
问题原因
磁盘空间不足的问题通常是如下四类原因:
- 磁盘分区空间使用率达到100%。
- 磁盘分区Inode使用率达到100%
- 磁盘存在已删除未释放的僵尸文件。
说明:
已删除文件可能因删除时文件句柄被打开,导致文件删除时文件空间未能被释放。
挂载点覆盖。
说明:
在原有文件系统的目录下已经存在大量文件,挂载新磁盘后挂载点(目录)被覆盖。但您系统内应用可能还是继续读写原有文件系统空间,这时就有可能出现您的应用报空间不足,但您使用 df 或 du 命令查看磁盘文件目录的容量使用情况又统计不到,原因是 df 或 du 命令统计的是当前挂载点对应的分区使用情况。
解决方案
请根据不同的问题原因,通过以下方式进行处理。
一、磁盘分区空间使用率达到100%
您可以通过清理占用磁盘空间较大的文件或目录、扩容磁盘或新购磁盘等几种方式来解决磁盘分区空间使用率达到100%的问题。具体操作步骤如下:
清理占用空间较大的文件或者目录
- 远程连接ECS实例。具体操作,请参见 通过密码或密钥认证登录Linux实例 。
- 执行以下命令,查看磁盘使用率。
df -h
系统显示类似如下信息。例如,分区/dev/xvda1的使用率为15%。
3. 执行以下命令,进入根目录,查看哪个目录占用磁盘空间较大。
cd /
du -sh *
系统显示类似如下信息。图示例可以看出 /usr 目录占用空间最大,则需要继续查看 /usr 目录下哪个文件或目录占用空间较大。请您根据实际环境进行操作。
4. 执行以下命令,逐级查看哪个目录占用磁盘空间较大。例如本例中进入较大的 /usr 目录,继续查看 /usr 目录下哪个文件或目录较大。
cd /usr
du -sh *
系统显示类似如下信息。图示例可以看出 local 目录占用空间最大,则需要查看 local 目录下哪个文件或目录占用空间较大,以此类推。
5. 结合业务情况判断,删除不再使用的文件或目录。
扩容磁盘或新购磁盘
如果您无法通过清理文件释放更多空间,可以考虑通过扩容磁盘或者新购磁盘的方式来解决。具体操作,请参见 创建云盘 、 挂载数据盘 和 云盘扩容指引 。
二、磁盘分区Inode使用率达到100%
磁盘分区Inode使用率达到100%会造成您的应用无法继续新建目录或者文件,此时通常您系统内对应的磁盘空间还未用满,Inode用满也是平时容易被忽略的点。您可以通过清除Inode占用高的文件或者目录、或者增加Inode数量来解决磁盘分区Inode使用率达到100%的问题。
说明:
Linux的Inode节点中记录了文件的类型、大小、权限、所有者、文件连接的数目、创建时间与更新时间等重要的信息,以及指向数据块的指针信息。一般情况不需要修改Inode配置,如果存放文件较多导致Inode容量占满,就需要进行修改。
查询 Inode 使用率
- 远程连接ECS实例。具体操作,请参见 通过密码或密钥认证登录Linux实例 。
- 执行以下命令,查询Inode使用率。
df -i
3. 如果Inode使用率达到或者接近100%,可以通过以下两种方式进行处理:
- 清除Inode占用高的文件或者目录
- 修改Inode数量
清理 Inode 占用高的文件或者目录
如果不方便格式化磁盘以增加Inode数量,可以参考以下步骤,清理Inode占用量高的文件或者目录。
1. 执行以下命令,分析根目录下的每个二级目录下有多少个文件。
for i in /*; do echo $i; find $i | wc -l; done
系统显示类似如下信息。图示例可以看出 /usr 目录下的文件数最多,则需要继续查看 /usr 目录下哪个目录文件数最多,文件数越多说明Inode占用越高。请您根据实际环境进行操作。
2. 逐层进入Inode占用最高的目录,继续执行上述命令,逐步定位占用过高空间的文件或目录,最后进行相应清理。
增加 Inode 数量
如果不允许清理磁盘中的文件,或者清理完可清理的文件后Inode使用率仍然较高,则您需要通过备份数据、重新格式化磁盘增加Inode数、拷回数据等步骤,完成数据的保留并增加文件系统Inode数量。
警告
- Inode数量的调整需要重新格式化磁盘,磁盘内的数据将被删除,请确保数据已经得到有效备份后,再进行以下操作。您可以自行拷贝文件,也可以通过快照方式进行数据备份,创建快照的具体操作请参见 创建一个云盘快照 。
- Inode数量的调整需要卸载文件系统,这可能会导致您的应用服务中断,请选择您业务合适的时间进行。
1. 执行以下命令,卸载文件系统。
本示例以卸载 /home 为例,请您根据实际环境进行替换。
umount /home
2. 执行以下命令,重新建立文件系统,增加Inode节点数。
本示例以磁盘分区为/dev/xvdb、文件系统类型为ext3、Inode节点数为1,638,400为例,请您根据实际环境进行修改。
mkfs.ext3 /dev/xvdb -N 1638400
说明
Linux的Inode数通常是根据磁盘容量大小生成,一般是1:16KB的比例,以40 GB云盘为例,其Inode节点数通常为2,621,440,其支持的最大值是2^32(大约43亿),您可以根据实际的云盘容量大小乘于一定的放大系数(例如1.2)来选择您业务合适的Inode值。
3. 执行以下命令,重新挂载目录。
本示例将按照 /etc/fstab 配置将已卸载的目录再重新挂载,请您根据实际情况操作。
mount -a
4. (可选)执行以下命令,查看并确认修改后的Inode节点数。
dumpe2fs -h /dev/xvdb | grep node
系统显示类似如下信息,表示Inode数调整成功,您可以接着拷回备份数据,恢复相关应用。
三、存在僵尸文件
如果磁盘分区容量和Inode容量都没有问题,可能是系统中存在大量文件已经被删除(显示为deleted)但是仍被系统内进程占用,系统无法释放磁盘空间,且由于这部分文件已经被标记删除,通过 df 或 du 命令无法统计到。如果僵尸文件过多,会占用较大的磁盘空间。您可以参考以下步骤查看并删除僵尸文件。
- 远程连接ECS实例。具体操作,请参见 通过密码或密钥认证登录Linux实例 。
- 如果系统没有预装lsof,选择以下合适命令,安装lsof。
- Alibaba Cloud Linux、CentOS等系统
yum install -y lsof
- Debian、Ubuntu等系统
apt-get install -y lsof
3. 执行以下命令,查看僵尸文件占用情况。
lsof |grep delete | sort -k7 -rn | more
系统显示类似如下信息,其中第7列为对应文件的大小(单位为Byte),您可以将第七列值累加起来看总文件大小和您非预期的磁盘使用空间是否接近,接近即为僵尸文件占用了您磁盘空间。
4. 通过以下两种方式释放句柄,清除僵尸文件,释放磁盘空间。
- 重启服务器清除
重启服务器,系统会退出现有的进程,释放调用的deleted文件的句柄。
重要
重启服务器可能会影响业务,请您选择合适时间进行重启。
- 通过kill命令清除
根据 lsof 命令列出的PID进程号(通常为第二列),使用 kill 命令结束占用这些文件的服务进程。
i. 执行以下命令,列出PID进程号。
lsof |grep delete
ii. 根据您的业务情况,确保对应进程可以停止或者重启,执行以下命令,停止占用这些文件的服务进程。
kill <进程号>
重要
如果服务器正在运行业务,可能会影响到业务,请慎重操作。
四、挂载点覆盖
当您都排除了上述三个问题,还未找到非预期的磁盘空间使用,可能得原因是挂载点覆盖。您可以用下述方法进行确认。
如下图所示案例,您可以看到30 GB的系统盘/dev/vda1使用率已经到了95%,通过 du 可以看到,主要是 /home 目录占用了24 GB空间。
但当我们把/dev/vdb1挂载到 /home 目录后,如下图所示,可以看到系统盘/dev/vda1使用率还是95%,整个根分区下最大的目录仅有 /usr 占用超过1 GB,无法找到具体哪个目录占用高, /home 目录统计到的使用空间仅为20 KB,不是此前看到的24 GB空间占用,此现象即为挂载点覆盖。
解决挂载点覆盖的问题,通常通过先取消磁盘分区挂载,再检查原挂载目录下的空间占用情况。
警告
分区卸载可能会导致您的应用服务中断,请选择您业务合适的时间进行。