rm 没有释放磁盘空间 [关闭]

Posted

技术标签:

【中文标题】rm 没有释放磁盘空间 [关闭]【英文标题】:rm not freeing diskspace [closed] 【发布时间】:2010-09-24 20:40:16 【问题描述】:

rm'ed 了一个 2.5gb 的日志文件 - 但它似乎没有释放任何空间。

我做到了:

rm /opt/tomcat/logs/catalina.out

然后这个:

df -hT

df 报告我的/opt 挂载仍然100% 使用。

有什么建议吗?

【问题讨论】:

根据分区的总大小,使用 -h 可能不会显示太大变化。但正如其他人指出的那样,tomcat 可能仍然打开文件。 ***.com/questions/321618/… 【参考方案1】:

最好的解决方案是使用“echo”(作为@ejoncas 的建议):

$ echo '' > huge_file.log  

这个操作非常安全和快速(每秒删除大约 1G 数据),尤其是当您在生产服务器上操作时。

不要简单地使用“rm”删除这个文件,因为首先你必须停止写入它的进程,否则磁盘将不会被释放。

参考:http://siwei.me/blog/posts/how-to-deal-with-huge-log-file-in-production

更新:我的故事的起源

2013年在优酷工作的时候,周六发现一台核心服务器宕机,原因是:磁盘满(有日志文件)

所以我简单地rm log_file.log(没有停止网络应用程序进程)但发现:1. 没有释放磁盘空间并且:2. 我实际上看不到日志文件。

所以我必须重新启动我的网络服务器(一个 Rails 应用程序),磁盘空间终于被释放了。

这对我来说是非常重要的一课。它告诉我echo '' > log_file.log 是释放磁盘空间的正确方法,如果您不想停止正在将日志写入此文件的正在运行的进程。

【讨论】:

根据unix.stackexchange.com/questions/68523/…,通过截断告诉文件系统不需要其余字节可能更快。【参考方案2】:

输入命令查看哪些被删除的文件占用了内存

 $ sudo lsof | grep deleted

它会显示已删除的仍保留内存的文件。

然后用 pid 或 name 杀死进程

$ sudo kill <pid>
$ df -h

现在检查你将拥有相同的记忆

如果不输入下面的命令查看哪个文件占用了内存

# cd /
# du --threshold=(SIZE)

提及任何大小,它将显示哪些文件占用超过阈值大小并删除文件

【讨论】:

在我的情况下 lsof | grep deleted 没有显示任何内容【参考方案3】:

你的问题:

有可能正在运行的程序仍在保留该文件。

您的解决方案:

根据此处的其他答案,您可以简单地关闭 tomcat 以阻止它保留文件。

如果这不是一个选项,或者您只是想了解更多详细信息,请查看以下问题:Find and remove large files that are open but have been deleted - 它建议了一些更严厉的方法来处理它,这些方法可能对您的情况更有用。


更多详情:

linux/unix 文件系统认为“打开的”文件是它们的另一个名称。 rm 从目录树中看到的文件中删除“名称”。在句柄关闭之前,文件仍然有更多“名称”,因此文件仍然存在。在文件完全未命名之前,文件系统不会获取文件。

这可能看起来有点奇怪,但这样做可以实现一些有用的东西,比如启用符号链接。符号链接本质上可以被视为同一文件的替代名称。

这就是为什么在完成后始终在文件句柄上调用与 close() 等效的语言很重要的原因。这会通知操作系统该文件不再被使用。 虽然有时这无济于事 - 这很可能是 Tomcat 的情况。请参阅Bill Karwin's Answer 了解原因。

根据文件系统,这通常实现为一种引用计数,因此可能不涉及任何实名。如果像 stdin 和 stderr 这样的东西被重定向到一个文件或另一个字节流(最常见的是通过服务完成),它也会变得很奇怪。

整个想法与“inodes”的概念密切相关,所以如果你是好奇的类型,我建议你先检查一下。

讨论

它不再那么好用了,但是你曾经能够更新整个操作系统,使用新库启动一个新的 http-daemon,最后在不再为客户端提供服务时关闭旧的它(释放旧手柄)。 http 客户端甚至不会错过任何一个节拍。

基本上,您可以完全清除内核和所有“从底层”运行的程序库。但是由于旧副本的“名称”仍然存在,因此该文件仍然存在于该特定程序的内存/磁盘中。然后就是重新启动所有服务等问题。虽然这是一个高级使用场景,但它是某些 unix 系统有多年正常运行时间记录的原因。

【讨论】:

【参考方案4】:

重新启动 Tomcat 将释放 Tomcat 对文件的任何保留。但是,为了避免重新启动 Tomcat(例如,如果这是一个生产环境并且您不想不必要地关闭服务),您通常可以覆盖该文件:

cp /dev/null /opt/tomcat/logs/catalina.out

甚至更短更直接:

> /opt/tomcat/logs/catalina.out

在故障排除或磁盘清理过程中,我一直使用这些方法来清除当前正在运行的服务器进程的日志文件。这会单独保留 inode,但会清除实际的文件数据,而尝试删除文件通常要么不起作用,要么至少会混淆正在运行的进程的日志写入器。

【讨论】:

【参考方案5】:

正如其他人所建议的,该文件可能仍被其他进程打开。要找出哪个,你可以做

lsof /opt/tomcat/logs/catalina.out

其中列出了您的进程。可能您会在该列表中找到 tomcat。

【讨论】:

【参考方案6】:

正如 FerranB 和 Paul Tomblin 在此线程中所指出的,该文件正在使用中,并且在文件关闭之前不会释放磁盘空间。

问题是你不能用信号通知 Catalina 进程关闭catalina.out,因为文件句柄不受 java 进程的控制。当您启动 Tomcat 时,它是由 catalina.sh 中的 shell I/O 重定向打开的。只有终止 Catalina 进程,才能关闭该文件句柄。

未来有两种解决方案可以防止这种情况发生:

不允许 Tomcat 应用程序的输出进入 catalina.out。而是使用swallowOutput 属性,并配置日志通道以进行输出。由 log4j 管理的日志可以在不重启 Catalina 进程的情况下轮换。

修改 catalina.sh 以管道输出到 cronolog,而不是简单地重定向到 catalina.out。这样 cronolog 将为您轮换日志。

【讨论】:

当我看到用于记录输出的 .sh 脚本时,我很困扰。感谢您为tomcat提供解决方案!正确的重定向是最好的选择,但顺便说一句,如果您处于紧要关头,您可以截断文件:unix.stackexchange.com/a/68532 @Ape-in​​ago,是的,谢谢你的提示。正如你所说,这在紧要关头很好。但是设置适当的日志轮换是一个更长期的解决方案。【参考方案7】:

如果文件有第二个硬链接,那么在删除之前不会删除它。

【讨论】:

这很好,值得在同一个文件系统上搜索另一个 2.5GB 文件(硬链接不能跨文件系统)。【参考方案8】:

如果某些东西仍然打开,则该文件实际上不会消失。您可能需要以某种方式向 catalina 发出信号以关闭并重新打开其日志文件。

【讨论】:

【参考方案9】:

rm 是否已记录/计划?尝试使用“同步”命令强制写入。

【讨论】:

【参考方案10】:

重新启动 tomcat,如果文件正在使用中并且您将其删除,则该过程完成后空间变为可用。

【讨论】:

是的,你是对的 - 文件在 *nix 中被引用计数,只要有引用(即打开的 fd),即使没有链接,它仍然会存在留给 inode。 在这种情况下最好的做法是回显“”> application.log。这将立即释放您的磁盘,而无需重新启动您的 tomcat。 使用lsof +L1,您可以找到正在使用的进程并阻止释放空间。

以上是关于rm 没有释放磁盘空间 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Linux删除文件之后磁盘空间没有被释放

rm -rf 删除文件后磁盘空间不释放

Linux rm命令删除文件磁盘空间不释放解决

Linux文件删除,但是df之后磁盘空间没有释放

Linux文件删除,但是df之后磁盘空间没有释放

[磁盘空间]lsof处理文件恢复句柄以及空间释放问题