billpg Asked: 2022-05-25 04:11:44 +0800 CST2022-05-25 04:11:44 +0800 CST 2022-05-25 04:11:44 +0800 CST 我可以复制不断修改的文件的快照吗? 772 我有一个文件一直保持打开状态,并被另一个进程不断修改。这个过程不断地寻找文件的不同部分并写入新的块。我希望能够制作该文件的副本,但在单个时间实例中作为文件的快照。 我不希望发生的是我复制了第一个字节块,文件更改,然后我复制了第二个块,包括新修改的字节。 Linux可以在这里帮助我吗? files file-copy 2 个回答 Voted White Owl 2022-05-25T04:34:46+08:002022-05-25T04:34:46+08:00 您需要在复制之前暂停写入过程。 在大多数情况下,写入器进程将具有一些备份功能。仔细查看更新文件的过程的文档。 要获得更详细的帮助,我们需要知道文件写入的是哪个进程。有人可能知道该应用程序并知道如何以适当的方式进行备份。 如果没有内置备份功能,您可以尝试通过使用killSIGSTOP/SIGCONT 信号来暂停编写器进程。如果每个逻辑更新都是单个操作,那么很好。但是,如果您的写入器进程可以在逻辑更新时执行两次写入(例如更新数据和更新文件的索引部分),那么您将面临在此类写入之间暂停进程的风险。 Best Answer Marcus Müller 2022-05-25T05:20:34+08:002022-05-25T05:20:34+08:00 Linux可以在这里帮助我吗? 是的。但不是你可能希望的那样。 因此,Linux 上的文件系统通常遵循这样的语义,即对已读取文件的更改(以任何方式)应尽可能立即反映在该文件的所有读取器中。注意这与你想要的不一致。 你可以做的是告诉你的文件系统或块设备层做一个快照,这里的语义是不同的,即在快照点要求一致性。 所以,你需要有 支持快照的文件系统,或 支持快照的块设备子层。 一致性 正如 doneal 非常正确地指出的那样:如果在单个“一致性单元”(即导致另一个一致文件状态的搜索和写入,可能是您认为的“数据更改”时拍摄快照,这些都不会帮助您从应用程序视图)正在进行中。 下面的事情都假设您正在拍摄快照,而当前没有正在进行写入。他们避免副本与文件不完全相同的是在开始复制的那一刻。如果您在写入 8 kB 数据的过程中创建快照,则您的快照包含 4 kB 的新数据和 4 kB 的旧数据,位于您打算覆盖的 8 kB 数据块中。这就是我所说的“数据不一致”。 这实际上意味着没有任何帮助:如果您没有确保文件一致性的合乎逻辑的方法,您的操作系统无法使文件进入一致状态。 如果需要,您将不得不研究“适当的”数据库系统如何确保当存储设备突然从系统中移除时数据库不会处于不可恢复的损坏状态。 您的文件无法做到这一点。如果您不限制快照时间点仅在没有未完成的写入时发生,您自己永远无法保证一致性!为此,在任何存储介质或操作系统上,您都必须更改文件架构。 最常见的方法是实现一个严格有序的机制: 1. 将更改,包括位置、长度和要对主文件执行的数据写入文件(或另一个文件)末尾的日志中,并带有尾随校验和,可让您检查是否完全发生。并且,只有在完全完成之后,才将更改写入主文件。3. 偶尔需要回去清理一下成功提交的日志条目。 当您现在在写入主数据文件时进行快照时,日志中的数据与主数据中的数据不一致。您可以从日志中重放写入,并恢复到一致的状态。如果您在写入日志时进行快照,则在读取锁时会注意到日志条目的校验和不正确,因此该日志条目不能完整,因此主要数据尚未受到什么影响日志条目描述。您从快照日志中删除损坏的日志条目。 文件系统快照 据我所知,在 Linux 下,只有 btrfs 和 openZFS 文件系统支持快照。Btrfs 是 linux 内核的一部分,所以这可能是最容易使用的。 在 btrfs 中,您的文件系统(例如,挂载在 /srv/data 上的文件系统)可以具有subvolumes。您可以将它们作为子目录访问,也可以单独安装它们。 btrfs快照只是与当前卷相同的子卷。这对 btrfs 来说“很容易”实现,因为这是一个写时复制文件系统:通常,每当您修改文件时,都会制作受影响存储块的副本,其中包含修改后的数据。然后,更新文件元数据:文件的内容只是块列表中的数据,如果您更改了某些内容,例如 4. 块,则该列表中的第四个条目将替换为对“新复制和修改”块。这是非常低的开销,因为存储设备无论如何都是按块工作的 - 你永远不能读取单个字节,你读取一个块,写入一个字节和一个块需要相同的时间。因此,读取、修改、写入不同的位置与就地修改一样昂贵。 现在,当创建快照时,所发生的只是快照后对文件元数据的任何修改都将转到单独的数据结构。因此,基本上,文件系统的快照和当前“活动”工作视图 100% 共享所有未更改的数据,但已更改的内容存在两次:一次在修改版本中,一次在原样中在快照时。 因此,将您的文件放在 btrfs 子卷上,制作快照,挂载该快照:您的文件及时“冻结”了。 块设备映射器快照 这些基本上适用于任何现代 Linux 文件系统。在这些很常见的世界中,XFS 是一种流行的文件系统选择(但任何文件系统都应该这样做)。 LVM 是 linux 卷管理器。这基本上意味着它是内核的一部分,您可以提供一个或多个块设备(“物理卷”),告诉它将这些设备组装成一个“卷组”,然后从累积的存储池中创建“逻辑卷”。 其中的一个特例是“精简卷”,这基本上意味着您说“好的,我的卷组中有 512 GB 的存储空间。我想创建一个可以使用文件系统格式化的逻辑卷。我想要那个最终可能会成为 TB(例如,如果我的客户实际使用这些),但现在,我什至没有那么多空间(甚至还没有订购新的 SSD,但你也不需要所有这些 1 TB 还没有)”。然后 LVM 将创建一个看起来像
您需要在复制之前暂停写入过程。
在大多数情况下,写入器进程将具有一些备份功能。仔细查看更新文件的过程的文档。
要获得更详细的帮助,我们需要知道文件写入的是哪个进程。有人可能知道该应用程序并知道如何以适当的方式进行备份。
如果没有内置备份功能,您可以尝试通过使用
kill
SIGSTOP/SIGCONT 信号来暂停编写器进程。如果每个逻辑更新都是单个操作,那么很好。但是,如果您的写入器进程可以在逻辑更新时执行两次写入(例如更新数据和更新文件的索引部分),那么您将面临在此类写入之间暂停进程的风险。是的。但不是你可能希望的那样。
因此,Linux 上的文件系统通常遵循这样的语义,即对已读取文件的更改(以任何方式)应尽可能立即反映在该文件的所有读取器中。注意这与你想要的不一致。
你可以做的是告诉你的文件系统或块设备层做一个快照,这里的语义是不同的,即在快照点要求一致性。
所以,你需要有
一致性
正如 doneal 非常正确地指出的那样:如果在单个“一致性单元”(即导致另一个一致文件状态的搜索和写入,可能是您认为的“数据更改”时拍摄快照,这些都不会帮助您从应用程序视图)正在进行中。
下面的事情都假设您正在拍摄快照,而当前没有正在进行写入。他们避免副本与文件不完全相同的是在开始复制的那一刻。如果您在写入 8 kB 数据的过程中创建快照,则您的快照包含 4 kB 的新数据和 4 kB 的旧数据,位于您打算覆盖的 8 kB 数据块中。这就是我所说的“数据不一致”。
这实际上意味着没有任何帮助:如果您没有确保文件一致性的合乎逻辑的方法,您的操作系统无法使文件进入一致状态。
如果需要,您将不得不研究“适当的”数据库系统如何确保当存储设备突然从系统中移除时数据库不会处于不可恢复的损坏状态。
您的文件无法做到这一点。如果您不限制快照时间点仅在没有未完成的写入时发生,您自己永远无法保证一致性!为此,在任何存储介质或操作系统上,您都必须更改文件架构。
最常见的方法是实现一个严格有序的机制: 1. 将更改,包括位置、长度和要对主文件执行的数据写入文件(或另一个文件)末尾的日志中,并带有尾随校验和,可让您检查是否完全发生。并且,只有在完全完成之后,才将更改写入主文件。3. 偶尔需要回去清理一下成功提交的日志条目。
当您现在在写入主数据文件时进行快照时,日志中的数据与主数据中的数据不一致。您可以从日志中重放写入,并恢复到一致的状态。如果您在写入日志时进行快照,则在读取锁时会注意到日志条目的校验和不正确,因此该日志条目不能完整,因此主要数据尚未受到什么影响日志条目描述。您从快照日志中删除损坏的日志条目。
文件系统快照
据我所知,在 Linux 下,只有 btrfs 和 openZFS 文件系统支持快照。Btrfs 是 linux 内核的一部分,所以这可能是最容易使用的。
在 btrfs 中,您的文件系统(例如,挂载在 /srv/data 上的文件系统)可以具有subvolumes。您可以将它们作为子目录访问,也可以单独安装它们。
btrfs快照只是与当前卷相同的子卷。这对 btrfs 来说“很容易”实现,因为这是一个写时复制文件系统:通常,每当您修改文件时,都会制作受影响存储块的副本,其中包含修改后的数据。然后,更新文件元数据:文件的内容只是块列表中的数据,如果您更改了某些内容,例如 4. 块,则该列表中的第四个条目将替换为对“新复制和修改”块。这是非常低的开销,因为存储设备无论如何都是按块工作的 - 你永远不能读取单个字节,你读取一个块,写入一个字节和一个块需要相同的时间。因此,读取、修改、写入不同的位置与就地修改一样昂贵。
现在,当创建快照时,所发生的只是快照后对文件元数据的任何修改都将转到单独的数据结构。因此,基本上,文件系统的快照和当前“活动”工作视图 100% 共享所有未更改的数据,但已更改的内容存在两次:一次在修改版本中,一次在原样中在快照时。
因此,将您的文件放在 btrfs 子卷上,制作快照,挂载该快照:您的文件及时“冻结”了。
块设备映射器快照
这些基本上适用于任何现代 Linux 文件系统。在这些很常见的世界中,XFS 是一种流行的文件系统选择(但任何文件系统都应该这样做)。
LVM 是 linux 卷管理器。这基本上意味着它是内核的一部分,您可以提供一个或多个块设备(“物理卷”),告诉它将这些设备组装成一个“卷组”,然后从累积的存储池中创建“逻辑卷”。
其中的一个特例是“精简卷”,这基本上意味着您说“好的,我的卷组中有 512 GB 的存储空间。我想创建一个可以使用文件系统格式化的逻辑卷。我想要那个最终可能会成为 TB(例如,如果我的客户实际使用这些),但现在,我什至没有那么多空间(甚至还没有订购新的 SSD,但你也不需要所有这些 1 TB 还没有)”。然后 LVM 将创建一个看起来像