我很好奇,当我们在具有快照的文件系统(例如 BTRFS)中有一个损坏的无法纠正的文件,并且我们尝试从备份中替换该文件时会发生什么?我怀疑快照仍将包含该文件的损坏版本。有没有办法修复快照中的这些错误?
另一个相关问题是,如果快照本身损坏了会发生什么?我们会失去它吗?
答案1
快照仍将包含损坏的版本,因为它们的概念是它们是时间点的。在所讨论的时间点,它们恰好是损坏的。
谷歌搜索后BTRFS 快照看起来您应该能够安装快照,对快照上的文件进行更改,这样就可以了。
如果只是文件损坏,而且你有备份,那应该不是什么大问题。如果文件系统损坏,那可能就更糟糕了。
关于“如果快照本身损坏会发生什么” - 这在 BTRFS 下不太可能发生,但我预计逻辑是将其复制到另一个块设备,然后尝试在该块设备上进行恢复,就好像它是原始 FS 一样。
(免责声明 - 我从未使用过 BTRFS。对于 ZFS,我只不过是个新手,但我对这些概念有相当好的掌握)
答案2
我使用 BTRFS。我可以确认并详细说明这个答案说;我还可以补充一些内容。
您可以挂载任何快照。您可以修改它,除非它是使用“只读”选项创建的。快照只是一个子卷,它不会“记住”它是由哪个其他子卷创建的。源子卷及其快照最初是等效的。最好将新创建的快照视为“分叉”,而不是字面上的“快照”、“副本”、“冻结状态”或任何其他暗示其相对于“原始”状态较差的名称。
当您分叉子卷(创建快照)时,如果您选择不再修改“副本”(通过明确将其创建为只读子卷或简单地不做任何操作,让它保持原样),而“原始”可能仍在使用中,则可以将其视为时间点快照。我在“apt-get upgrade”之前使用快照备份我的系统,但我从不费心将它们创建为“只读”。我的观点是:它们的时间点状态不是因为我磁盘上的某些元数据,而是因为我头脑中的元数据——我只是避免修改它们。
快照与“原始”子卷共享(最初几乎所有)数据块。如果给定块的内容导致文件损坏,则该文件在共享该块的每个快照中都会损坏。覆盖(修改)其中一个子卷中的文件会将其映射到仅包含此子卷上下文中的新内容的块;其他子卷保持原样。
如果您碰巧在多个子卷之间共享了一个损坏的文件,并且想要从备份中替换它,那么您可以:
- (常用方法)覆盖整个文件(或取消链接并重新创建),这会将其所有部分重新映射到其他块;
- (不寻常的方法)对文件应用二进制补丁,这会将其某些部分重新映射到其他块(如果损坏发生在文件内而不是文件系统内,则可能发生这种情况,例如无效但可读的 PDF)。
在多个子卷中独立执行此操作将导致独立重新映射,它将多次而不是仅一次使用未使用的块。
为了避免这种情况并使多个子卷中的这些替换文件共享其所有块,请按以下步骤操作:
- 如果尚未安装,请将 BTRFS 文件系统的根目录安装到某处:
mount -o subvol=/ …
。这样,所有可能的子卷都将在单个安装点下可用。 - 替换任意单个子卷中的备份文件。
- 对于需要替换文件的每个其他子卷
- 取消链接(删除)文件,
- 然后使用选项
cp
从另一个子卷复制()已经替换的文件--reflink=always
;在单个挂载点内执行此操作非常重要。
- 您现在可以访问
umount
BTRFS 文件系统的根目录。