ONTAP SnapMirror 관계를 만들었는데 목적지에 아무것도 넘어오지 않습니다. 또는 넘어가긴 하는데 원본에 있는 시간당 스냅샷이 DR에는 하나도 없습니다. 둘 다 흔한 상황이고, 원인은 서로 다른 곳에 있습니다.
이 글은 준비 순서를 일부러 틀려가며 어디서 막히는지, 그때 에러가 어디에 찍히는지를 실제 출력으로 확인한 기록입니다. 정책(비동기·동기)과 SnapMirror 라벨이 무엇을 결정하는지도 대조 실험으로 짚었습니다.

이 글의 실습 환경과 범위
이 글은 ONTAP Simulator 9.17.1 기반 가상 랩에서 직접 명령을 실행하고 그 출력을 근거로 작성했습니다. 실제 장비(FAS/AFF)와는 지원 기능·성능·하드웨어 동작에서 차이가 있으며, ONTAP 버전에 따라 명령과 출력이 달라집니다.
| 구성 | 값 |
|---|---|
| 스토리지 | ONTAP Simulator 9.17.1, 2노드 클러스터 cluster1 |
| 원본 | NFS_SVM:nfs_vol1 1GB — 애그리게이트 N2_data |
| 목적지 | DR_SVM:nfs_vol1_dr 1GB — 애그리게이트 N1_data |
확인을 위해 두 번째 클러스터를 하나 더 세웠습니다. 단일 노드짜리 drcluster 입니다. 그래서 이 글의 명령과 출력은 인터클러스터 LIF부터 클러스터 간 SnapMirror까지 전부 실제로 실행한 것입니다.
| 클러스터 | 구성 | 인터클러스터 LIF |
|---|---|---|
cluster1 | 2노드 (원본) | 192.168.126.24, 192.168.126.25 |
drcluster | 1노드 (목적지) | 192.168.126.60 |
1. 준비 순서 — 아래에서 위로 쌓는다
실무의 SnapMirror는 다른 사이트의 클러스터로 보냅니다. 그래서 관계를 만들기 전에 네트워크와 신뢰 관계를 먼저 세워야 합니다. 한 칸을 건너뛰면 다음 명령이 거부됩니다.
| 순서 | 무엇을 | 어디에 |
|---|---|---|
| 1 | 인터클러스터 LIF | 양쪽 클러스터의 모든 노드 |
| 2 | 클러스터 피어링 cluster peer create | 양쪽 클러스터 |
| 3 | SVM 피어링 vserver peer create | 원본 SVM ↔ 목적지 SVM |
| 4 | 관계 생성 · 초기화 snapmirror create → initialize | 목적지 클러스터에서 |
1-1. ⭐ 인터클러스터 LIF는 클러스터 관리 SVM에 만든다
클러스터끼리 주고받는 트래픽은 데이터 LIF가 아니라 인터클러스터 LIF를 탑니다. NetApp 문서는 “피어링하는 클러스터의 모든 노드에 인터클러스터 LIF를 만들어야 한다”고 명시합니다. [문서확인] 한 노드라도 빠지면 그 노드가 관여하는 전송이 실패합니다.
여기서 가장 헷갈리는 것이 -vserver 에 무엇을 넣느냐입니다. LIF가 올라갈 자리는 특정 노드의 포트인데, -vserver 는 노드가 아니라 관리 LIF들이 올라가 있는 클러스터 관리 SVM 입니다.
cluster1::> vserver show -fields vserver,type
vserver type
------------ -----
NFS_SVM data
cluster1 admin <-- 인터클러스터 LIF 는 여기에
cluster1-01 node <-- 여기가 아니다
cluster1-02 node
노드 SVM을 넣으면 이렇게 거부됩니다.
cluster1::> network interface create -vserver cluster1-01 -lif ic_wrong -service-policy default-intercluster -home-node cluster1-01 -home-port e0d -address 192.168.126.26 -netmask 255.255.255.0
Error: command failed: LIF creation on a Node Vserver is disallowed.
노드는
-home-node로 지정하고,-vserver에는 클러스터 관리 SVM을 넣습니다. 둘을 같은 것으로 착각하기 쉬운데, 에러 메시지(LIF creation on a Node Vserver is disallowed)가 이유를 정확히 말해주지 않아서 한 번은 걸립니다.
제대로 만들면 이렇습니다. 노드가 둘이므로 두 개를 만듭니다.
cluster1::> network interface create -vserver cluster1 -lif ic_lif_01 -service-policy default-intercluster -home-node cluster1-01 -home-port e0d -address 192.168.126.24 -netmask 255.255.255.0
cluster1::> network interface create -vserver cluster1 -lif ic_lif_02 -service-policy default-intercluster -home-node cluster1-02 -home-port e0d -address 192.168.126.25 -netmask 255.255.255.0
cluster1::> network interface show -role intercluster
Logical Status Network Current Current Is
Vserver Interface Admin/Oper Address/Mask Node Port Home
----------- ---------- ---------- ------------------ ------------- ------- ----
cluster1
ic_lif_01 up/up 192.168.126.24/24 cluster1-01 e0d true
ic_lif_02 up/up 192.168.126.25/24 cluster1-02 e0d true
만들 때 이런 경고가 같이 나옵니다. 랩처럼 포트가 하나뿐이면 넘어가도 되지만, 운영에서는 페일오버 그룹을 제대로 잡아야 노드 하나가 빠져도 인터클러스터 경로가 유지됩니다.
Warning: The configured failover-group has no valid failover targets for the
LIF's failover-policy. To view the failover targets for a LIF, use the
"network interface show -failover" command.
핵심 인자는 -service-policy default-intercluster 입니다. 이 정책이 실제로 무엇을 여는지 보면 이렇습니다.
cluster1::> network interface service-policy show -vserver cluster1 -policy default-intercluster
Vserver: cluster1
Policy Name: default-intercluster
Included Services: intercluster-core, management-https,
backup-ndmp-control
문서 기준으로 인터클러스터 LIF는 intercluster-core 서비스를 제공하는 LIF이고, 보통 이 기본 서비스 정책으로 만듭니다. [문서확인] 위 출력이 그 정의를 그대로 보여줍니다.
방화벽도 같이 봐야 합니다. 문서는 양방향으로 시작되는 TCP 통신이 포트 11104, 11105 에서 열려 있어야 하고, 로컬의 모든 인터클러스터 LIF가 원격의 모든 인터클러스터 LIF와 통신할 수 있어야 한다고 못박습니다. [문서확인] 방화벽이 한 방향만 열려 있어 피어링이 안 되는 사례가 여기서 나옵니다.
1-2. 클러스터 피어링 — 패스프레이즈를 주고받는다
원본 클러스터에서 상대의 인터클러스터 IP를 주고 패스프레이즈를 발급받습니다.
cluster1::> cluster peer create -address-family ipv4 -peer-addrs 192.168.126.60 -generate-passphrase
Notice:
Passphrase: d4yviqpFBiTgroE9A1GEiMbh
Expiration Time: 8/28/2026 13:04:29 +09:00
Intercluster LIF IP: 192.168.126.24
Peer Cluster Name: drcluster
Warning: make a note of the passphrase - it cannot be displayed again.
패스프레이즈에는 만료 시각이 있습니다. 기본 1시간이고, 다시 보여주지 않습니다. 상대 클러스터 담당자가 따로 있다면 그 안에 전달해야 합니다.
이제 목적지 클러스터에서 같은 패스프레이즈로 수락합니다. 여기서 한 번 걸립니다.
drcluster::> cluster peer create -address-family ipv4 -peer-addrs 192.168.126.24,192.168.126.25 -passphrase <패스프레이즈>
Error: invalid argument "-passphrase"
-passphrase는 명령줄 인자로 받지 않습니다. 명령을 치면 ONTAP이 프롬프트로 되물어서 입력받습니다. 스크립트로 자동화하려면 이 방식이 막히므로 REST API(POST /api/cluster/peers)를 쓰는 편이 낫습니다.-peer-cluster-name도 존재하지 않는 인자입니다.
$ curl -sk -u "admin:***" -X POST "https://<목적지 관리 IP>/api/cluster/peers" -H "Content-Type: application/json" -d '{ "remote": { "ip_addresses": ["192.168.126.24","192.168.126.25"] }, "authentication": { "passphrase": "<패스프레이즈>" } }'
⭐ 양쪽에서 각각 확인한다
cluster1::> cluster peer show
Peer Cluster Name Cluster Serial Number Availability Authentication
------------------------- --------------------- -------------- --------------
drcluster 1-80-000011 Available ok
drcluster::> cluster peer show
Peer Cluster Name Cluster Serial Number Availability Authentication
------------------------- --------------------- -------------- --------------
cluster1 1-80-000008 Available ok
한쪽만 보고 넘어가면 안 됩니다.
Availability: Available과Authentication: ok를 양쪽 클러스터에서 각각 확인합니다. 한쪽만 정상인 상태로 진행하면 SVM 피어링이나 전송에서 뒤늦게 막히고, 그때는 원인이 여기라는 걸 떠올리기 어렵습니다.
-instance 로 보면 경로와 암호화까지 드러납니다.
cluster1::> cluster peer show -instance
Peer Cluster Name: drcluster
Remote Intercluster Addresses: 192.168.126.60
Availability of the Remote Cluster: Available
Remote Cluster Nodes: drcluster-01
Remote Cluster Health: true
Unreachable Local Nodes: -
Authentication Status Administrative: use-authentication
Authentication Status Operational: ok
IPspace for the Relationship: Default
Encryption Protocol For Inter-Cluster Communication: tls-psk
Algorithm By Which the PSK Was Derived: jpake
인터클러스터 통신은 tls-psk 로 암호화되고, 그 사전 공유 키는 jpake 로 유도됩니다. 아까 주고받은 패스프레이즈가 여기에 쓰입니다. Unreachable Local Nodes 가 비어 있는지도 같이 봐야 합니다 — 여기에 노드 이름이 찍히면 그 노드의 인터클러스터 LIF에 문제가 있다는 뜻입니다.
2. SVM 피어링 — 없으면 여기서 즉시 거부된다
여기부터는 랩에서 직접 실행한 결과입니다. 클러스터가 하나라 1·2단계 없이 목적지 SVM과 DP 볼륨을 만들고 바로 관계를 걸어봤습니다.
cluster1::> vserver create -vserver DR_SVM -aggregate N1_data -rootvolume DR_SVM_root -rootvolume-security-style unix
[Job 82] Job succeeded: Vserver creation completed.
cluster1::> volume create -vserver DR_SVM -volume nfs_vol1_dr -aggregate N1_data -size 1GB -type DP
[Job 83] Job succeeded: Successful
cluster1::> snapmirror create -source-path NFS_SVM:nfs_vol1 -destination-path DR_SVM:nfs_vol1_dr -type XDP
Error: command failed: Vservers "NFS_SVM" and "DR_SVM" are not peered. Either
they are not in a Vserver peer relationship, the "Peer State" of the
relationship is not "peered", the "snapmirror" application is not
supported by the relationship or "NFS_SVM" is not the local name for the
peer-vserver.
이 에러는 친절한 편입니다. 명령이 즉시 거부되고 원인 후보 네 가지를 다 적어줍니다. 특히 “snapmirror 애플리케이션이 지원되지 않는다” 는 경우 — 피어 관계는 있는데 -applications snapmirror 를 빼먹었을 때입니다.
cluster1::> vserver peer create -vserver NFS_SVM -peer-vserver DR_SVM -applications snapmirror
Info: "vserver peer create" command is successful.
cluster1::> vserver peer show
Peer Peer Peering Remote
Vserver Vserver State Peer Cluster Applications Vserver
----------- ----------- ------------ ----------------- -------------- ---------
DR_SVM NFS_SVM peered cluster1 snapmirror NFS_SVM
NFS_SVM DR_SVM peered cluster1 snapmirror DR_SVM
같은 클러스터 안이라 바로 peered 가 됐습니다. 그런데 클러스터가 다르면 여기서 멈춥니다. 같은 명령을 drcluster 의 SVM을 상대로 걸어봤습니다.
cluster1::> vserver peer create -vserver NFS_SVM -peer-vserver DR2_SVM -peer-cluster drcluster -applications snapmirror
Info: [Job 87] 'vserver peer create' job queued
cluster1::> vserver peer show
Vserver Peer Vserver State Peer Cluster Applications
----------- ------------- -------------- -------------- ------------
NFS_SVM DR_SVM peered cluster1 snapmirror
NFS_SVM DR2_SVM initializing drcluster snapmirror
같은 관계인데 보는 쪽에 따라 상태 이름이 다릅니다. 요청한 쪽에서는
initializing, 수락해야 하는 쪽에서는pending으로 보입니다. 원본 클러스터만 들여다보면 “초기화 중인가 보다” 하고 기다리게 되는데, 실제로는 상대 쪽 승인을 기다리는 중입니다.
drcluster::> vserver peer show
Vserver Peer Vserver State Peer Cluster Applications
----------- ------------- ---------- -------------- ------------
DR2_SVM NFS_SVM pending cluster1 snapmirror
drcluster::> vserver peer accept -vserver DR2_SVM -peer-vserver NFS_SVM
Info: [Job 34] 'vserver peer accept' job queued
수락하고 나면 양쪽 모두 peered 가 됩니다.
cluster1::> NFS_SVM DR2_SVM peered drcluster snapmirror
drcluster::> DR2_SVM NFS_SVM peered cluster1 snapmirror
클러스터 간에서는 -peer-cluster 인자가 하나 더 필요하다는 것도 차이입니다. 같은 클러스터 안이면 생략합니다.
3. ⭐ 목적지는 DP 볼륨 — 그런데 create 는 성공한다
이 글에서 가장 볼 만한 지점입니다. 일반 RW 볼륨을 목적지로 지정해봤습니다.
cluster1::> volume create -vserver DR_SVM -volume wrong_dr -aggregate N1_data -size 1GB
[Job 84] Job succeeded: Successful
cluster1::> snapmirror create -source-path NFS_SVM:nfs_vol1 -destination-path DR_SVM:wrong_dr -type XDP
Operation succeeded: SnapMirror create for the relationship with destination "DR_SVM:wrong_dr".
cluster1::> snapmirror initialize -destination-path DR_SVM:wrong_dr
Operation is queued: SnapMirror initialize of destination "DR_SVM:wrong_dr".
둘 다 성공했다고 답합니다. 타입이 틀렸는데 경고 한 줄 없습니다. 실패는 몇 초 뒤 다른 곳에 찍힙니다.
cluster1::> snapmirror show -destination-path DR_SVM:wrong_dr -fields state,status,healthy,last-transfer-error
source-path destination-path state status healthy last-transfer-error
---------------- ---------------- ---------- ------ ------- -----------------------------------------------------------
NFS_SVM:nfs_vol1 DR_SVM:wrong_dr Broken-off Idle false Destination DR_SVM:wrong_dr must be a data-protection volume.
명령 두 개가 모두 “성공”이라고 답했는데 결과는
Broken-off입니다. 진짜 원인은last-transfer-error필드에만 있고,snapmirror show를 옵션 없이 치면 이 필드가 안 나옵니다. 그래서 “관계는 있는데 왜 전송이 안 되지” 상태로 한참 헤매게 됩니다.
cluster1::> snapmirror show -fields state,status,healthy,unhealthy-reason,last-transfer-error
4. 세 번째 함정 — 스케줄은 베이스라인을 대신 해주지 않는다
cluster1::> snapmirror create -source-path NFS_SVM:nfs_vol1 -destination-path DR_SVM:nfs_vol1_dr -type XDP -schedule hourly
cluster1::> snapmirror show -fields state,status,healthy,schedule
source-path destination-path schedule state status healthy
---------------- ------------------ -------- ------------- ------ -------
NFS_SVM:nfs_vol1 DR_SVM:nfs_vol1_dr hourly Uninitialized Idle true
스케줄이
hourly로 붙어 있는데도Uninitialized입니다. 베이스라인 전송은 스케줄이 해주지 않습니다.snapmirror initialize를 한 번 직접 쳐야 하고, 그 뒤부터 스케줄이 증분을 돌립니다.
$ sudo dd if=/dev/urandom of=/mnt/ontap-nfs/dataA.dat bs=1M count=100
cluster1::> snapmirror initialize -destination-path DR_SVM:nfs_vol1_dr
cluster1::> snapmirror show -fields state,status,healthy,last-transfer-size,last-transfer-duration
source-path destination-path state status healthy last-transfer-size last-transfer-duration
---------------- ------------------ ------------ ------ ------- ------------------ ----------------------
NFS_SVM:nfs_vol1 DR_SVM:nfs_vol1_dr Snapmirrored Idle true 102.5MB 0:0:24
4-1. 클러스터 간이면 경로 표기가 달라진다
피어링이 끝났으니 실제로 클러스터를 넘어 걸어봤습니다. 관계는 목적지 클러스터에서 만듭니다.
drcluster::> volume create -vserver DR2_SVM -volume nfs_vol1_xc -aggregate DR_data -size 1GB -type DP
drcluster::> snapmirror create -source-path cluster1://NFS_SVM/nfs_vol1 -destination-path drcluster://DR2_SVM/nfs_vol1_xc -type XDP -policy MirrorAllSnapshots
Operation succeeded: SnapMirror create for the relationship with destination "DR2_SVM:nfs_vol1_xc".
경로가
SVM:볼륨에서클러스터://SVM/볼륨로 바뀝니다. 같은 클러스터 안이면 앞의 짧은 형식을 쓰고, 클러스터를 넘으면 긴 형식을 씁니다. 이걸 모르고 짧은 형식으로 치면 상대 클러스터의 SVM을 못 찾습니다.
초기화하면 인터클러스터 LIF를 타고 실제로 넘어갑니다.
drcluster::> snapmirror initialize -destination-path DR2_SVM:nfs_vol1_xc
drcluster::> snapmirror show -fields state,status,healthy
source-path destination-path state status healthy
---------------- ------------------- ------------ ------------ -------
NFS_SVM:nfs_vol1 DR2_SVM:nfs_vol1_xc Snapmirrored Transferring true
그런데 이 전송이 한참 동안 끝나지 않았습니다. snapmirror show 만 보면 Transferring 에서 멈춘 것처럼 보이고, last-transfer-size 는 이전 전송 값이라 움직이지 않습니다. 이럴 때 봐야 하는 건 -instance 입니다.
drcluster::> snapmirror show -destination-path DR2_SVM:nfs_vol1_xc -instance
SnapMirror Policy: MirrorAllSnapshots
Mirror State: Snapmirrored
Relationship Status: Transferring
Transfer Snapshot: hourly.2026-08-28_0705 <-- 지금 넘기는 스냅샷
Snapshot Progress: 15.52MB
Total Progress: 15.53MB
Snapshot Checkpoint: 2.79MB
Newest Snapshot: daily.2026-08-28_0010
Exported Snapshot: daily.2026-08-27_0910
Healthy: true
Transfer Error: -
Last Transfer Size: 18.59KB <-- 직전 전송 값. 지금 것이 아니다
진행 중인 전송의 양은
Total Progress에 있습니다.last-transfer-size는 끝난 전송의 크기라 진행 중에는 갱신되지 않습니다. 둘을 혼동하면 “전송이 멈췄다”고 오판합니다.Transfer Error가 비어 있고Total Progress가 늘고 있으면 느린 것이지 멈춘 것이 아닙니다.
느린 이유는 정책에 있었습니다. MirrorAllSnapshots 는 이름 그대로 원본의 스냅샷을 전부 넘깁니다. 원본에 시간당 스냅샷이 쌓여 있으면 그 개수만큼 순차로 전송합니다. Transfer Snapshot 필드가 지금 어느 스냅샷을 넘기는 중인지 알려줍니다.
최신 상태만 필요하다면 MirrorLatest 를 쓰면 베이스라인이 훨씬 짧습니다. “스냅샷 이력까지 DR에 둘 것인가”가 정책 선택의 실제 기준이고, 그 대가가 이 시간입니다.
한 가지 더 — SnapMirror 라이선스는 양쪽 클러스터에 각각 필요합니다. 새로 세운 drcluster 에는 라이선스가 없어서 따로 넣어야 했습니다. 원본에만 있으면 되는 것이 아닙니다.
drcluster::> system license show -package SnapMirror
There are no entries matching your query.
drcluster::> system license add -license-code <SnapMirror 키>
License for package "SnapMirror" and serial number "1-81-...4082368507" installed.
5. 정책 — 비동기냐 동기냐를 여기서 정한다
SnapMirror의 동작은 관계에 붙은 정책이 결정합니다. 9.17.1에 기본 제공되는 정책을 그대로 옮기면 이렇습니다.
cluster1::> snapmirror policy show -fields policy,type
vserver policy type
-------- ------------------------- -------------------------
cluster1 MirrorAllSnapshots async-mirror
cluster1 MirrorLatest async-mirror
cluster1 DPDefault async-mirror
cluster1 XDPDefault vault
cluster1 DailyBackup vault
cluster1 MirrorAndVault mirror-vault
cluster1 Asynchronous mirror-vault
cluster1 Unified7year mirror-vault
cluster1 Sync sync-mirror
cluster1 StrictSync strict-sync-mirror
cluster1 AutomatedFailOver automated-failover
cluster1 AutomatedFailOverDuplex automated-failover-duplex
17 entries were displayed.
| 구분 | 타입 | 뜻 |
|---|---|---|
| 비동기 | async-mirror | DR용 미러. 원본 상태를 그대로 따라간다 |
vault | 백업용. 라벨이 붙은 스냅샷을 오래 보관한다 | |
mirror-vault | 둘을 합친 것. 최신 상태 + 라벨 스냅샷 보관 | |
| 동기 | sync-mirror | 복제 실패 시 클라이언트 I/O는 계속된다 |
strict-sync-mirror | 복제 실패 시 클라이언트 I/O도 실패시킨다 |
NetApp 문서는 이 차이를 이렇게 정리합니다 — Sync 모드에서는 애플리케이션 I/O가 주 스토리지와 보조 스토리지에 병렬로 전달되고, 보조 쪽 쓰기가 어떤 이유로든 완료되지 않아도 애플리케이션은 주 스토리지에 계속 쓸 수 있습니다. 반면 StrictSync 모드는 보조 쪽 쓰기가 실패하면 애플리케이션 I/O를 실패시켜 양쪽이 항상 동일하도록 보장합니다. [문서확인]
StrictSync는 “데이터 일치”를 위해 “서비스 중단”을 감수하는 선택입니다. 금융 원장처럼 한 건도 어긋나면 안 되는 데이터가 아니면 보통 Sync를 씁니다.
실제로 걸어보면 상태 표시가 다르다
같은 원본에 동기식 관계를 하나 더 만들어 비동기와 나란히 놓아봤습니다.
cluster1::> volume create -vserver DR_SVM -volume sync_dr -aggregate N1_data -size 500MB -type DP
cluster1::> snapmirror create -source-path NFS_SVM:nfs_vol1 -destination-path DR_SVM:sync_dr -policy Sync
cluster1::> snapmirror initialize -destination-path DR_SVM:sync_dr
cluster1::> snapmirror show -fields state,status,policy,policy-type,lag-time
source-path destination-path policy-type policy state status healthy lag-time
---------------- ------------------ ------------------ -------------- ------------ ------ ------- --------
NFS_SVM:nfs_vol1 DR_SVM:nfs_vol1_dr mirror-vault MirrorAndVault Snapmirrored Idle true 0:2:31
NFS_SVM:nfs_vol1 DR_SVM:sync_dr sync-mirror Sync Snapmirrored InSync true 0:0:0
동기식은
status가InSync이고lag-time이0:0:0입니다. 비동기식은Idle이고 다음 전송까지 lag가 쌓입니다. 동기식 관계에서InSync가 아니면 그 자체가 경보입니다 — 비동기의Idle과는 의미가 완전히 다릅니다.
참고로 관계를 만들 때 -policy 를 지정하지 않으면 기본값이 붙습니다. 위 첫 줄이 그 경우로, MirrorAndVault 가 자동으로 선택됐습니다. 의도한 정책이 맞는지 snapmirror show -fields policy 로 한 번은 확인하는 편이 좋습니다.
6. ⭐ 라벨 — 왜 hourly 스냅샷은 DR에 없는가
정책 안을 열어보면 SnapMirror 라벨이라는 항목이 나옵니다. 이게 어떤 스냅샷을 복제할지를 정합니다.
cluster1::> snapmirror policy show -policy MirrorAndVault -instance
SnapMirror Policy Name: MirrorAndVault
SnapMirror Policy Type: mirror-vault
Create Snapshot: true
Total Number of Rules: 3
Rules:
SnapMirror Label Keep Preserve Warn Schedule Prefix Retention Period
---------------------- ---- -------- ---- -------- ---------- ----------------
sm_created 1 false 0 - - -
daily 7 false 0 - - -
weekly 52 false 0 - - -
규칙이 셋입니다 — SnapMirror가 스스로 만드는 스냅샷(sm_created), 그리고 라벨이 daily 인 것 7개, weekly 인 것 52개. 이 목록에 없는 라벨은 복제 대상이 아닙니다.
그럼 원본의 스냅샷 정책은 어떤 라벨을 붙이고 있을까요.
cluster1::> snapshot policy show -policy default -instance
Snapshot Policy Name: default
Schedule Count Prefix SnapMirror Label
-------------- ----- ------------- ------------------
hourly 6 hourly - <-- 라벨이 없다
daily 2 daily daily
weekly 2 weekly weekly
기본 스냅샷 정책의
hourly에는 SnapMirror 라벨이 없습니다. 그래서 시간당 스냅샷을 아무리 많이 찍어도 DR에는 하나도 넘어가지 않습니다. 설정이 잘못된 게 아니라 기본값이 원래 그렇습니다.
대조 실험 — 라벨만 다른 스냅샷 두 개
변수를 하나만 남기고 확인했습니다. 같은 시점에, 라벨만 다르게 스냅샷 두 개를 만들었습니다.
cluster1::> snapshot create -vserver NFS_SVM -volume nfs_vol1 -snapshot label_daily_test -snapmirror-label daily
cluster1::> snapshot create -vserver NFS_SVM -volume nfs_vol1 -snapshot label_none_test
cluster1::> snapshot show -vserver NFS_SVM -volume nfs_vol1 -fields snapshot,snapmirror-label
vserver volume snapshot snapmirror-label
------- -------- ---------------- ----------------
NFS_SVM nfs_vol1 label_daily_test daily
NFS_SVM nfs_vol1 label_none_test -
cluster1::> snapmirror update -destination-path DR_SVM:nfs_vol1_dr
cluster1::> snapshot show -vserver DR_SVM -volume nfs_vol1_dr -fields snapshot,snapmirror-label
vserver volume snapshot snapmirror-label
------- ----------- -------------------------------------------- ----------------
DR_SVM nfs_vol1_dr snapmirror.394e013e-…_2153774456.…_110500 -
DR_SVM nfs_vol1_dr label_daily_test daily
DR_SVM nfs_vol1_dr snapmirror.394e013e-…_2153774456.…_112747 -
label_daily_test는 넘어갔고label_none_test는 넘어가지 않았습니다. 데이터도, 시점도, 크기도 같습니다. 다른 것은 라벨 하나뿐입니다.
실제로 원본에는 hourly 스냅샷이 6개 있었지만 목적지에는 SnapMirror가 만든 것과 라벨 붙은 것만 있었습니다. “DR에 시간당 복구 지점이 있을 것”이라고 믿고 있다가 사고 때 발견하면 늦습니다.
시간당 스냅샷도 DR에 두고 싶다면 두 가지를 맞춰야 합니다 — 원본 스냅샷 정책의 해당 스케줄에 라벨을 붙이고, SnapMirror 정책에 그 라벨 규칙을 추가합니다.
# 1) 원본 스냅샷 정책의 hourly 스케줄에 라벨을 붙인다
cluster1::> snapshot policy modify-schedule -policy <정책> -schedule hourly -newsnapmirror-label hourly
# 2) SnapMirror 정책에 그 라벨 규칙을 추가한다
cluster1::> snapmirror policy add-rule -vserver cluster1 -policy <정책> -snapmirror-label hourly -keep 6
둘 중 하나만 하면 안 됩니다. 라벨만 붙이고 정책에 규칙이 없으면 여전히 안 넘어가고, 규칙만 있고 라벨이 없으면 대상이 없습니다. [문서확인] NetApp 문서도 “복제할 스냅샷에 지정하는 SnapMirror 라벨은 원본의 스냅샷 정책에서 지정한다”고 설명합니다.
파라미터 이름에 함정이 있습니다. 라벨을 새로 만들 때는 snapshot policy create -snapmirror-label1 이지만, 기존 스케줄을 고칠 때는 -snapmirror-label 이 아니라 -newsnapmirror-label 입니다. 앞의 이름으로 치면 Error: invalid argument "-snapmirror-label" 이 납니다 — 9.17.1에서 직접 확인했습니다.
7. 전송량 — 스냅샷을 기준점으로 삼는다
$ sudo dd if=/dev/urandom of=/mnt/ontap-nfs/dataB.dat bs=1M count=10
cluster1::> snapmirror update -destination-path DR_SVM:nfs_vol1_dr
cluster1::> snapmirror show -fields last-transfer-size,last-transfer-duration,lag-time
source-path destination-path last-transfer-size last-transfer-duration lag-time
---------------- ------------------ ------------------ ---------------------- --------
NFS_SVM:nfs_vol1 DR_SVM:nfs_vol1_dr 10.25MB 0:0:14 0:0:31
| 동작 | 전송량 | 시간 |
|---|---|---|
| 베이스라인 (100MB 파일) | 102.5MB | 24초 |
10MB 추가 후 update | 10.25MB | 14초 |
break 후 resync | 3.53KB | 즉시 |
전체를 다시 보내지 않습니다. 두 볼륨이 공통으로 가진 스냅샷이 기준점이고 그 뒤 변경분만 갑니다. 그래서 스냅샷을 함부로 지우면 안 됩니다 — 공통 스냅샷이 사라지면 증분이 끊기고 베이스라인부터 다시 해야 합니다.
lag-time 은 목적지가 원본보다 얼마나 뒤처져 있는지입니다. 이 값이 스케줄 주기보다 계속 커지면 전송이 못 따라가고 있다는 뜻입니다. 모니터링에서 실제로 봐야 하는 값이 이것입니다.
8. ⭐ 복제가 되어도 서비스는 안 된다
cluster1::> volume show -vserver DR_SVM -volume nfs_vol1_dr -fields type,size,used,state,junction-path
vserver volume size state junction-path used type
------- ----------- ---- ------ ------------- ------- ----
DR_SVM nfs_vol1_dr 1GB online /nfs_vol1_dr 101.6MB DP
cluster1::> network interface show -vserver DR_SVM
There are no entries matching your query.
데이터는 101.6MB가 들어와 있고 junction까지 걸려 있는데, DR SVM에는 데이터 LIF가 하나도 없습니다. 복제 트래픽은 인터클러스터 경로로 도는 일이라 데이터 LIF가 없어도 잘 돕니다. 하지만 재해가 나서 이걸 서비스로 올릴 때는 LIF·export policy·DNS가 전부 새로 필요합니다.
“SnapMirror 걸어놨으니 괜찮다”가 위험한 이유입니다. 데이터는 안전해도 서비스는 준비되어 있지 않습니다. 전환 절차를 문서로 만들어두고 한 번은 실제로 해봐야 합니다.
9. break 와 resync — 전환 리허설
cluster1::> snapmirror break -destination-path DR_SVM:nfs_vol1_dr
cluster1::> volume show -vserver DR_SVM -volume nfs_vol1_dr -fields type
vserver volume type
------- ----------- ----
DR_SVM nfs_vol1_dr RW <-- DP 에서 RW 로 바뀌었다
cluster1::> snapmirror show -fields state,healthy
source-path destination-path state healthy
---------------- ------------------ ---------- -------
NFS_SVM:nfs_vol1 DR_SVM:nfs_vol1_dr Broken-off true
Broken-off인데healthy: true입니다. 3절의 실패한 관계도Broken-off였지만 그때는healthy: false였습니다. 같은 상태 이름이 정상 전환일 수도, 장애일 수도 있습니다. 둘을 가르는 것이healthy필드입니다.
cluster1::> snapmirror resync -destination-path DR_SVM:nfs_vol1_dr
cluster1::> snapmirror show -fields state,last-transfer-size
source-path destination-path state last-transfer-size
---------------- ------------------ ------------ ------------------
NFS_SVM:nfs_vol1 DR_SVM:nfs_vol1_dr Snapmirrored 3.53KB
3.53KB만 오갔습니다. 공통 스냅샷이 아직 양쪽에 있어서 그 차이만 맞추면 되기 때문입니다. 볼륨 타입도 RW에서 DP로 되돌아갑니다.
다만 break 이후 목적지에 쓴 데이터는 resync 때 버려집니다. 재해 전환 후 목적지에서 계속 서비스했다면 그 변경분을 살려야 하므로, 원본 쪽을 목적지로 삼는 역방향 관계를 만들어 되돌리는 절차를 씁니다. 이 랩은 목적지에 쓰지 않았으므로 그냥 되돌렸습니다.
덤 — 볼륨을 지워도 공간이 바로 안 돌아온다
cluster1::> volume delete -vserver DR_SVM -volume wrong_dr
Info: Volume "wrong_dr" in Vserver "DR_SVM" will be marked as deleted and
placed in the volume recovery queue. The space used by the volume will be
recovered only after the retention period of 12 hours has completed.
지운 볼륨이 12시간 복구 큐에 남고 그동안 공간도 안 돌아옵니다. 실수로 지웠을 때 살릴 수 있다는 뜻이라 좋은 기능이지만, “볼륨 지웠는데 애그리게이트 여유가 그대로”라고 당황하는 자리이기도 합니다. 급하면 volume recovery-queue purge 로 즉시 비웁니다.
정리 — 전송이 안 될 때 점검 순서
| 증상 | 확인 |
|---|---|
| 인터클러스터 LIF가 안 만들어진다 | -vserver 에 노드가 아니라 클러스터 관리 SVM을 넣었는지 (LIF creation on a Node Vserver is disallowed) |
| 클러스터 피어링이 안 된다 | 인터클러스터 LIF가 모든 노드에 있는지. 포트 11104·11105 양방향 |
cluster peer show 가 한쪽만 정상 | 양쪽 클러스터에서 각각 Availability·Authentication 확인. -instance 의 Unreachable Local Nodes 도 비어 있어야 한다 |
SVM 피어가 initializing 에서 안 변한다 | 초기화 중이 아니라 상대 승인 대기다. 목적지에서 vserver peer accept |
snapmirror create 가 거부된다 | vserver peer show — peered 인지, snapmirror 애플리케이션이 있는지. 클러스터 간이면 경로를 클러스터://SVM/볼륨 로 |
| 클러스터 간인데 라이선스 오류 | SnapMirror 라이선스는 양쪽 클러스터에 각각 필요하다 |
Uninitialized 에서 안 변한다 | 베이스라인은 스케줄이 안 해준다. snapmirror initialize 직접 실행 |
Broken-off + healthy false | -fields last-transfer-error 로 사유 확인. 목적지 볼륨 타입이 첫 후보 |
Broken-off + healthy true | 정상. break 로 전환된 상태 |
동기식인데 InSync 가 아니다 | 그 자체가 경보. 비동기의 Idle 과 의미가 다르다 |
| 특정 스냅샷이 DR에 없다 | 라벨. 원본 스냅샷 정책의 라벨 ↔ SnapMirror 정책 rule 을 맞춘다 |
Transferring 에서 멈춘 것 같다 | -instance 의 Total Progress 를 본다. last-transfer-size 는 직전 전송 값이라 안 움직인다 |
| 베이스라인이 유난히 오래 걸린다 | 정책이 MirrorAllSnapshots 면 스냅샷을 전부 넘긴다. 최신만 필요하면 MirrorLatest |
| 전송은 되는데 계속 밀린다 | lag-time 추이. 스케줄 주기보다 커지면 못 따라가는 것 |
| 복제는 되는데 접속이 안 된다 | network interface show -vserver <DR SVM> — 데이터 LIF가 아예 없을 수 있다 |
SnapMirror에서 헷갈리는 대부분은 “명령이 성공을 보고했는데 실제로는 안 되고 있는” 구간에서 나옵니다. create 도 initialize 도 성공이라고 답한 뒤 last-transfer-error 에만 진실이 남아 있었고, 라벨이 없는 스냅샷은 에러 없이 조용히 복제되지 않았습니다. state 하나만 보지 말고 healthy·last-transfer-error·lag-time 을 같이 보는 습관이 시간을 아껴줍니다.
같은 볼륨을 다루는 다른 글도 함께 보시면 도움이 됩니다 — 파일을 지워도 용량이 안 줄어드는 글은 이 글의 증분 전송이 무엇 위에 서 있는지를 설명해주고, NFS 마운트가 access denied로 거부될 때는 재해 전환 후 목적지를 서비스로 올릴 때 다시 만나는 문제입니다.
참고 문서 — ONTAP peering basics · ONTAP peering prerequisites · Create cluster peer relationships · Create intercluster SVM peer relationships · SnapMirror synchronous disaster recovery · Define a rule for a SnapMirror policy · snapmirror policy create (CLI)


