写点什么

服务器删除文件后磁盘空间没有立刻释放问题

作者:javaNice
  • 2023-11-10
    四川
  • 本文字数:2318 字

    阅读完需:约 8 分钟

服务器删除文件后磁盘空间没有立刻释放问题

🔊业务场景

发现一台服务器的磁盘空间不足,需要进行处理,登录后发现磁盘使用率已经 100%,操作删除了一些文件和日志信息后,查看空间仍然没有变化。

📖一、现象描述

操作系统: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
复制代码


然后 查看磁盘空间的使用情况,发现 / (根目录)的空间并没有发生变化


\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%。

🧣五、最后的话

🖲要熟练掌握技巧,一定多多练习:纸上得来终觉浅,绝知此事要躬行



发布于: 刚刚阅读数: 3
用户头像

javaNice

关注

还未添加个人签名 2023-11-02 加入

还未添加个人简介

评论

发布
暂无评论
服务器删除文件后磁盘空间没有立刻释放问题_Java_javaNice_InfoQ写作社区