2026 원격 Mac rsync `--link-dest`·`--copy-dest` 증분 스냅샷과 스테이징: 디스크·스캔·inode와 원자 릴리스 연결
원격 Mac에 iOS/macOS 산출물을 매번 풀복사하면 NVMe 쓰기와 inode가 빠르게 고갈되고 백업·CI와 대역을 뺏깁니다. 동일 APFS 볼륨에서 rsync --link-dest로 변경 없는 블록을 하드링크 공유하고, 링크 불가 객체는 --copy-dest로 보완합니다. 이후 원자 릴리스, SHA256 무결성 게이트, files-from·매니페스트를 같은 파이프라인에 배치하는 것이 2026년 현장에서 재현성이 높습니다.
목차(TOC)
1. 세 가지 통증: 풀복사, 반쯝 공개 창, inode·스캔
디스크·시간: 전체 트리 복제는 링크·xattr까지 포함해 지연을 키우고 파생 데이터와 경쟁합니다.
반쯝 공개 창: 공개 트리에 직접 rsync하면 중단 시 신·구 혼재가 남습니다. 스테이징에 가두고 검증 뒤 심볼릭을 한 번만 바꿉니다(원자 릴리스).
inode·스캔: 하드링크는 블록은 공유해도 디렉터리 항은 늘어납니다. 거대 트리는 먼저 --files-from으로 열거 면을 줄입니다.
- 복제 배수: 세 세대 풀 보관은 논리 크기가 약 3배로 보입니다. link-dest는 동일 데이터에 묶습니다.
- 롤백 근거: 직전 성공본이 없으면 link-dest 전제가 깨집니다. N-1은 반드시 남깁니다.
- 병렬 충돌: 동일 프리픽스에 동시 rsync하면 반쯝 링크 트리가 노출됩니다. 잡 ID로 서브디렉터리를 쪼갭니다.
2. 결정표: link-dest, copy-dest, tarball, 링크 없는 rsync
증분 링크가 tarball·풀 rsync보다 유리한지 빠르게 가르는 표입니다.
| 축 | `--link-dest` 증분 | `--copy-dest` 보조 | 계층 tarball | 링크 없는 staging rsync |
|---|---|---|---|---|
| 디스크 | 미변경 블록 공유, 배수≈1+Δ | 일부 파일 풀복사 | 단일 파일 업로드, 스캔 낮음 | 세대마다 풀복제 |
| 동일 FS | 강한 의존 | 약한 의존 | 볼륨 간 이동 가능 | 볼륨 간 가능 |
| 스캔 비용 | 경로 집합 비례 | 동일 | 낮음 | 높음 |
| 원자 전환 | 스테이징과 궁합 | 궁합 | 풀릴 창 필요 | 궁합 |
3. How-to: 디렉터리, 기준본, 일곱 단계
예: /srv/releases/build-…/를 불변으로 쌓고 /srv/releases/current는 심볼릭으로 둡니다. PREV는 게이트 통과 직전본 절대 경로를 CI가 주입하고 사람이 current를 만지지 않습니다.
# PREV=/srv/releases/build-20260506-183000
# NEXT=/srv/releases/build-20260507-091500
rsync -a --delete --link-dest="$PREV" \
${LOCAL_BUILD}/ "ci@${REMOTE_MAC}:$NEXT/"
- PREV 건전성: manifest가 비면 맹신하지 말고 풀 시드로 재구축합니다.
- NEXT 준비: 빈 디렉터리를 만들고 소유·모드를 PREV에 맞춥니다.
- files-from: 거대 트리는 manifest로 대상을 확정한 뒤 link-dest를 얹습니다.
- SSH 생존:
ServerAliveInterval등으로 장거리 끊김을 줄입니다. - SHA256 게이트:
shasum -a 256과 manifest 일치를 필수로 둡니다(무결성 글). - current 전환: 성공 후에만
ln -sfn "$NEXT" /srv/releases/current입니다. - 보존·삭제: N세대 정책에 맞춰 삭제 전 PREV를 참조하는 잡이 없는지 확인합니다.
# 링크 불가 소수 객체에 copy-dest 병행 예시
rsync -a --link-dest="$PREV" --copy-dest="$PREV" \
./artifacts/ "ci@${REMOTE_MAC}:$NEXT/"
4. 성능·리스크: 스캔, 교차 마운트, 권한·비링크
교차 마운트는 최우선 레드라인입니다. 다른 APFS 컨테이너·USB·네트워크 마운트는 링크 가능성이 달라집니다. df로 디바이스 일치를 확인하고 불가면 tarball 쪽으로 기울입니다.
특수 파일(소켓, FIFO, 일부 디바이스)은 링크 불가입니다. --copy-dest로 실패 확률을 낮추되 manifest에 타입 열을 두어 감사 가능하게 둡니다.
권한·xattr: 필요 플래그는 rsync 버전에 따라 다릅니다. 기준 트리에 잘못된 chmod가 다음 세대로 전파되므로 기준은 읽기 중심으로 운용합니다.
5. 지표: 디스크 배수, 링크 수, 롤백 SLA
작은 바이너리 델타에서는 추가 디스크를 풀 대비 수%~35% 수준으로 누르는 사례가 많습니다. 디렉터리 항은 세대에 선형이므로 청소 규칙을 별도로 둡니다.
게이트 초, 전환 초, 롤백 초를 메트릭으로 남기고 exit code만 신뢰하지 않습니다(예: 120s/1s/30s 임시 SLO).
6. FAQ: 병렬 잡·매니페스트·게이트 결합
질문: link-dest가 SHA256을 대체하나요? 답: 아니요. 용량·복제 시간만 줄이고 변조 탐지는 매니페스트 책임입니다.
질문: 동일 NEXT를 여러 사람이 쓰나요? 답: 금지합니다. 잡 ID로 분리하고 합격본만 승격합니다.
질문: 수동 SFTP와 혼용은? 답: 권위가 이중화되면 기준 트리와 실체가 갈라져 다음 증분 전제가 깨집니다. 경로를 단일화합니다.
7. 정리와 호스팅 Mac 전환
--link-dest를 스테이징·매니페스트·SHA256·심볼릭 전환 열에 넣으면 원격 Mac의 세대 보관 비용을 선형에서 델타 근처로 당길 수 있습니다.
대신 동일 볼륨·권한 위생·병렬 격리가 필요하고 자체 노드는 공유 계정·대역 경쟁으로 절약분이 공수로 소모되기도 합니다.
격리·가시성·감사 기본값을 초기부터 원하면 SFTPMAC 원격 Mac 렌탈과 헬프를 참고해 증분·원자 릴리스를 호스트 기준으로 이식하는 편이 재작업을 줄입니다.