为什么在`rm`坏后关闭计算机电源会保存我的文件?


31

经典情况:我遇到了麻烦rm,立即意识到我删除了错误的文件。(没有什么紧要关头,我可以容忍最近的备份,但仍然很烦人。)

如果想使用extundelete此类工具恢复文件,我知道进一步的磁盘活动是我的敌人,所以我立即物理关闭了计算机的电源(即使用电源按钮,而不是使用halt诸如此类的命令)。这是一台笔记本电脑,没有重要任务在运行,也没有打开任何东西,因此是可以接受的操作。(顺便说一句,从那以后我就知道,在这种情况下要做的第一件事就是首先估计丢失的文件是否仍然可以通过https://unix.stackexchange.com/a/101247进程打开-如果是,则应以这种方式恢复它们,而不是关闭机器电源。)

尽管如此,一旦机器断电,我想了一会儿并认为文件不值得花时间启动实时系统进行适当的取证。所以我重新启动了机器。然后我发现我的文件仍坐在磁盘上:在rm断电之前,这些文件还没有传播到磁盘上。我跳了一点舞,感谢系统管理员之神的意想不到的宽恕。

现在我的问题是了解这是怎么可能的,以及在将an rm实际传播到磁盘之前的典型延迟是多少?我知道磁盘IO不会立即刷新,但会在内存中放置一段时间,但是我认为磁盘日志会迅速确保挂起的操作不会完全丢失。https://unix.stackexchange.com/a/78766似乎暗示了一种单独的机制来刷新脏页和刷新日记帐操作,但没有提供足够的详细信息说明日记帐将如何涉及到rm以及预期的延迟时间操作被刷新。

更多详细信息:数据位于LUKS卷内的ext4分区中,并且在备份计算机时,我在中看到以下内容syslog

Sep 24 10:24:58 gamma kernel: [   11.457007] EXT4-fs (dm-0): 1 orphan inode deleted
Sep 24 10:24:58 gamma kernel: [   11.458393] EXT4-fs (dm-0): recovery complete
Sep 24 10:24:58 gamma kernel: [   11.482475] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null)

但是我不相信它与rm

另一个问题是是否有一种方法可以告诉内核不执行任何未决的磁盘操作(而是将其转储到某个地方),而不是关闭计算机电源。(当然,不执行挂起的操作听起来很危险,但是无论如何关闭机器电源,都会发生这种情况,并且在某些情况下可以节省您的时间。)这当然会“更清洁”,也很有趣例如,对于那些不易关闭物理电源的远程服务器。

Answers:


22

听起来您对所发生的事情有很好的了解。

是的,因为您在更改提交到磁盘之前就硬关闭了系统电源,所以它们在您重新引导时就已存在。

在将所有写入刷新到磁盘之前,系统会缓存所有写入。有几个控制此行为的选项,全部位于/proc/sys/vm/dirty_* [ kernel doc ]中。除非应用程序通过fsync() [ man 2 fsync ]明确地执行了刷新,否则当数据足够旧或写入缓存已满时,将提交数据。
上面使用的“数据”的定义包括对目录条目的修改以删除文件。

现在,对于期刊而言,这是对期刊用途的常见误解之一。日记的目的不是确保重播更改或确保数据不会丢失。日记的目的是为了防止损坏文件系统本身,而不是其中的文件。该日志仅包含有关进行的更改的信息,而不包含(通常)更改本身的完整数据。确切的详细信息取决于文件系统和日志模式。对于ext3 / 4,请参阅中的data安装选项man 8 mount


要回答您的补充问题,即是否有一种方法可以防止未重启的未决写操作:

通过快速阅读内核源代码,您似乎可以使用magic sysrq u命令([ wikipedia ],[ kernel doc ])进行紧急的重新装入只读操作。看来这将立即以只读方式重新安装所有卷,而无需进行同步操作。

要使用此功能,只需按Alt+ SysRq+即可u


1
感谢您的回答!我仍然对日志感到困惑:我是否应该将它视为仅在将更改刷新到磁盘后才涉及到的东西,以便写缓存是唯一估计rm写时间的宽限期的相关机制?换句话说,只有在即将执行写操作时,事情才会提交给日志?还是图片比这更复杂?至于alt-sysrq-u,这是一个很不错的主意。您是否对“似乎”索赔有参考意见?(您提供的链接似乎没有遵循它。)谢谢!:)
a3nm

此外,magic sysrq还具有局限性,您仍然无法在远程计算机上执行该操作。
a3nm

3
@ a3nm可以在远程计算机上使用sysrq。echo u > /proc/sysrq-trigger(您可能需要先激活它)。
Paulo Almeida 2014年

该日志仅处理文件系统元数据,不处理文件内容(默认情况下,可以完全更改日志格式),但是在这种情况下,它可以删除文件,因为我们正在处理删除目录项。因此,日志必须确保该文件存在(假设文件没有其他更改,则带有其先前的内容)或不存在。
安赫尔

@ a3nm关于您的期刊评论。写缓存位于日志和磁盘之间。当您写入文件系统时,将先更新日志,然后再更新文件系统,但尚未将它们都提交到磁盘。
帕特里克

2

来自:https : //www.kernel.org/doc/Documentation/filesystems/ext4.txt

commit = nrsec(*)可以告知Ext4每'nrsec'秒同步其所有数据和元数据。默认值为5秒。这意味着,如果您断电,则将损失多达最近5秒钟的工作量(由于日志功能,您的文件系统不会受到损坏)。此默认值(或任何低值)会影响性能,但对数据安全性很有好处。将其设置为0与将其保留为默认值(5秒)具有相同的效果。将其设置为非常大的值将提高性能。

另请参见此处有关如何刷新它们的信息:如何清空Linux系统上的缓冲区和缓存?

从以上链接引用:

注意:清理内存中不必要的内容(Kernerl 2.6.16或更高版本)。始终确保首先运行同步,以将有用的内容刷新到磁盘上!!!

To free pagecache:

$ echo 1 > /proc/sys/vm/drop_caches

To free dentries and inodes:

$ echo 2 > /proc/sys/vm/drop_caches

To free pagecache, dentries and inodes:

$ echo 3 > /proc/sys/vm/drop_caches

感谢您的回答!但是,我不明白这一点:至于提到的“同步”,在内核决定将更改从内存刷新到磁盘commit=nrsec,会发生这种情况吗?还是设置保证无论和设置如何,所有更改都会在1秒后被清除?commit=1dirty_expire_centisecsdirty_writeback_centisecs
a3nm

内核将每1秒将所有缓存/缓冲区刷新(同步)到光盘一次commit=1。据我了解,sync尽管虚拟内存设置可能会更快地发生,但它会强制一切发生。
大卫

同样出于性能原因,不建议将设置(和存储寿命)设置为低于默认值。
David
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.