我发现我的一个日志消耗了大量来自正在运行的进程的空间。我想清理这个文件,这样我就可以运行 logadm 来轮换它。但我不知道怎么办
# >MyLog_nohup.out
# ls -lLh MyLog_nohup.out
-rw-r-lr-- 1 user group 72G Jul 30 07:26 MyLog_nohup.out
# du -sh MyLog_nohup.out
480K MyLog_nohup.out
即使在释放它之后,仍然消耗 72G,并且在其上运行更多,只是显示空行..我该如何解决这个问题?
我无法承担重新启动该过程的费用。但我想使用 logadm 来轮换该日志文件,这可能吗?我尝试过,但它一直在无限循环地处理空白行。与我对此文件执行更多操作时相同。还有其他方法可以解决这个问题吗?
对于 logrotate,有一个 copytruncate 选项可以处理打开的文件,但当文件具有这些空行时我无法使用它,因为它在循环中运行。我仍然不明白为什么我无法查看/更多/头这个文件!
答案1
您的文件没有损坏;在 Linux 和 POSIX 系统上,只要正在运行的进程有一个打开的文件描述符对于它正在写入的某个文件,即使您删除或重命名该文件,它也能够继续写入该文件(因为文件描述符与i节点,而不是文件名)。特别是logrotate
or logadm
- 或任何外部命令序列 - 不会对磁盘空间做任何有用的事情。
我假设你使用的是 Linux。
如果你的进程有 pid 1234,你可以查看/proc/1234/
特别列出的目录/proc/1234/fd/
。读过程(5)。
您可能应该停止有问题的进程(使用kill -TERM
then kill -QUIT
then 最后kill -KILL
;请参阅信号(7)&杀死(1)),然后删除该文件,最后更正和/或配置您的程序以执行一些更有用的日志,然后再次启动它。
您可能已经丢失了程序完成的所有计算。所以最好尽快停止它,改进它(也许你想要一些应用程序检查点, 或者坚持,或者添加某种方法来关闭它,然后重命名,然后重新打开日志文件),然后重新启动程序的改进版本。
你应该阅读高级Linux编程。您的程序中可能有几个错误(可能与日志记录有关)。你可能会使用跟踪(1)去了解系统调用由您的流程完成,您可以使用系统日志(3)在您的(改进的)程序中。
很可能,你的程序中有一个设计错误。所以最好现在就停止,思考,改进,然后重新开始。等待磁盘完全填满对你没有帮助(而且会使情况变得更糟)。
为了将来的测试目的,您可以考虑设置一些磁盘配额和/或一些资源限制(例如设置限制(2)和 bashulimit
内置)。
将来,始终将您的程序设计为能够承受重新启动该过程的费用。无法承担这始终是一个巨大的错误(特别是,您需要一些备份策略,并且您需要一些修订控制在您的源代码上;我建议git为了那个原因)。
答案2
# ls -lLh MyLog_nohup.out -rw-r-lr-- 1 个用户组 72G 7 月 30 日 07:26 MyLog_nohup.out # du -sh MyLog_nohup.out 480K MyLog_nohup.out
对我来说这看起来像是一个稀疏文件。稀疏文件在磁盘上分配虚拟大小(在您的情况下为 72G)以提高效率,但实际上使用的空间与写入文件上的数据一样多(在您的情况下为 480K)。虚拟大小不计算在已用空间中(如果删除文件,您将不会释放 72G,而只会释放 480k)。
读取文件时您会看到空行,因为......其中只有空行(空)。尝试使用 hexdump (1) 查看实际数据(如果有),但对于任何有意义的输出,您需要一个能够理解文件格式的工具(创建文件的程序应该附带一个用于该工具的工具)。
此外,正如其他人指出的那样,当文件仍然映射在内存中时,您无法回收文件的资源。您需要释放映射,即以以太网终止程序,或者您可以使用 gdb 尝试此操作 (1)
pidof <procname> # find the pid of the process which creates the log file
ls -l /proc/<pid>/fd/ # find the fd pointing to MyLog_nohup.out
gdb -p <pid> # attach to pid
(gdb) p close(<fd>) # close fd pointing to log file
但请注意,当 fd 关闭时,程序可能会重新创建日志文件或出现未指定的行为,并且由于您“无法重新启动进程”,因此上述操作可能风险太大,只需保留日志文件即可。