zfsトランスポートストリームのデータ量が「変動」するのはなぜですか?常に同じデータを生成するために特定のスナップショットを送信したい!
以下のテストデータは、同様のアプローチを使用して生成された。dd if=/dev/zero of=filename bs=1024 count=1000
テストファイルの作成間に一定の間隔でスナップショットが作成されます。その後、コマンド履歴を使用してデータを/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 - -
時には上記のスナップショットを作成し、「USEDBYSNAPSHOTS」値に何かを入れるために既存のファイルを追加しました。
これは基本的に学術的な質問です。分散が小さい範囲にあると思います。テストデータ自体が小さいので、ここで注目しています。
答え1
dd
パイプと一緒に使用しないでください。dd
低レベルです。read
システムコールとのインタフェースですwrite
。
を実行するとdd bs=1024 count=1
が実行されますread(0, buf, 1024)
。
1024バイト未満のデータが返された場合read
(たとえば、パイプに現在200バイトしか含まれていない場合)、欠落している824バイトを取得しようとするのではなく、dd
最後のread
ブロック読み取りが不完全であることを報告します(後で+
)。書き込みでも同じことが起こります。
これがパイプで使用するのが危険な理由ですdd
。これは、パイプに書き込むプロセスまたはパイプから読み取るプロセスの数がブロックサイズに比例してパイプサイズの区切り記号であることを保証できない場合、パイプサイズの区切り文字になるという保証がないためです。完全なデータブロック。
(echo AAAA; sleep 1; echo BBBBBB) | dd bs=3 > /dev/null
3+2 records in
3+2 records out
私たちが読んだものを書くので、実際には大きな問題ではありませんがcount
。
GNUはこの問題を解決するdd
必要があります。-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