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