10

Linux系统删除文件后空间并没有释放原因及解决方法

 2 years ago
source link: https://www.huhexian.com/32025.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Linux系统删除文件后空间并没有释放原因及解决方法

青山 2022-03-1510:12:42评论2770字

今日收到监控报警,发现一台服务器的磁盘空间不足,需要进行处理,登录后发现可利用率不足1%,进行相关查看和处理工作;但是操作删除了一些备份文件和日志信息后,查看空间仍然不足。

一、现象描述

操作系统:CentOS 6.8 x64

使用 df -h 命令,看见 / 根目录下磁盘空间已满(99%),于是手动清理大日志文件。

  1. [root@local ~]# df -h
  2. Filesystem Size Used Avail Use% Mounted on
  3. /dev/mapper/rootvg-LogVol00 59G 59G 0 100% /
  4. /dev/sda1 190M 13M 168M 8% /boot
  5. tmpfs 2.0G 0 2.0G 0% /dev/shm

通过 du -sh 命令,找到占用大量空间的日志文件,于是使用 rm -rf 删除了它。

  1. [root@local ~]# cd /var/nginx/logs/
  2. [root@local ~]# rm -rf t-access.log t-error.log

然后 查看磁盘空间的使用情况,发现 / (根目录)的空间并没有发生变化。但是可以看到 Used 发生了变化。

  1. [root@local ~]# df -h
  2. Filesystem Size Used Avail Use% Mounted on
  3. /dev/mapper/rootvg-LogVol00 59G 56G 0 100% /
  4. /dev/sda1 190M 13M 168M 8% /boot
  5. tmpfs 2.0G 0 2.0G 0% /dev/shm

这是怎么回事呢?

二、原因分析

未释放磁盘空间的原因:

在Linux或者Unix系统中,通过rm或者文件管理器删除文件将会从文件系统的文件夹结构上解除链接(unlink),然而假设文件是被打开的(有一个进程正在使用),那么进程将仍然能够读取该文件,磁盘空间也一直被占用。而我删除的是nginx的访问日志文件,在删除的时候该文件正在被使用。

三、解决办法

首先获得一个已经被删除的可是仍然被应用程序占用的文件列表。操作如下:

  1. [root@local ~]# lsof |grep deleted
  2. nginx 4399 root 38w REG 253,0 19304448 10835682 /var/nginx/logs/t-access.log (deleted)
  3. nginx 4399 root 39w REG 253,0 3502080 10835684 /var/nginx/logs/t-error.log (deleted)
  4. nginx 4401 nobody 38w REG 253,0 19304448 10835682 /var/nginx/logs/t-access.log (deleted)
  5. nginx 4401 nobody 39w REG 253,0 3502080 10835684 /var/nginx/logs/t-error.log (deleted)
  6. nginx 4402 nobody 38w REG 253,0 19304448 10835682 /var/nginx/logs/t-access.log (deleted)
  7. nginx 4402 nobody 39w REG 253,0 3502080 10835684 /var/nginx/logs/t-error.log (deleted)
  8. nginx 4403 nobody 38w REG 253,0 19304448 10835682 /var/nginx/logs/t-access.log (deleted)
  9. nginx 4403 nobody 39w REG 253,0 3502080 10835684 /var/nginx/logs/t-error.log (deleted)
  10. nginx 4404 nobody 38w REG 253,0 19304448 10835682 /var/nginx/logs/t-access.log (deleted)
  11. nginx 4404 nobody 39w REG 253,0 3502080 10835684 /var/nginx/logs/t-error.log (deleted)

从输出的结果可以看到 /var/nginx/logs/t-access.log 和 t-error.log 还在被使用中,所以导致未释放空间。

那么如何让进程释放呢?

方法1:直接 kill 掉相应的进程,或者停掉使用这个文件的应用,让操作系统自己主动回收磁盘空间。

由于还有其他项目正在使用该应用(nginx服务),所以不能停掉nginx服务,于是使用 kill 命令删除相应的进程。

  1. [root@local ~]# kill -9 4399
  2. [root@local ~]# kill -9 4401
  3. [root@local ~]# kill -9 4402
  4. [root@local ~]# kill -9 4403
  5. [root@local ~]# kill -9 4404

再次,查看磁盘空间的使用情况,发现空间已经被回收了。

  1. [root@local ~]# df -h
  2. Filesystem Size Used Avail Use% Mounted on
  3. /dev/mapper/rootvg-LogVol00 59G 56G 0 95% /
  4. /dev/sda1 190M 13M 168M 8% /boot
  5. tmpfs 2.0G 0 2.0G 0% /dev/shm

方法2:以后清理正在被读写的大日志文件时,直接使用 echo "" > xxx.log 命令,即直接将文件置空,并不影响服务的使用,文件大小也被控制下来,磁盘空间也释放了。

说明:

当Linux打开一个文件的时候,Linux内核会为每个进程在/proc/ 『/proc/nnnn/fd/文件夹(nnnn为pid)』建立一个以其pid为名的文件夹用来保存进程的相关信息,而其子文件夹fd保存的是该进程打开的全部文件的fd(fd:file descriptor)。

kill进程是通过截断proc文件系统中的文件能够强制要求系统回收分配给正在使用的的文件。这是一项高级技术,仅到管理员确定不会对执行中的进程造成影响时使用。应用程序对这样的方式支持的并不好,当一个正在使用的文件被截断可能会引发不可预知的问题。

四、删除原理

一般来说,不会出现删除文件后空间不释放的情况,但是也存在例外,比如文件被进程锁定,或者有进程在使用这个文件,例如输出日志文件,要了解这个问题,就需要知道Linux下文件的存储机制和存储结构。

一个文件在文件系统中由两个部分构成:数据和指针。指针位于文件系统的meta-data中,数据被删除后,指针被清除,而数部分还是存储在磁盘中,只不过数据对应的指针被清除后,文件数据部分占用的空间就可以被覆盖了。之所以出现删除大文件后,空间还没有释放,就是因为有进程一直在使用这个文件的指针,日志文件的服务还在运行,导致虽然删除了日志大文件,但文件对应的指针部分由于被进程锁定,并未从meta-data中清除,而由于指针并未被删除,那么系统就认为文件并未被删除,所以使用 df 命令查看还是 100%。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK