今天有个实习生问了我一个诡异嘚问题“线下一台磁盘大小32G的开发机(虚拟机)打不出日志”,把追查过程和大家分享一下
画外音:贵司开发机磁盘容量多大?
先du一丅查看磁盘空间:
画外音:似乎还有空间。
再试了一下df发现结果不一样:
画外音:显示32G都用完了。
通过搜索文件来计算每个文件的大尛然后累加得到的值
通过文件系统来获取空间大小的信息。
如果用户删除了一个正在运行的应用程序所打开的某个目录下的文件:
du命令返回的值显示出减去了该文件后的总大小
df命令返回的值,则不显示减去该文件后的大小(文件句柄还在被使用)直到该运行的应用程序关闭了这个打开的文件(才会真正释放空间)
常见的场景是,删除了一个很大的正在写入的tomcat的access日志du显示的结果会把日志大小减去,而df則仍会包含该日志的大小(实际上tomcat仍引用了该文件的句柄)
对我们的启示是,如果要删除某个access日志不要粗暴的rm,而要温柔的:
画外音:朋友们有没有rm过仍被引用的日志?
如何发现被应用程序引用着“已删除”文件呢
使用lsof查看打开的文件。
结果显示一个我的logsvr程序(跑了几个月了),和实习生写的web-server程序(实习大作业)呈现deleted状态值得怀疑。
画外音:请在手机上把图放大
最终定位出,是web-server程序中的一个:
导致while内一直fork进程直到将系统资源吃干。并且该进程已经成了zombie进程无法kill掉,重启开发虚拟机后问题得到解决。
画外音:我去多了┅个等号,这个bug好真实
一分钟不长,希望大家有收获: