zfs发送量波动异常

zfs发送量波动异常

为什么 zfs 发送流中的数据量会“波动”?我希望发送特定快照总是产生完全相同的数据!

下面的测试数据是通过类似的方法创建的dd if=/dev/zero of=filename bs=1024 count=1000

快照是在创建测试文件之间每隔一定时间拍摄的。然后,我使用 command-history 反复将数据发送到 /dev/null,以便快速地一次又一次地重新运行该命令。没有作弊 - 快照是在测试之前拍摄的,对文件系统的任何“写入”都不会影响增量发送中发生的情况,至少我是这么想的。

sol10-primary:/TST> # ls -l
total 1007
-rw-r--r--   1 root     root      102400 Mar  4 12:01 data1
-rw-r--r--   1 root     root      102400 Mar  4 11:49 data2
-rw-r--r--   1 root     root          30 Mar  4 11:48 data3
-rw-r--r--   1 root     root      102400 Mar  4 11:50 data4
-rw-r--r--   1 root     root      102400 Mar  4 11:52 data5
-rw-r--r--   1 root     root      102400 Mar  4 11:53 data6
sol10-primary:/TST> # rm data5
sol10-primary:/TST> # dd if=/dev/zero of=data5 bs=1024 count=100          
100+0 records in
100+0 records out
sol10-primary:/TST> # zfs send -i s1 rpool/tst@s3 | dd bs=1024 > /dev/null
412+6 records in
412+6 records out
sol10-primary:/TST> # zfs send -i s1 rpool/tst@s3 | dd bs=1024 > /dev/null
412+5 records in
412+5 records out
sol10-primary:/TST> # zfs send -i s1 rpool/tst@s3 | dd bs=1024 > /dev/null
412+6 records in
412+6 records out
sol10-primary:/TST> # zfs send -i s1 rpool/tst@s3 | dd bs=1024 > /dev/null
402+32 records in
402+32 records out
sol10-primary:/TST> # zfs send -i s1 rpool/tst@s3 | dd bs=1024 > /dev/null
405+22 records in
405+22 records out
sol10-primary:/TST> # zfs send -i s1 rpool/tst@s3 | dd bs=1024 > /dev/null
412+6 records in
412+6 records out
sol10-primary:/TST> # zfs send -i s1 rpool/tst@s3 | dd bs=1024 > /dev/null
412+5 records in
412+5 records out
sol10-primary:/TST> # zfs list -o name,mountpoint,used,referenced,usedbychildren,usedbysnapshots -r rpool/tst
NAME          MOUNTPOINT   USED  REFER  USEDCHILD  USEDSNAP
rpool/tst     /TST         892K   532K          0      360K
rpool/tst@s1  -             20K   232K          -         -
rpool/tst@s2  -             20K   432K          -         -
rpool/tst@s3  -            120K   532K          -         -

有时在上面我创建了一个快照,然后对现有文件进行 dd-ed,只是为了将某些内容放入“USEDBYSNAPSHOTS”值中。

这基本上是一个学术问题,我怀疑方差在很小的范围内,只是在这里注意到,因为我的测试数据本身很小。

答案1

请勿dd与管道一起使用。dd是低级的。它是read和系统调用的接口write

当你执行 a 时dd bs=1024 count=1,它就会执行 a read(0, buf, 1024)

如果read返回的数据少于 1024 字节(例如因为管道目前仅包含 200 字节),dd则不会重新尝试read获取丢失的 824 字节,它将报告最后读取的块不完整(后面的部分+)。同样的事情也可能发生在写作上。

这就是为什么在管道上使用是危险的dd,因为除非您可以保证写入或读取管道的进程的数量与块大小成正比并且是管道大小的分隔符,否则无法保证您会得到完整的数据块。

(echo AAAA; sleep 1; echo BBBBBB) | dd bs=3 > /dev/null
3+2 records in
3+2 records out

这并不是什么大问题,因为我们只是编写我们读到的内容,但是当您指定一个count.

GNUdd必须-iflag fullblock解决这个问题:

$ (echo AAAA; sleep 1; echo BBBBBB) | dd bs=3 iflag=fullblock > /dev/null
4+0 records in
4+0 records out
12 bytes (12 B) copied, 1.00068 s, 0.0 kB/s

相关内容