解决进程文件句柄泄露导致磁盘空间无法释放问题
2018-02-10 13:14
375 查看
解决进程文件句柄泄露导致磁盘空间无法释放问题
问题的产生
今天突然接到一台服务器磁盘空间使用率达到90%的报警,于是登陆机器查看磁盘使用情况,发现确实外挂到/data的一块磁盘使用率达到了90%:[root@awsuw7-46 data]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda2 100G 17G 84G 17% / devtmpfs 30G 0 30G 0% /dev tmpfs 29G 0 29G 0% /dev/shm tmpfs 29G 2.7G 27G 10% /run tmpfs 29G 0 29G 0% /sys/fs/cgroup /dev/xvdf 246G 209G 26G 90% /data tmpfs 5.8G 0 5.8G 0% /run/user/1000 tmpfs 5.8G 0 5.8G 0% /run/user/1003
分析问题
对于这种情况我一般的处理方法是跳到对应的目录,查看哪个目录占用的空间比较大,然后进一步清理。由于这块磁盘是外挂到/data目录,因此查看下该目录下各个目录磁盘的占用情况:[root@awsuw7-46 data]# du -h --max-depth=1 3.7G ./photo 16K ./lost+found 9.1G ./mls2 36K ./parser 79G ./web 15G ./mls 106G .
可以发现一个奇怪的现象:该外挂目录总共才使用了106G,但是df -h显示的是该磁盘已经使用了209G,那么使用的另外那103G去哪儿了呢,况且这块磁盘也没有多个分区,就这一个分区且挂载到了/data下。这确实是个很奇怪的问题,于是网上搜索了下原因,原来是不正确的删除文件导致的:
在Linux操作系统中,当一个文件被删除后,在文件系统目录中已经不可见了,所以du就不会再统计它了。然而如果此时还有运行的进程持有这个已经被删除了的文件的句柄,那么这个文件就不会真正在磁盘中被删除, 分区超级块中的信息也就不会更改,所以df命令查看的磁盘占用没有减少。我们知道在Linux中磁盘分区的超级块是非常重要的,在superblock中记录该分区上文件系统的整体信息,包括inode和block的总量,剩余量,使用量,以及文件系统的格式等信息。因此,superblock不更新,那么磁盘的使用量必然不会变化,操作系统对于文件的存盘都是需要事先读取superblock的信息,然后分配可用的inode和block。
解决问题
1.首先找出文件句柄泄露的进程,我的方法比较low,找出系统中启动时间比较久的java进程(因为这台机器主要是java服务),然后用lsof看这个进程的文件句柄使用情况。之所以这么做主要是因为最近启动的进程发生句柄泄露的可能性很小,因为即使存在句柄泄露,重启后也会释放文件句柄的。可以看出2962这个进程最可能发生句柄泄露了。[root@awsuw7-46 data]# ps -eo pid,lstart,comm | grep java 746 Thu Jan 18 19:44:15 2018 java 1117 Thu Feb 8 02:20:03 2018 java 1160 Thu Feb 8 02:20:09 2018 java 2962 Thu Nov 16 23:08:40 2017 java 3610 Wed Feb 7 22:55:37 2018 java 4579 Thu Feb 8 20:45:09 2018 java 5155 Mon Dec 25 19:01:32 2017 java 6481 Wed Jan 10 05:16:28 2018 java 6519 Thu Jan 18 00:51:07 2018 java 9756 Thu Feb 8 02:36:23 2018 java
2.使用lsof分析上面找到的进程文件句柄使用情况,可以看出该进程确实存在句柄泄露,而且非常严重,已经有2208个文件没有释放了:
[root@awsuw7-46 ~]# lsof -p 2962 | grep "delete" | wc -l 2208 [root@awsuw7-46 ~]# lsof -p 2962 | grep "delete" | head -n 20 java 2962 web 17r REG 202,2 2098273 17844538 /tmp/winstone962950350375526798.jar (deleted) java 2962 web 168w REG 202,80 0 1969499 /data/web/mls/data/jobs/mls_91/builds/590/23.log (deleted) java 2962 web 325w REG 202,80 0 6455947 /data/web/mls/data/jobs/mls_39/builds/1080/10.log (deleted) java 2962 web 341w REG 202,80 0 1975873 /data/web/mls/data/jobs/mls_113/builds/1054/29.log (deleted) java 2962 web 347w REG 202,80 0 2506849 /data/web/mls/data/jobs/mls_59/builds/.1073/21.log (deleted) java 2962 web 350w REG 202,80 8192 1975877 /data/web/mls/data/jobs/mls_113/builds/1054/31.log (deleted) java 2962 web 352w REG 202,80 0 5387403 /data/web/mls/data/jobs/mls_80/builds/505/23.log (deleted) java 2962 web 354w REG 202,80 0 3422611 /data/web/mls/data/jobs/mls_29/builds/.385/23.log (deleted)
3.重启上面找到的发生内存泄露的进程,发现磁盘使用量回归正常状态:
[ec2-user@awsuw7-46 ~]$ df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda2 100G 17G 84G 17% / devtmpfs 30G 0 30G 0% /dev tmpfs 29G 0 29G 0% /dev/shm tmpfs 29G 2.7G 27G 10% /run tmpfs 29G 0 29G 0% /sys/fs/cgroup /dev/xvdf 246G 128G 106G 55% /data tmpfs 5.8G 0 5.8G 0% /run/user/1000 tmpfs 5.8G 0 5.8G 0% /run/user/1003 tmpfs 5.8G 0 5.8G 0% /run/user/1005 tmpfs 5.8G 0 5.8G 0% /run/user/1008 tmpfs 5.8G 0 5.8G 0% /run/user/1007 tmpfs 5.8G 0 5.8G 0% /run/user/1006
后来和工作同事确认了下,确实是他们写了个定时脚本清理这个进程产生的文件,而且是定期直接rm删掉,这必然会导致进程发生句柄泄露。
相关链接:
https://www.cnblogs.com/heyonggang/p/3644736.htmlhttp://www.eygle.com/archives/2009/10/linux_unix_file_handle_deleted.html
相关文章推荐
- Linux解决rm 删除大文件后 磁盘空间无法释放的问题
- C#操作Office文件,成功释放,但读取文件时提示"文件***正由另一进程使用,因此该进程无法访问此文件"的解决办法
- 关于spring mvc拦截器拦截js文件等导致无法正常使用问题的解决
- 关于IIS服务启动失败的问题:“IIS提示‘另一个程序正在使用此文件,进程无法访问’”,的解决方法
- CFileDialog改变文件路径导致的一系列问题(如无法安全删除u盘、访问相对路径失败)的解决方法
- 因文件对象未释放导致文件无法删除问题处理或访问
- 如何解决烦人的VS.NET2003编译时“无法将程序集复制到文件,另一个程序正在使用,进程无法访问”的问题?
- 关于spring mvc拦截器拦截js文件等导致无法正常使用问题的解决
- [虚拟机-系统重启]文件系统损坏导致虚拟机无法正常启动的问题及解决方法
- [转]WPF的BitmapImage的文件无法释放及内存泄露的问题
- 浏览器版本不同导致文件无法下载问题解决方法
- 解决oracle数据库TNSLSNR.exe进程占用8080端口,导致tomcat无法正常启动问题
- 请求帮助:如何解决烦人的VS.NET2003编译时“无法将程序集复制到文件,另一个程序正在使用,进程无法访问”的问题?
- django 解决css,js文件304导致无法加载显示问题
- oracle可执行文件s位导致的Cluster资源组无法正常启动的问题解决
- c# 读取其他程序正打开的文件的时“正由另一进程使用,因此该进程无法访问该文件。"的问题解决方法
- 【转】“正由另一进程使用,因此该进程无法访问该文件”的问题&解决方法
- 解决ewebeditor的上传组件与IIS大小限制导致无法上传大于200K文件的问题
- Ubuntu由于修改etc/profile文件导致开机无法登陆问题解决办法(仅供参考)
- WPF的BitmapImage的文件无法释放及内存泄露的问题