![有了完整的数据日志,为什么数据会立即出现在目录中?](https://linux22.com/image/2254/%E6%9C%89%E4%BA%86%E5%AE%8C%E6%95%B4%E7%9A%84%E6%95%B0%E6%8D%AE%E6%97%A5%E5%BF%97%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%E6%95%B0%E6%8D%AE%E4%BC%9A%E7%AB%8B%E5%8D%B3%E5%87%BA%E7%8E%B0%E5%9C%A8%E7%9B%AE%E5%BD%95%E4%B8%AD%EF%BC%9F.png)
我有一个关于 ext3 文件系统上的完整数据日志的问题。手册页说明如下:
data=journal
All data is committed into the journal prior to being written into
the main filesystem.
在我看来,这意味着文件首先保存到日志中,然后复制到文件系统。
我认为如果我下载了一些东西,它应该首先保存在日志中,如果完成则转移到 FS。但启动后下载文件出现在目录(FS)中。这有什么问题吗?
编辑:也许认为“所有数据”=文件的整个大小是错误的?因此,如果所有数据可能只是一个块或其他东西,那就有意义了,而且我看不到东西首先写入日志?!
答案1
首先,您怀疑“所有数据”并不意味着整个文件是正确的。事实上,文件系统的该层在固定大小的文件块上运行,而不是在整个文件上运行。在这个级别上,保留有限数量的数据非常重要,因此处理整个文件(可以是任意大的)是行不通的。
其次,你的问题有一个误解。您无法通过查看目录内容来观察日记行为ls
,它的工作级别要低得多。使用普通工具,您总是会看到该文件在那里。 (如果创建一个文件似乎没有创建它,那将是灾难性的。)在幕后发生的事情是文件可以以不同的方式存储。首先,前几个块被保存在日志中。然后,尽可能高效地将数据移动到其最终位置。它仍然是同一目录中的同一文件,只是存储方式不同。
观察日志行为的唯一方法是查看内核正在向磁盘写入什么内容,或者在崩溃后分析磁盘内容。在正常操作中,日志是一个实现细节:如果您可以看到它的运行情况(除了性能方面),它就会被严重破坏。
有关文件系统日志的更多信息,我建议从维基百科文章。在 ext3 术语中,adata=journal
确保如果系统崩溃,每个文件都处于崩溃前某个时刻的状态(由于缓冲,它并不总是最新状态)。这种情况不会自动发生的原因是内核会重新排序磁盘写入以提高效率(这可能会产生很大的影响)。这被称为《物理杂志》在维基百科文章中。另外两种模式 (data=ordered
和data=writeback
) 是以下形式《逻辑日记》:它们速度更快,但可能会导致文件损坏。该日志将损坏的风险限制在少数包含垃圾的文件中; ext3 始终使用完整的元数据日志。如果没有元数据日志,元数据可能会丢失,从而导致主要文件系统损坏。此外,如果没有日志,崩溃后的恢复需要完整的文件系统完整性检查,而使用日志恢复意味着重放一些日志条目。
请注意,即使使用日志,典型的 UNIX 文件系统也不能保证全局文件系统一致性,最多只能保证每个文件的一致性。也就是说,假设您写入 file foo
,然后写入 file bar
,然后系统崩溃。有可能bar
拥有新内容但foo
仍然拥有旧内容。为了获得完全的一致性,你需要一个交易性的文件系统。
答案2
我认为如果我下载了一些东西,它应该首先保存在日志中,如果完成则转移到 FS。
您的意思是该文件仅在关闭后才出现。这类似于 Ext4 的可选行为,请参阅安装选项叫auto_da_alloc
.
auto_da_alloc|noauto_da_alloc
当 noauto_da_alloc 通过以下模式替换现有文件时,许多损坏的应用程序不使用 fsync()
fd = open("foo.new")/write(fd,..)/close(fd)/ 重命名("foo.new", "foo")
或者更糟
fd = 打开(“foo”,O_TRUNC)/写入(fd,..)/关闭(fd)。
如果启用了auto_da_alloc,ext4将检测replace-via-rename和replace-via-truncate模式,并强制分配任何延迟的分配块,以便在下一次日志提交时,在默认的data=ordered模式下,在提交 rename() 操作之前,新文件将被强制写入磁盘。这提供了与 ext3 大致相同级别的保证,并避免了在延迟分配块被强制写入磁盘之前系统崩溃时可能发生的“零长度”问题。