首页 > 代码库 > 经验分享-关于在linux下删除大文件后,磁盘空间没有得到释放的解决办法

经验分享-关于在linux下删除大文件后,磁盘空间没有得到释放的解决办法

这个博客很早就注册啦,但是一直没有更新,最近辞职闭关清修,争取每天写一篇技术博客~~

闲话不多说,直接开始切入正题啦~

事情发生在2014年的4月份,人生中的第一次跳槽,成功的入职一家刚刚起步的 CDN的公司,做了一名不称职的研发运维,当时正好赶上前任运维离职,最开始公司之前用的是多squid,由于公司现在的团队中对squid比较了解的人都走光了,在加上多squid有一个严重的弊端,就是本机多个squid进程之间缓存的内容是无法共享的,有的时候同一个文件则会被缓存多分,十分浪费磁盘空间,由于本机多个squid进程的调度算法当时做的也不完善,导致cache的命中率并不高......

(在这里要为不太了解squid的朋友们解释一下,为什么要在同一台服务器上要开启多个squid进程,squid是个比较“老牌”的反向代理cache软件,它采用的是单进程架构,效率比较低,为了提高效率,就在本机开了多个squid进程提供服务,这就是上面说的多squid)

根据以上遇到的种种问题,在加上公司迟迟没有招到对squid特别了解的研发人员(二三线城市...你懂的...)

当时就决定把业务上的多squid替换为nginx,个人认为用nginx做反向代理和cache,效率上会比squid高很多,原因主要有以下两点。

  1. nginx本身支持多进程,缓存在多个进程中是共享的,同一个文件不会被缓存多分。

  2. 配置更加方便灵活,可以把不同客户站点的配置文件分成多个子配置文件

当时公司的业务量还不是特别大的情况下,获得了老大的批准,准备慢慢的把公司的cache业务从squid迁移到nginx上,对整个架构进行一个改造。

nginx做cache试行了半个月后,和之前的squid对比,磁盘的利用率,以及命中率得到了明显提升~

(记得当时才刚刚做运维将近一年的时间,看见公司的cdn架构优化有了小进展,当时觉得成就感油然而生)

但是作为一个商用CDN,替换cache软件,对当前的架构进行修改哪是那么容易的事...因为把squid换成了nginx,日志的纪录格式也和以前完全不一样了,导致以前的日志收集系统,计费系统,缓存刷新推送系统,全都要重新去弄。

因为涉及到客户的计费,刷新等问题,当时就比较着急,自己也缺乏工作经验,自己写了个shell脚本+计划任务做了一个日志切割,日志切割处理的比较粗糙,在加上当时cache的max_size大小给的也不是很合适(当时缓存和日志是放在同一个分区下的...由于工作经验不足没有考虑到日志占用多少磁盘空间),结果给自己埋下了一个比较大的“坑”。


新架构正式上线了两个礼拜左右,之前埋下的定时炸弹终于爆发了,有几个地区的上层中转节点无法正常提供服务了,经过排查错误日志,最终确定是留给nginx做cache的分区已经快满了。

当时想的比较简单,满了就删日志呗,当时想着尽量不去删缓存,因为会降低命中率,而且日志文件占用的空间也比较大,当时就把当天的日志文件删掉了,但是磁盘的空间依旧没有得到释放。

之后,查看了下/data目录所有文件的总和,发现这个目录下所有文件的总和远远低于这个分区的大小,但是就是找不出占用磁盘最多的那个文件在哪里。。。


当时把业务通过lvs把业务切到其他的中转节点后,误打误撞的重启了一下服务器,结果,磁盘空间被释放了,回到了正常。


后来自己在网上搜那些大神们写的文档,才知道,这跟linux的文件删除原理有直接的关系!!

下面我就把大神们的文档所讲的这个知识点,言简意赅的描述一遍。

在linux系统中,想要彻底的删除一个文件,取决于两个“计数器”,这两个计数器一个是磁盘引用的“计数器”(记录了这个文件有几个硬链接),另一个则是内存引用的“计数器”(纪录了这个文件正在被几个进程所调用),当这两个“计数器”全部为0,也就是这个文件没有硬链接,没有任何进程在调用的时候,这个文件才会真正的被删除。


这就是之前明明删除了很大的日志文件,但是磁盘空间仍然不被释放的原因所在。

我们来分析一下。

当前的cache访问日志,正在被nginx占用着,直接rm删除了这个日志文件,其实只是将磁盘引用的“计数器”置为0,但是nginx的进程仍然在调用这个日志文件,往这个日志文件里面写东西,内存引用的“计数器”没有置为0,所以这个日志文件没有真正的被删除,导致空间无法被释放!!!


这时由于经验不足所犯下的错误。。。所以提醒和我一样的新手们注意,程序在运行的时候,正在写入的日志文件绝对不可以rm直接删除,即使删除了,空间也不会被释放。


最后做个补充~,在网上搜到了一条linux下的命令,可以查看到被删除,但是仍被程序占用的文件名一级路径。

lsof | grep del

以后大家碰上这种情况,可以使用这个命令查看一下,是不是有明明已经被删除,但是仍然被程序占用着的文件。


如果这个日志文件正在被程序写入,同时又想清空

可以使用下面的方法

cat /dev/null > /data/access.log






本文出自 “reBiRTH” 博客,请务必保留此出处http://suhaozhi.blog.51cto.com/7272298/1904976

经验分享-关于在linux下删除大文件后,磁盘空间没有得到释放的解决办法