HubertNNN Asked: 2020-01-18 05:21:02 +0800 CST2020-01-18 05:21:02 +0800 CST 2020-01-18 05:21:02 +0800 CST ZFS 写入时复制如何处理大文件 772 假设我有一个example.log在 ZFS 上调用的大文件 (8GB)。我要做cp example.log example.bak一个副本。然后我在原始文件中添加或修改几个字节。会发生什么? ZFS 将复制整个 8GB 文件还是仅复制更改的块(以及从文件描述符指向该块的所有 inode 链)? file-copy cp 2 个回答 Voted Best Answer dhag 2020-01-18T10:28:16+08:002020-01-18T10:28:16+08:00 据我所知,FreeBSD ZFS 不支持使用 cp 进行写时复制。本机 cp 似乎没有此类轻量级副本的选项,并且尝试--reflink在 ZFS 系统上出现错误的 GNU cp 我尝试使用错误消息“cp: failed to clone 'example.bak' from 'example.log': Operation不支持”。 一位评论者提到 Solaris cp 具有-z执行此类复制的开关。 但是,我希望这能回答您的基本问题,写入时复制用于文件系统快照:假设您在 1000GB 可用空间中使用了 900GB,没有什么能阻止您制作该文件系统的快照,快照不会占用 900GB ; 事实上,它最初根本不会占用任何新的数据块。 在创建包含 的原始文件系统的快照后 example.log,您最终会得到两个“副本”:快照中的只读版本,以及原始位置中的实时版本。当副本被修改时会发生什么,无论是通过附加还是通过就地更改?这就是魔法发生的地方:只有那些被改变的块被复制并开始占用空间。并非整个文件一被更改就被复制。 mmusante 2020-01-21T18:47:13+08:002020-01-21T18:47:13+08:00 该cp命令将创建一个新文件,因此每个块都会有一个副本。一旦您修改了原始文件中的几个字节,ZFS 将首先将包含这些字节的数据块从磁盘复制到 RAM 中,将新字节应用到其中,然后将该块写入磁盘上的新位置。原始块将被释放(在这里简化,但本质上就是这样)。该文件的其余块被单独留下。 关于您问题的 inode 部分:ZFS 没有 inode。相反,它维护“间接块”。这些是磁盘上指向文件数据的元数据块。根据文件大小和文件的块大小,可以有多层间接块。指向修改块的间接块将需要更新,但其余的则保持不变。
据我所知,FreeBSD ZFS 不支持使用 cp 进行写时复制。本机 cp 似乎没有此类轻量级副本的选项,并且尝试
--reflink
在 ZFS 系统上出现错误的 GNU cp 我尝试使用错误消息“cp: failed to clone 'example.bak' from 'example.log': Operation不支持”。一位评论者提到 Solaris cp 具有
-z
执行此类复制的开关。但是,我希望这能回答您的基本问题,写入时复制用于文件系统快照:假设您在 1000GB 可用空间中使用了 900GB,没有什么能阻止您制作该文件系统的快照,快照不会占用 900GB ; 事实上,它最初根本不会占用任何新的数据块。
在创建包含 的原始文件系统的快照后
example.log
,您最终会得到两个“副本”:快照中的只读版本,以及原始位置中的实时版本。当副本被修改时会发生什么,无论是通过附加还是通过就地更改?这就是魔法发生的地方:只有那些被改变的块被复制并开始占用空间。并非整个文件一被更改就被复制。该
cp
命令将创建一个新文件,因此每个块都会有一个副本。一旦您修改了原始文件中的几个字节,ZFS 将首先将包含这些字节的数据块从磁盘复制到 RAM 中,将新字节应用到其中,然后将该块写入磁盘上的新位置。原始块将被释放(在这里简化,但本质上就是这样)。该文件的其余块被单独留下。关于您问题的 inode 部分:ZFS 没有 inode。相反,它维护“间接块”。这些是磁盘上指向文件数据的元数据块。根据文件大小和文件的块大小,可以有多层间接块。指向修改块的间接块将需要更新,但其余的则保持不变。