【NetApp】ONTAPバージョンの異なるクラスタ間でのSnapMirror逆再同期で苦戦した話

2022年10月1日

こんにちは、キクです。

最近、僕はNetAppで新しいクラスタを作成するという業務に取り組んでいました。
その中で既存のクラスタとの間でSnapMirror関係を構築する作業があったのですが、一部想定と異なる動作をして苦戦を強いられるという経験をしました。
具体的には「異なるONTAPバージョンのクラスタ間で逆再同期ができなかった」というもの。
ただ、完全にできなかったわけではなく、一部できなかったという状態。

クラスタBからクラスタAへの逆再同期はできるけど、クラスタAからクラスタBへの逆再同期はできない・・・?

こんな感じで頭が「?」になったわけですが、無事に解決することができたので記事に残したいなと思いました。
というわけで、今回は『異なるONTAPバージョン間での逆再同期』をテーマに書いていきたいと思います!

それでは、よろしくお願いします。

動作環境

本記事の内容は下記の環境で実施したものになります。
・ONTAP 9.3
・ONTAP 9.8

注意事項

本記事は僕が経験した内容をもとに記載しておりますが、
実行環境や設定内容によっては動作が異なる場合があります。
そのため『参考程度』にお読みいただけますと幸いです。

作業背景

本章では、本記事で取り扱う「異なるONTAPバージョンのクラスタ間での逆再同期」で苦戦を強いられるまでの背景についてお話ししていきたいと思います。
今回のSnapMirror関係の最初の状態、そして最終状態も以下のような構成となります。

この構成を簡単に説明すると、通常時にはオンサイト側のクラスタAに保存しているデータを利用し、DR対策としてオフサイト側のクラスタBにSnapMirrorでデータを同期しています。

なお、以降の内容については、こちらに登場する各キーワードを用いて話を進めていければと思います。

実際に「逆再同期ができない」という事態に遭遇するまでには、以下の作業を実施しました。

エラー発生までに実施した作業内容

・SnapMirror設定
・SnapMirror関係の解除
・オフサイト(ONTAP9.3)からオンサイト(ONTAP9.8)への逆再同期を実施
・SnapMirror関係の解除
・オンサイト(ONTAP9.8)からオフサイト(ONTAP9.3)への逆再同期を実施

作業1では、一般的なSnapMirror設定を実施しています。
以前、SnapMirrorの基礎的な部分を整理した記事を書いたので、気になる方はそちらもご一読いただけると嬉しいです。
関連記事:【NetApp】SnapMirrorの基本的な概念と設定方法

作業2〜5は、DR対策として取り入れたSnapMirror関係が正常に動作するかを確認するための作業となります。
具体的には、作業3でオフサイト側に同期しているデータをオンサイト側に逆再同期することでデータをリストアし、作業5を実施することで元のSnapMirror関係に復旧することが狙いです。
しかし、作業5を実行したタイミングで以下のようなエラーが発生してしまい、元のSnapMirror関係に復旧できないという状態に陥ってしまいました。

Remote peer cluster "Cluster-B" requires an effective cluster version of "9.5.0" or later to support "flip"

逆再同期には「Flip Resync」や「Reverse Resync」などいくつか呼び方があるみたいで、上記エラー文の「flip」は逆再同期を示していると認識して大丈夫です。
そのため、上記のエラー文は「クラスタBに逆再同期したいならONTAP 9.5.0以上である必要がある」という意味になり、今回の環境ではクラスタBはONTAP9.3なので実質的に逆再同期ができないと言われてしまいました。
よって「データは復旧できているけど、SnapMirror関係の復旧ができない」という状態になってしまっています。
これが本記事のテーマとして扱う「問題部分」となります。

以降の章からは、今回の構成でデータおよびSnapMirror関係の復旧をする方法をご紹介します。

ちなみに、本記事では上記の作業5の状態からの復旧方法ではなく、最初のSnapMirror設定時点からの作業となるので、あらかじめご了承ください。

補足事項

本記事では、各手順での結果を分かりやすくするために作業対象以外のSnapMirror関係は設定していないものとします。

1. SnapMirror関係の解除

それでは、本題に入っていこうと思います。
まず最初に行うのは「SnapMirror関係の解除」になります。
これは上記の「作業2」と同じ内容で、次章で実施する「逆再同期」のための事前準備となります。

SnapMirrorによって同期状態の各ボリュームは次のようなタイプになっています。

ボリュームタイプ

ソースボリューム  :RW(Read / Write)
ターゲットボリューム:DP(Data Protect)

RWは「読み書き可能」な状態、DPはデータ保護モードと呼ばれる「読み込みのみ可能」な状態です。

SnapMirror関係の解除を実施することで、ターゲットボリュームのタイプが「RW」になります。
これによって「逆再同期」が実施可能な状態になります。

作業内容(クラスタB側)

まず、以下のコマンドを実行して対象ボリュームのタイプが「DP」となっていることを確認します。

::> volume show

次に、以下のコマンドで現在のSnapMirror関係を確認していきます。

::> snapmirror show

この時点では、まだSnapMirror関係は正常に保たれているので、Mirror Stateが「Snapmirrored」になっていることを確認できればOKです。

続いて、以下のコマンドによりSnapMirror関係の解除を実施していきます。

::> snapmirror break -source-path ソースSVM名:ソースボリューム名 -destination-path ターゲットSVM名:ターゲットボリューム名
[入力例]

::> snapmirror break -source-path srcSVM:srcVOL -destination-path dstSVM:dstVOL

改めてSnapMirror関係の状態を確認していきます。

::> snapmirror show

SnapMirror関係が解除され、Mirror Stateが「Broken-off」になっていれば成功です。

最後に、対象ボリュームのタイプが「RW」に変更されていることを確認します。

::> volume show

2. SnapMirror関係の逆再同期

SnapMirror関係の解除も完了したので、本章では「SnapMirror関係の逆再同期」を実施していきます。
「逆再同期」という名前の通り、通常とは逆方向で同期をかける作業になります。

具体的には、通常は「ソース → ターゲット」で同期をかけているものを、「ターゲット → ソース」の方向で同期をかけます。
これにより、例えばソース側のデータが利用できなくなってしまったような場合に、ターゲット側からデータをリストアすることが可能です。

ただし、逆再同期を実施するとソース側のデータは上書きされて利用できなくなってしまうので注意が必要です。

作業内容1(クラスタB側)

まずは、GUI画面から以下の手順で「逆再同期」を実施していきます。

①左ペインにて「保護 -> 関係」をクリック
②右ペインにて対象SnapMirror関係を右クリック
③右ペインにて「操作 -> 逆再同期」をクリック

逆再同期ウィザードにて、以下を実施して「逆再同期」を開始します。

①表示されている「逆再同期前 / 逆再同期後」の情報が正しいことを確認
②「関係を逆再同期する」にチェック
③「逆再同期」をクリック

逆再同期が実行され、画面から対象のSnapMirror関係情報が表示されなくなったことを確認します。

作業内容2(クラスタA側)

逆再同期を実施したことでクラスタA側がターゲットボリュームになりました。
これに伴い、クラスタA側でSnapMirror関係を確認できる状態となっています。

以下のコマンドを実行し、SnapMirror関係が表示されることを確認します。

::> snapmirror show

この時点では、Mirror Stateが「SnapMirrored」であることを確認します。
また、Source PathおよびDestination Pathが通常時と逆であることが確認できるかと思います。

本章の最後に、対象ターゲットボリュームのタイプが「DP」になっていることを確認します。

::> volume show

3. SnapMirror関係の解除

本章では、改めて「SnapMirror関係の解除」を実施していきます。
「またやるの?」と思われる方もいらっしゃるかもしれませんが、"また"やっていきます。

その理由は、現在ターゲットボリュームとなっているクラスタA側のボリュームは、最終的にはソースボリュームにしなければなりません。
そのためには、ボリュームタイプは「DP」ではなく「RW」でなければならないので「SnapMirror関係の解除」が必要になってくるというわけです。

作業内容(クラスタA側)

まずは、以下のコマンドで現在のSnapMirror関係を確認します。

::> snapmirror show

前章で「逆再同期」を実施していますので、Mirror Stateが「Snapmirrored」になっていることが確認できればOKです。

続いて、SnapMirror関係の解除をしていきます。

::> snapmirror break -source-path ソースSVM名:ソースボリューム名 -destination-path ターゲットSVM名:ターゲットボリューム名
[入力例]

::> snapmirror break -source-path dstSVM:dstVOL -destination-path srcSVM:srcVOL

コマンド構成は同じですが、1回目の時とは「ソース / ターゲット」が逆になっている点に注意しましょう。

改めてSnapMirror関係の確認をします。

::> snapmirror show

1回目と同様に、Mirror Stateが「Broken-off」になっていることが確認できるかと思います。

本章の最後に、対象ターゲットボリュームのタイプが「RW」になっていることを確認します。

::> volume show

これでクラスタA側のボリュームが次の章で実施する「新規SnapMirror関係の作成」でソースボリュームとして利用できる状態になりました。

4. 新規SnapMirror関係の作成

本章では、上記で触れてきたSnapMirror関係(以降、「旧SnapMirror関係」と呼称)とは別に、新しいSnapMirror関係を作成していきます。
一時的に同一ボリューム間でSnapMirror関係が混在する状態になりますが、特に問題はありません。

作業内容1(クラスタA側)

まずは、以下のコマンドで現在のSnapMirror関係を確認します。

::> snapmirror show

前章で「SnapMirror関係の解除」を実施していますので、 Mirror Stateが「Broken-off」になっていることが確認できればOKです。

次に、現在こちら側がソースとなっているSnapMirror情報を確認します。

::> snapmirror list-destinations
[実行例]

::> snapmirror list-destinations
This table is currently empty.

現在のソースボリュームはクラスタB側であり、クラスタA側からは同期していない状態なので「何も表示されない」が正しい結果です。

作業内容2(クラスタB側)

まずは、現在のSnapMirror関係を確認します。

::> snapmirror show

ややこしいのですが、基本的に本コマンドはターゲットボリュームを保持しいてるクラスタ側で実行することでSnapMirror関係が表示されるものと思っています。
そのため、現在ソース側であるクラスタBにおいては本コマンドでは「何も表示されない」が正しい結果となります。

次に、現在こちら側がソースとなっているSnapMirror情報を確認します。

::> snapmirror list-destinations

旧SnapMirror関係では、現在「解除済み」の状態ですが、「ソース / ターゲット」の関係性でいえば「ソース」の状態です。
そのため、本コマンドにより情報が表示されます。

続いて、旧SnapMirror関係とは別の新しいSnapMirror関係を作成していきます。

::> snapmirror create -source-path ソースSVM名:ソースボリューム名 -destination-path ターゲットSVM名:ターゲットボリューム名 -policy SnapMirrorポリシー名 -schedule SnapMirrorスケジュール名
[入力例]

::> snapmirror create -source-path srcSVM:srcVOL -destination-path dstSVM:dstVOL -policy MirrorAllSnapshots -schedule daily

改めてSnapMirror関係を確認してみます。

::> snapmirror show

先ほどは何も表示されませんでしたが、今回は新しく作成したSnapMirror関係が表示されます。
なぜなら、新しく作成したSnapMirror関係ではこちら側が「ターゲット」になっているからです。

なお、この時点ではMirror Stateは「Broken-off」の状態となっています。
ただし、次の作業で「Snapmirrored」になるので、現時点ではこれで問題ありません。

5. 新規SnapMirror関係の再同期

本章では、新規SnapMirror関係での「新規SnapMirror関係の再同期」を実施します。
先ほど実施した「逆再同期」とは異なり、通常の方向での同期、つまり「ソース → ターゲット」での同期となります。
新規SnapMirror関係でのソース/ターゲット関係は以下の状態ですので、クラスタAからクラスタBに対して同期を実施する形になります。

新規SnapMirror関係でのボリューム情報

ソースボリューム  :クラスタA側
ターゲットボリューム:クラスタB側

これにより、先ほどまでは「Broken-off」だった新規SnapMirror関係が「Snapmirrored」になります。

なお、本作業は冒頭で「エラーが出て失敗した」とご紹介した「オンサイト(ONTAP9.8)からオフサイト(ONTAP9.3)への逆再同期」と同等の作業となっています。

作業内容(クラスタB側)

まずは、GUI画面から以下の手順で「再同期」を実施していきます。

①左ペインにて「保護 -> 関係」をクリック
②右ペインにて対象SnapMirror関係を右クリック
③右ペインにて「操作 -> 再同期」をクリック

再同期ウィザードにて、以下の手順で「再同期」を開始します。

①表示される「ソース / デスティネーション」の情報が正しいことを確認
②「デスティネーションボリュームの新しいデータを削除する」にチェック
③「再同期」をクリック

以下の手順で再同期が完了したことを確認します。

確認事項

・「関係の状態」が「SnapMirror済み」になっていること
・「転送ステータス」が「アイドル」になっていること

本章の最後に、対象ターゲットボリュームのタイプが「DP」になっていることを確認します。

::> volume show

6. 旧SnapMirror関係の解放

それでは、いよいよ仕上げの作業に入っていきます。
最終的には新規SnapMirror関係のみを残して、旧SnapMirror関係は削除された状態となります。
本章では「旧SnapMirror関係の削除」の前段階として「解放」を実施していきます。

解放作業は旧SnapMirror関係での現在のソース側、すなわちクラスタB側で実施します。
これによりクラスタB側から旧SnapMirror関係の紐付けが文字通り「解放」されることになります。

作業内容1(クラスタA側)

「クラスタB側で解放作業をする」と言いましたが、まずはクラスタA側でやることがあります。
それは「Relationship IDの確認」です。
解放および削除をする際に、作業対象外のSnapMirror関係を誤って解放/削除してしまっては大変です。
そうならないためにもRelationship IDを確認することによって対象SnapMirror関係を特定しての作業が可能となり、より安全に進めることができます。

まずは、以下のコマンドで現在のSnapMirror関係を確認します。

::> snapmirror show

旧SnapMirror関係は現在「解除」の状態なので、「Broken-off」と表示されることを確認します。

続いて、以下のコマンドで旧SnapMirror関係のRelationship IDを確認します。

::> snapmirror show -destination-path ターゲットSVM名:ターゲットボリューム名 -fields relationship-id
[入力例]

::> snapmirror show -destination-path srcSVM:srcVOL -fields relationship-id

改めてですが、旧SnapMirror関係では一度逆再同期を実施しているので、ソース/ターゲットが入れ替わっています。
よって、ここで指定するターゲットSVM名およびターゲットボリューム名はクラスタAの情報となります。

[出力例]

source-path         destination-path      relationship-id
------------------- --------------------- -------------------------------
dstSVM:dstVOL       srcSVM:srcVOL         aaaa-bbbb-cccc-dddd-eeee     

作業内容2(クラスタB側)

こちらでも一度SnapMirror関係を確認しておきます。

::> snapmirror show

旧SnapMirror関係においては、現在クラスタBは「ソース」の位置付けなので、本コマンドでは「何も表示されない」が正しい表示結果となります。

続いて、クラスタB側でも旧SnapMirror関係のRelationship IDを確認します。
クラスタA側で確認した方法とは異なり、今回は以下のコマンドで確認をします。

::> snapmirror list-destinations

先ほどクラスタA側で確認した「Relationship ID」と一致したIDを持つSnapMirror関係が作業対象となります。
今回の場合は「aaaa-bbbb-cccc-dddd-eeee」というRelationship IDを持つSnapMirror関係が対象ですね。

[出力例]

                                                                        Progress
Source                        Destination                 Transfer      Last          Relationship
Path                Type      Path              Status    Progress      Updated       Id
------------------  --------  ----------------  --------  ------------  ------------  -------------------------------
dstSVM:dstVOL       XDP       srcSVM:srcVOL     Idle      -             -             aaaa-bbbb-cccc-dddd-eeee

それでは、旧SnapMirror関係の解放を実施します。

::> snapmirror release -relationship-id 対象ID -destination-path ターゲットSVM名:ターゲットボリューム名
[入力例]

::> snapmirror release -relationship-id aaaa-bbbb-cccc-dddd-eeee -destination-path srcSVM:srcVOL

無事に解放が実施されて「Job succeeded: SnapMirror Release Succeeded」と表示されるのを確認できればOKです。

改めて以下のコマンドを実行し、旧SnapMirror関係でソースとして同期していた情報を確認してみます。

::> snapmirror list-destinations

先ほど「Relationship ID」を確認した時とは異なり、今回は旧SnapMirror関係の情報が表示されなくなっているかと思います。

今回の場合、旧SnapMirror関係を解放したことでクラスタBをソースとして利用するSnapMirror関係は存在しなくなったので「This table is currently empty」と表示されることになります。

最後に、もう一度現在のSnapMirror関係の情報を確認します。

::> snapmirror show

先ほどの表示結果とは特に変化はなく「何も表示されない」の状態で問題ありません。

補足事項

もし作業対象のSnapMirrorとは別のSnapMirror関係でターゲットとして利用している場合、解放前後で表示結果に変化がないことを確認しましょう。

7. 旧SnapMirror関係の削除

それでは、最後に「旧SnapMirror関係の削除」を実施していきます。
本作業を実施することで、本来実現したかった環境が整う形となります。

作業内容1(クラスタA側)

ここまで何度も実行してきましたが、削除前にSnapMirror関係を確認しておきましょう。

::> snapmirror show

以下のコマンドを実行し、削除対象である旧SnapMirror関係を削除していきます。

::> snapmirror delete -destination-path ターゲットSVM:ターゲットボリューム名
[入力例]

::> snapmirror delete -destination-path srcSVM:srcVOL

無事に削除が実施されて「Operation succeeded」と表示されるのを確認できればOKです。

改めて、現在のSnapMirror関係の情報を確認します。

::> snapmirror show

無事に削除が実施され、削除対象の旧SnapMirror関係の情報が表示されていないことが確認できればOKです。
今回のように、他にSnapMirror関係がない場合には「This table is currently empty」と表示されます。

作業内容2(クラスタB側)

クラスタB側でも現在のSnapMirror関係の情報を確認しておきます。

::> snapmirror show

以下の状態であればOKです。

確認事項

・旧SnapMirror関係の情報が表示されないこと
・新規SnapMirror関係の情報が表示されること

それでは、最後に新規SnapMirror関係のターゲットボリュームのタイプが「DP」であることを確認しておきましょう。

::> volume show

これにて、本記事で実施したかった全作業が完了となります。
お疲れ様でした!!

おわりに

いかがだったでしょうか。

2つのクラスタを行ったり来たりして、非常にややこしい内容だったかと思います。
ただ、各クラスタがソース/ターゲットのどちらに属しているかをイメージしながら作業をすることで、混乱をいくらか回避することができます。

また、作業対象を間違えないように「Relationship ID」を特定して作業するというのも大切なポイントでした。
ひとつ間違えば大切なデータが失われてしまうような作業でもあるので、できる限り丁寧に作業していきたいですね。

なかなか全く同じ環境で作業をすることはないかもしれませんが、似たような状況でお困りの方にとって本記事が何かしらのヒントになっていれば嬉しいです。

本記事を最後まで読んでいただき、ありがとうございました。
ではでは!

-NetApp
-