btrfs send
테라바이트 규모의 데이터를 전송하는 데 사용할 수 있지만 receive
이러한 명령은 유용한 진행 출력을 생성하지 않습니다(사용된 경우에도 -v
).성공 여부를 어떻게 확인하나요?
예를 들어, 라는 새 하위 볼륨을 생성하는 경우 source
여기에 1GB의 임의 데이터를 쓰고 전송할 수 있도록 읽기 전용으로 설정합니다.
# btrfs subvolume create source
# head -c 1G < /dev/urandom > source/data
# btrfs property set source ro true
btrfs send
그런 다음 새 하위 볼륨의 복사본을 사용하고 생성하되 receive
완료되기 전에 프로세스를 중단합니다.
# mkdir destination
# btrfs send source | btrfs receive destination
At subvol source
At subvol source
^C
btrfs subvolume list
문제가 없음을 나타냅니다.
# btrfs subvolume list .
ID 1216 gen 370739 top level 5 path source
ID 1219 gen 371244 top level 5 path destination/source
새 하위 볼륨을 정상적으로 탐색할 수 있지만 해당 데이터가 명백히 손상되었습니다.
# exa -lT
- ├── destination
- │ └── source
251M │ └── random_data
- └── source
1.1G └── random_data
btrfs subvolume show destination/source
하위 볼륨이 불완전하다는 경고는 표시되지 않습니다. 이는 s 가 s 와 동일하지 않음을 나타내며 destination/source
실행이 완료된 경우에만 s 가 s 로 설정되는 것처럼 보입니다.UUID
source
destination/source
Received UUID
source
UUID
btrfs receive
Received UUID
생성된 하위 볼륨이 btrfs receive
다른 파일 시스템에 있는 해당 UUID가 있는 하위 볼륨의 수정되지 않은 완전 복사본이라는 것이 보장 됩니까 ?
이 부분man btrfs-send
destination/source
그렇게 하지 않는 것이 좋습니다 . 위 예에서 향후 스냅샷의 상위 스냅샷을 사용하면 source
손상을 감지하고 복구하지 못할 수도 있음을 암시하는 것 같습니다 . 그러나 이 조언의 목적 send -c
과 이 조언이 send -p
.
증분 모드(옵션
-p
및-c
)에서는 송신자와 수신자 모두가 사용할 수 있는 이전에 전송된 스냅샷을 사용하여 전송된 스냅샷을 다른 파일 시스템에서 재구성하기 위해 전송해야 하는 정보의 양을 줄일 수 있습니다.
-p <parent>
주어지면 이 옵션을 생략할 수 있으며-c <clone-src>
, 이 경우 btrfs send는 복제 소스에서 적절한 상위 항목을 결정합니다.이러한 스냅샷이 양쪽(송신자와 수신자) 모두에서 정확히 동일한 상태에 있다는 것을 보장하지 않는 한 복제 소스를 지정할 수 없습니다.
내가 아는 한,snap-sync
,buttersink
및 기타 유사한 도구는 출력을 btrfs send
일련의 파일로 리디렉션하고 신뢰할 수 있는 방법( rsync
단순 파이프가 아닌)을 사용하여 전송함으로써 이 문제를 해결합니다. 배포판에 포함되지 않은 타사 소프트웨어에 의존하지 않고 자체 증분 백업 솔루션을 개발하려는 경우 이것이 올바른 접근 방식입니까?
답변1
Received UUID
핵심요약: 이 플래그가 설정되어 있으면 readonly
부주의나 악의가 개입되지 않는 한 문제가 발생할 가능성이 없습니다.
@timakro가 이미 답변에서 말했듯 Received UUID
이 전송이 완료될 때까지 설정되지 않습니다. 플래그도 마찬가지입니다 readonly
. 이는 스트림의 모든 명령이 체크섬 처리된다는 사실과 결합되어(내가 아는 한 전송된 메타데이터에도 체크섬이 포함되어 있음) 수신 측에서 손상된 스냅샷으로 끝날 가능성이 낮아집니다 readonly
. Received UUID
. 이들 중 하나라도 설정되지 않으면 btrfs는 향후 참조를 위해 해당 스냅샷 사용을 거부합니다 btrfs receive
.
특별히 제작된 스트림을 수신하거나 일부 프로세스 또는 사용자가 수신된 스냅샷을 수신하는 동안 해당 내용을 변경하는 경우 의도적인 손상이 발생할 수 있습니다. btrfs-receive
맨페이지 에서 :
실수
btrfs receive는 성공적으로 완료되면 하위 볼륨을 읽기 전용으로 설정합니다. 그러나 수신 프로세스 중에 수신 경로의 파일 또는 디렉터리에 대한 쓰기 권한이 있는 사용자는 파일을 추가, 삭제 또는 수정할 수 있습니다. 이 경우 결과 읽기 전용 하위 볼륨은 전송 하위 볼륨의 정확한 복사본이 아닙니다.
정확한 복사본을 생성하는 것이 목적인 경우 수신 작업이 완료되고 하위 볼륨이 읽기 전용으로 설정될 때까지 수신 경로를 사용자 액세스로부터 보호해야 합니다.
또한 현재 수신은 델타 전송 스트림이 실제로 의미가 있는지 확인하는 작업을 제대로 수행하지 못하므로 특별히 제작된 전송 스트림이 동일한 파일 시스템의 임의 파일에 대한 참조 링크가 포함된 하위 볼륨을 생성할 수 있습니다. 따라서 사용자는 신뢰할 수 없는 소스의 전송 스트림에 대해 btrfs 수신을 사용하지 말고 신뢰할 수 없는 네트워크를 통해 신뢰할 수 있는 스트림을 보낼 때 신뢰할 수 있는 스트림을 보호하는 것이 좋습니다.
readonly
또한 하위 볼륨의 플래그를 비활성화하고 내용을 수정한 다음 다시 활성화할 수 있다는 점도 주목할 가치가 있습니다 . 어느 쪽이든 이렇게 하면 모든 보장은 사라질 것입니다.
출력을 파일로 파이프하고 파일을 전송하는 것은아니요위의 보호 중 하나를 제공하십시오. 개인적으로 btrfs send
의 출력을 ssh
. 스트림을 파일에 중간에 저장하면 신뢰할 수 없는 연결로 인해 중단된 전송을 재개할 수 있다는 이점이 있습니다.아니요데이터 무결성 형태로는 어떠한 보장도 제공되지 않습니다.
수신된 스냅샷이 전송된 스냅샷과 일치하는지 확인하는 좋은(완벽하지는 않지만) 방법은 를 사용하는 것입니다 rsync -avcn --del path/to/sent/snapshot/ user@remote:path/to/received/snapshot/
.
답변2
나는 당신이 말한 마지막 부분만을 기반으로 한 12개 이상의 백업 시스템을 가지고 있습니다. 1TB가 넘는 네트워크 백업을 처리하고 있기 때문에 직접 파이프는 선택 사항이 아니었습니다. 약간의 손실과 시간 낭비를 감수할 수는 없습니다.
내 최종 설정은 다음과 같습니다.
부팅 단계:
- 첫 번째 전체 스냅샷 찍기
- 스냅샷을 로컬 파일로 보내기(-f 옵션)
- 재동기화 또는 물리적 미디어 전송 스냅샷 파일을 원격 사이트로 전송합니다.
- 첫 번째 스냅샷을 원격으로 수신
증분 단계:
새로운 로컬 스냅샷
현재 스냅샷과 이전 스냅샷 사이의 diff 파일을 로컬에서 생성하고 전송합니다.
원격 사이트로 재동기화
전송된 스냅샷 파일을 원격으로 가져오기
정리 논리(오래된 스냅샷 유지, 삭제 고려...)
이 프로젝트는 3년 동안 진행되어 왔습니다. 최악의 경우 스냅샷이 일치하지 않는 경우 마지막 두 개(로컬 1개, 원격 1개)를 삭제하면 다음 전송 시 다시 작동하게 됩니다.
행운을 빌어요
답변3
Received UUID
생성된 하위 볼륨이btrfs receive
다른 파일 시스템에 있는 해당 UUID가 있는 하위 볼륨의 수정되지 않은 완전 복사본이라는 것이 보장 됩니까 ?
이 Received UUID
필드는 하위 볼륨을 수신한 후에만 설정됩니다. ~에서btrfs-progs 소스:
@received_uuid: 이 하위 볼륨이 수신된 하위 볼륨의 UUID이거나, 이 하위 볼륨이 수신되지 않은 경우 모두 0입니다. 이 필드 @stransid, @rtransid, @stime 및 @rtime은 하위 볼륨을 수신한 후 사용자 공간에 의해 수동으로 설정됩니다.
자세한 정보 표시 모드에서도 이를 확인할 수 있습니다.
$ btrfs send -v 2020-12-28/ | ssh root@link "btrfs receive -v /mnt/test"
At subvol 2020-12-28/
BTRFS_IOC_SEND returned 0
joining genl thread
At subvol 2020-12-28
receiving subvol 2020-12-28 uuid=778ec7aa-6709-d240-b41d-58d99a6fb9a0, stransid=9
BTRFS_IOC_SET_RECEIVED_SUBVOL uuid=778ec7aa-6709-d240-b41d-58d99a6fb9a0, stransid=9
답변4
@timakro의 사례를 테스트했지만 작동하지 않습니다. 완전히 전송되지 않은 스냅샷에는 여전히 UUID가 있습니다.
먼저, 별도로 마운트된 두 개의 btrfs 볼륨이 있습니다.
➜ lsblk|grep loop99
loop99 7:99 0 1G 0 loop
|-loop99p1 259:0 0 512M 0 part /mnt/tmp1
`-loop99p2 259:1 0 486M 0 part /mnt/tmp2
그런 다음 첫 번째 btrfs 볼륨에 새 하위 볼륨을 만들고 해당 하위 볼륨에 임의의 파일을 만들었습니다.
➜ sudo btrfs subvolume create tmp1/ori
Create subvolume 'tmp1/ori'
➜ sudo dd if=/dev/urandom of=tmp1/ori/test.iso bs=1M count=256
256+0 records in
256+0 records out
268435456 bytes (268 MB, 256 MiB) copied, 1.58701 s, 161.3 MB/s
읽기 전용 스냅샷을 생성한 후 이를 두 번째 btrfs 볼륨으로 전송하고 전송을 중단합니다.
➜ sudo btrfs subvolume snapshot -r tmp1/ori tmp1/snap
Create a readonly snapshot of 'tmp1/ori' in 'tmp1/snap'
➜ sudo btrfs send tmp1/snap | sudo btrfs receive tmp2
At subvol tmp1/snap
At subvol snap
^C
해시를 통해 수신된 스냅샷이 원본과 다르며 이는 손상되었음을 의미합니다.
➜ sudo sha256sum tmp1/snap/test.iso
49455edf92d582346215679a52eb6d72f0afa10748ef62f1ce3fc5e417e70f6a tmp1/snap/test.iso
➜ sudo sha256sum tmp2/snap/test.iso
bb30f487a39579dabc768129d59d4abeca25777e4eeb4f41b9beca366d379bab tmp2/snap/test.iso
이제 UUID를 확인해 보겠습니다.
➜ sudo btrfs subvolume list tmp1 -u
ID 257 gen 25 top level 5 uuid b5f8ff5d-fafb-814a-a31b-25bb96c185b5 path ori
ID 258 gen 25 top level 5 uuid d2bfa408-b330-954f-9aa8-138de5030898 path snap
➜ sudo btrfs subvolume list tmp2 -u
ID 256 gen 31 top level 5 uuid 77950b38-812d-3646-88cd-8107def1eced path snap
불완전한 스냅샷에는 자체 UUID가 있으며 읽기 전용 플래그가 설정되지 않은 것 외에는 불완전한 상태를 나타내는 표시나 힌트가 없습니다.