日志程序如何继续记录到已删除的文件?


12

Unix Power Tools,第3版清空文件部分,而不是删除文件

如果活动进程打开了文件(对于日志文件来说并不罕见),则删除该文件并创建一个新文件不会影响日志记录程序。这些消息只会继续转到不再链接的文件。清空文件不会破坏关联,因此清除文件不会影响日志记录程序。

重点是我的

我不明白为什么程序会继续记录到已删除的文件。是因为文件描述符条目没有从过程表中删除吗?

Answers:


11

删除文件时,实际上是删除了指向该文件(指向inode)的链接。如果有人已经打开了该文件,则他们可以保留他们拥有的文件描述符。该文件保留在磁盘上,占用空间,并且如果您有权访问该文件,则可以对其进行读写。

unlink功能是由POSIX定义的:

当文件的链接计数变为0且没有进程打开文件时,应释放文件所占用的空间,并且不再可访问该文件。如果在删除最后一个链接时一个或多个进程打开了文件,则应在unlink()返回之前删除该链接,但应推迟文件内容的删除,直到关闭对该文件的所有引用为止

由于这种行为,这条建议。守护程序将打开该文件,并且不会注意到该文件已被删除(除非它正在专门监视它,这是罕见的)。它将继续愉快地写入它具有的现有文件描述符:您将继续占用磁盘上的(更多)空间,但是您将看不到它写入的任何消息,因此您的处境实际上是最糟糕的两个世界。如果将文件截断为零长度,则空间将立即释放,并且所有新消息都将附加在文件的新末端,您可以在其中看到它们。

最终,当守护程序终止或关闭close文件时,空间将被释放。在此期间,没有新用户可以打开文件(除非通过系统特定的反射接口(如Linux的/proc/x/fd/...接口)打开)。还保证:

如果文件的链接计数为0,则当与该文件关联的所有文件描述符都关闭时,该文件所占用的空间将被释放,并且该文件将不再可访问。

因此,您不会永久丢失磁盘空间,但是通过删除文件不会获得任何好处,并且您无法访问新消息。


1
如果用户(这里是root)尝试取消链接会发生什么/proc/x/fd/y?这会导致进程无法写入文件描述符,还是非法操作?
nanofarad 2014年

@hexafraction /proc/*/fd/*是指向实际文件的符号链接,因此删除它们不会删除该文件。我建议您尝试一下:)(当然不在生产系统上!)
Ruslan 2014年

1
@MichaelHomer也许您可以在答案中阐明,一旦取消链接文件,指向文件描述符的进程便可以在相同路径下或不在同一路径下再次链接它。有时这可能很有用。
lgeorget 2014年

@hexafraction好的,这些只是进程状态和对象的表示(在文件系统空间中)。如果您在文件系统空间中删除这些表示形式,则实际进程将不会发生任何事情-除非它(或某些其他进程)依赖在那里的表示形式。不知道你可以使用rm内部无节制/proc/sys不通过系统反正继续听。
David Tonhofer 2014年

@lgeorget这是如何实现的?
2014年

8

究竟。

文件是三方的。

  • 内容,即字节的平面数组,写在磁盘上的某处或即时生成。
  • 索引节点,或索引节点的简称,它是一种数据结构填充和内核使用。它包含有关文件的所有元数据(大小,权限等),以及指向文件内容位置的指针。
  • 一个或多个目录条目(即位置),以类似于的路径进行操作/home/user/personal_file,它们充当句柄,您可以通过该句柄使用文件,修改文件的内容,更改其元数据等。

打开文件时,您将提供操作系统的路径,它会直接向您返回到索引节点的句柄。使用称为文件描述符的此句柄,您可以根据需要(或至少在OS允许的情况下)操纵文件。

您永远不能直接删除索引节点,而必须提供操作系统路径以要求删除。因此,当您要删除文件时,仅删除目录条目。如果文件具有其他目录条目,它将继续可访问,即使没有,也不会删除它的inode,同时仍然有指向它的文件描述符。@MichaelHomer的答案在这个特定主题上更具技术性和详细性。


4

其他两个答案很好地说明了这个问题-在所有目录链接到该文件以及所有打开的文件描述符都消失之前,该文件不会被“删除” 。

为了避免这种情况,使用它是一个好习惯

> /var/log/bigfile

代替

rm -f /var/log/bigfile

因为那只是将内容重置为0字节而不是删除它,所以您仍然可以看到写入的内容。

如果删除了文件,并且在Linux上具有/ proc / fd文件系统,则仍可以使用

> /proc/12345/fd/3

将文件的内容清零(假设12345是您的进程ID,而3是大文件的fd号)。如果磁盘已满,并且由于某种原因您无法终止正在写入日志文件的进程,则可以节省生命。


> /var/log/bigfile删除文件中的现有数据,但不会阻止程序在其中写入数据。在极少数情况下,这是对的。我想说这是一个坏习惯。如果要删除文件,请使用rm。如果要停止正在此处写入的程序,请在删除之前或之后将其杀死,或以其他方式使其停止写入。
吉尔斯(Gillles)“所以-不要再邪恶了”

1
@Giles,本主题涉及以下事实:如果程序仍然打开文件,则删除将无济于事。而且如果由于某些程序行为不当和syslogd填满而使磁盘满了/var/log/messages> /var/log/messages比杀死磁盘更好的选择syslogd。当然,这并不能阻止您首先分析问题所在。
Guntram Blohm支持Monica 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.