为什么接收到的 ZFS 数据集比原始数据集使用的少 space?
Why received ZFS dataset uses less space than original?
我在 server1
上有一个数据集,我想备份到第二个 server2
。
Server1(原始):
zfs list -o name,used,avail,refer,creation,usedds,usedsnap,origin,compression,compressratio,refcompressratio,mounted,atime,lused storage/iscsi/webhost-old
产生:
NAME USED AVAIL REFER CREATION USEDDS USEDSNAP ORIGIN COMPRESS RATIO REFRATIO MOUNTED ATIME LUSED
storage/iscsi/webhost-old 67,8G 1,87T 67,8G Út kvě 31 6:54 2016 67,8G 16K - lz4 1.00x 1.00x - - 67,4G
正在向第二台服务器发送卷:
zfs send storage/iscsi/webhost-old | pv | ssh -c arcfour,aes128-gcm@openssh.com root@10.0.0.2 zfs receive -Fduv pool/bkp-storage
在 378 秒内收到 69.6GB 的流(189MB/秒)
Server2 zfs list 产生:
NAME USED AVAIL REFER CREATION USEDDS USEDSNAP ORIGIN COMPRESS RATIO REFRATIO MOUNTED ATIME LUSED
pool/bkp-storage/iscsi/webhost-old 36,1G 3,01T 36,1G Pá pro 29 10:25 2017 36,1G 0 - lz4 1.15x 1.15x - - 28,4G
为什么尺寸会有这么大的差异?谢谢。
从你发布的内容中,我注意到 3 件事情看起来很奇怪:
compressratio
在系统 2 上是 1.15 倍,但在系统 1 上是 1.00 倍
- 在系统 2 上,
used
比 logicalused
高 1.27 倍
- 系统 1 的
logicalused
和数字 zfs receive
报告比系统 2 高 ~2.3 倍
这些术语都在 man page 中定义,但在实践中仍然容易混淆逆向工程解释。
(1) 如果在将所有数据写入源数据集后启用压缩,则可能会发生这种情况,因为在启用该设置时 ZFS 不会重写数据以对其进行压缩。除非您使用 -c
,否则 zfs send
发送的数据是未压缩的,但如果在目标数据集上启用了设置,系统 2 将尝试将其压缩为 运行s zfs receive
.如果系统 1 和系统 2 在写入数据之前具有相同的压缩设置,则它们也会具有相同的 compressratio
。
(2) 可能是由于随数据一起写入的元数据而发生的,但在这种情况下,它对于 "normal" 元数据来说太高了,它占大多数池的 1-2%。这可能是由池范围的设置引起的,例如配置 RAID-Z,或者条带化和镜像的奇怪组合(例如 4 个条带,但其中一个是镜像)。
对于(3),我重新阅读了手册页试图弄明白:
logicalused
The amount of space that is "logically" consumed by this dataset and
all its descendents. See the used property. The logical space
ignores the effect of the compression and copies properties, giving a
quantity closer to the amount of data that applications see.
如果您发送数据集(而不是单个 iSCSI 卷)并且发送大小与系统 2 的 logicalused
值(而不是系统 1)相匹配,我猜您忘记发送一些子数据集(即通过使用 zfs send -R
)。但是,在这种情况下,这些都不是真的。
我不得不做一些额外的挖掘 -- this blog post from 2005 可能包含解释。如果系统 1 在写入数据时没有启用压缩(就像我上面对 (1) 的猜测),则负责不写入清零块 (zio_compress_data
) 的函数将不会是 运行 ,因此您可能将一堆空块写入磁盘,并占 logicalused
大小。但是,由于 lz4
是在系统 2 上配置的,它会在那里 运行,并且这些块不会被计算在内。
我在 server1
上有一个数据集,我想备份到第二个 server2
。
Server1(原始):
zfs list -o name,used,avail,refer,creation,usedds,usedsnap,origin,compression,compressratio,refcompressratio,mounted,atime,lused storage/iscsi/webhost-old
产生:
NAME USED AVAIL REFER CREATION USEDDS USEDSNAP ORIGIN COMPRESS RATIO REFRATIO MOUNTED ATIME LUSED
storage/iscsi/webhost-old 67,8G 1,87T 67,8G Út kvě 31 6:54 2016 67,8G 16K - lz4 1.00x 1.00x - - 67,4G
正在向第二台服务器发送卷:
zfs send storage/iscsi/webhost-old | pv | ssh -c arcfour,aes128-gcm@openssh.com root@10.0.0.2 zfs receive -Fduv pool/bkp-storage
在 378 秒内收到 69.6GB 的流(189MB/秒)
Server2 zfs list 产生:
NAME USED AVAIL REFER CREATION USEDDS USEDSNAP ORIGIN COMPRESS RATIO REFRATIO MOUNTED ATIME LUSED
pool/bkp-storage/iscsi/webhost-old 36,1G 3,01T 36,1G Pá pro 29 10:25 2017 36,1G 0 - lz4 1.15x 1.15x - - 28,4G
为什么尺寸会有这么大的差异?谢谢。
从你发布的内容中,我注意到 3 件事情看起来很奇怪:
compressratio
在系统 2 上是 1.15 倍,但在系统 1 上是 1.00 倍- 在系统 2 上,
used
比logicalused
高 1.27 倍
- 系统 1 的
logicalused
和数字zfs receive
报告比系统 2 高 ~2.3 倍
这些术语都在 man page 中定义,但在实践中仍然容易混淆逆向工程解释。
(1) 如果在将所有数据写入源数据集后启用压缩,则可能会发生这种情况,因为在启用该设置时 ZFS 不会重写数据以对其进行压缩。除非您使用 -c
,否则 zfs send
发送的数据是未压缩的,但如果在目标数据集上启用了设置,系统 2 将尝试将其压缩为 运行s zfs receive
.如果系统 1 和系统 2 在写入数据之前具有相同的压缩设置,则它们也会具有相同的 compressratio
。
(2) 可能是由于随数据一起写入的元数据而发生的,但在这种情况下,它对于 "normal" 元数据来说太高了,它占大多数池的 1-2%。这可能是由池范围的设置引起的,例如配置 RAID-Z,或者条带化和镜像的奇怪组合(例如 4 个条带,但其中一个是镜像)。
对于(3),我重新阅读了手册页试图弄明白:
logicalused
The amount of space that is "logically" consumed by this dataset and
all its descendents. See the used property. The logical space
ignores the effect of the compression and copies properties, giving a
quantity closer to the amount of data that applications see.
如果您发送数据集(而不是单个 iSCSI 卷)并且发送大小与系统 2 的 logicalused
值(而不是系统 1)相匹配,我猜您忘记发送一些子数据集(即通过使用 zfs send -R
)。但是,在这种情况下,这些都不是真的。
我不得不做一些额外的挖掘 -- this blog post from 2005 可能包含解释。如果系统 1 在写入数据时没有启用压缩(就像我上面对 (1) 的猜测),则负责不写入清零块 (zio_compress_data
) 的函数将不会是 运行 ,因此您可能将一堆空块写入磁盘,并占 logicalused
大小。但是,由于 lz4
是在系统 2 上配置的,它会在那里 运行,并且这些块不会被计算在内。