缘起

我们测试环境中的一台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