LINUX运维实战案例之文件已删除但空间不释放问题的分析与解决办法

1.错误现象

运维监控系统发送通知,服务器空间已满。
登录服务器,检查根分区确实没有空间,如下图:

这里先讲解一下服务器的一些删除策略。
由于Linux没有回收站功能,所以我们在线服务器上所有要删除的文件都会先移动到system/tmp目录下,然后定期清除/tmp目录下的数据。
这个策略本身并没有什么问题,但是经过检查发现,这台服务器的系统分区没有单独的/tmp分区,所以/tmp下的数据实际上占用了根分区的空间。
现在问题已经找到了,只要删除/tmp目录下的一些大数据就可以了。
执行以下命令查看/tmp下最大的三个数据文件,如下图:

[root@localhost~]#du-s/tmp/*|sort-nr|head-3

69206016/tmp/access_log

36/tmp/hsperfdata_root

36/tmp/hsperfdata_mapred

通过命令输出发现有/tmp目录下的文件66G大小的文件access_log,这个文件应该是apache生成的access日志文件。
从日志大小来看,应该是apache日志文件很久没有清理了。
基本确定是这个文件导致根空间满了。
确认该文件可以删除后,执行如下删除操作:

[root@localhost~]#rm/tmp/access_log

然后检查系统根分区是否存在空间被释放,如下图:

从输出中可以看到,根分区空间仍然没有释放。
这是怎么回事?

2.解决思路

一般来说,删除文件后空间不会被释放,但也有例外,比如文件被进程锁定,或者有进程不断访问该文件。
这个文件写入数据等,要理解这个问题,需要了解Linux下文件的存储机制和存储结构。

文件在文件系统中的存储分为两部分:数据部分和指针部分。
该指针位于文件系统的元数据中。
数据被删除后,指针从元数据中删除。
被清除,数据部分存储在磁盘中。
将元数据中数据对应的指针清除后,就可以覆盖文件数据部分占用的空间,写入新的内容。
出现删除的原因访问access_log文件后,空间还没有释放,因为httpd进程还在向这个文件写入内容。
结果,虽然access_log文件被删除,但由于进程锁定,该文件对应的指针并没有从元数据中清除。
由于指针没有被删除,系统内核就认为文件没有被删除,所以通过df命令没有释放空间也就不足为奇了。

3.故障排除

现在我们有了解决问题的想法,让我们看看是否有进程一直在向acess.log文件写入数据。
这里需要Linux。
lsof命令下的转到/tmp/aces下的s.log文件被httpd进程锁定,而httpd进程一直在向该文件写入日志数据。
从第七列我们可以看到,这个日志文件的大小只有70G,系统根分区的总大小也只有100G。
可以看出,这个文件就是导致系统根分区空间不足的罪魁祸首。
最后一列的“已删除”状态表示该日志文件已被删除,但由于进程仍在向该文件写入数据,因此空间尚未释放。

4.解决问题

至此至此,问题已经基本解决了。
有很多方法可以解决此类问题。
最简单的方法是关闭或重新启动httpd进程。
当然你也可以重新启动操作系统,但这不是最好的方法。
对于这种不断向文件写入日志的进程,释放文件占用的磁盘空间的最好方法就是在线清除该文件。
可以通过以下命令完成:

[root@localhost~]#echo""/tmp/acess.log

通过这种方法,不仅可以节省磁盘空间立即释放,同时也保证进程继续将日志写入文件。
该方法常用于清理Apache、Tomcat、Nginx等Web服务生成的在线日志文件。
感谢您的阅读,希望对大家有所帮助,请继续关注ScriptHouse,我们会努力分享更多优秀文章。

Linux如何查看文件是被那个进程占用写数据?

检查哪个进程持有文件并写入信息是运维和开发中常见的问题。
Linux系统提供了不同的方法来解决这个问题。
本文详细介绍了如何使用命令行工具查找正在写入特定文件的进程。
首先,我们可以使用“lsof”命令查看哪些进程打开了该文件。
例如,要查看myfile.txt被哪些进程使用,请运行lsof/path/to/myfile.txt。
如果lsof没有得到结果,可能是因为进程在执行其他任务时被中断或阻塞。
在某些情况下,“lsof”可能无法直接检测到写入文件的过程。
此时我们需要使用更高级的工具,例如“SystemTap”。
`SystemTap`是一个内核级监控和故障排除工具,用于分析和调试系统行为。
要使用“SystemTap”,您必须首先安装相关软件包。
在CentOS7中可以通过执行`yum-yinstallsystemtap`来安装。
我们可以使用SystemTap的inodewatch.stp工具来监视文件系统活动。
运行命令`systemtap-e'inodewatch("/path/to/myfile.txt")'',监视输出并找出写入文件的过程。
一旦获得了文件写入进程的进程号,就可以使用“ps”命令来查看进程详细信息,例如“ps-ef|grep”。
这样你就可以清楚地看到哪个进程正在写入指定的文件。
在某些情况下,您可能需要中止写入文件的过程,以防止文件被覆盖或生成不必要的数据。
一般来说,直接终止进程可能不是最佳实践,因为这可能会导致应用程序崩溃或数据丢失。
在某些情况下,您可能需要中断这些进程,例如执行数据备份或执行系统维护时。
正确的方法是在结束流程之前首先确保数据被安全地存储或处理。
如果一个进程在后台运行并继续循环写入文件,例如使用“iostat”命令进行监视时,可以使用“SIGSTOP”或“SIGKILL”标志来终止该进程或“stap`工具用于更多控制和控制。
综上所述,通过`lsof`、`SystemTap`和`ps`命令可以准确检测写入文件的过程。
当需要中断这些进程时,数据安全稳定请务必小心操作,以确保系统运行。