缘起
我们测试环境中的一台Job机器磁盘空间使用率一直很高(VM 40G),最近经常遇到磁盘空间已满,导致一些任务无法正常运行,比如新项目的代码无法部署,影响正常的开发流程。几天前为赶项目进度,我们采用临时清理一些日志文件的方式,仅仅空出几G的空间,只能缓解一时,隔天又满了。总是这样就也太坑了,我决定花些时间彻底解决一下,不管采用什么办法。早晨起床后,我在Doit.im中创建了项目,并进行一些规划,列出一些需要进行的任务。
我对这台机器的职责并不熟悉,我猜测会否是该机器上部署了太多的服务导致,如果是这样,就将它们迁移出去;如果是因为机器配置太低的原因,则切换到配置更高的机器;迁移的话就需要对该机器上运行的任务进行梳理……
实战
到公司后,又听到该机器磁盘已满,又是临时的清理了些空间。我跑去测试环境的维护人员哪里,督促他解决这个问题,之后就待在那里和他一起解决。
1. 首先,确认了这台机器只是作为Job机器,没有其他的服务。那么问题在哪里呢?
2. 使用`du -sh /path`命令逐级缩小查找范围,期间也删除了一些小的日志文件,最终发现了一个16G+的`nohup.out`日志文件。
3. 终于找到罪魁祸首了,果断`rm nohup.out`删除掉它。咔,发现磁盘空间并没有被释放掉。这是什么情况?
4. 分析后发现,因为写入这个日志文件的进程还在执行导致的。那么,怎样定位这个进程呢?
5. 我首先尝试使用`ps aux | grep cmd`命令,发现没有与该目录下文件名匹配的进程;接着我尝试遍历`/proc`目录下所有进程的`fd`目录,命令:`find /proc -name fd -type d | grep nohup.out`,方法可行。
6. 这时瞄一眼同事的屏幕,神器出厂,lsof,`lsof | grep nohup.out`即可,还可以显示文件的状态,被我删除的文件后缀有`(deleted)`。
7. 定位到进程pid后,在使用`ps -p pid`查看进程的命令;`kill`关闭进程,`nohup`重启命令,日志文件重定向到`/dev/null`,磁盘空间瞬间释放了
8. `lsof`命令的结果显示,还有很多其他的`nohup.out`文件存在,它们也将被逐个清理掉。
反思
虽然上面的过程可以在解决问题,但是这是一个折腾的过程,我们需要如何避免类似的问题?
1. 使用`nohup`启用命令时,将日志重定向到指定的目录下或者`/dev/null`;
2. 对于Job的日志,最好是在代码中调用日志接口,写入到指定目录,同时按照日期进行分割,这样方便以后的清理。
遗留问题
1. 使用`ls -al`查看`/proc`下的文件描述符(fd),发现它们是软连接(lr-x——),为什么删除掉文件后,磁盘空间没有被释放呢?(SegmentFault)
1024个赞!
Pingback: 一个文件描述符与磁盘空间释放的问题 | segment-解决方案