忘れかけのIT備忘録

今まで学んできた知識や小技、なるほど!と思ったことをメモするブログです。

Data Guardのフェイルオーバー/フェイルバック検証(その2)

今回はバックアップからのリストア/不完全リカバリで旧プライマリDBを復旧してみようと思います。

■検証環境、前提、設定情報
Data Guardのスナップショット・スタンバイ検証 - 忘れかけのIT備忘録 と同様

■検証パターン
①手動フェイルオーバー
②フェイルバック(リストア/不完全リカバリ)

■検証
①手動フェイルオーバー
プライマリDBでインスタンス障害が発生した場合を想定し、手動フェイルオーバーして現行のスタンバイDBがプライマリロールに昇格できるか検証します
インスタンス障害は本検証ではインスタンス異常停止(abort)させます
※プライマリDBが稼働していないパターン

【検証手順】
1. [現プライマリDB]RMANバックアップ
2. [現プライマリDB]インスタンス障害発生
3. [現スタンバイDB]アーカイブギャップ取得
4. [現スタンバイDB]MRP停止
5. [現スタンバイDB]手動フェイルオーバー
6. [新プライマリDB]OCRのロール、開始オプション変更
7. [新プライマリDB]DB再起動

【想定】
フェイルオーバー後、現スタンバイDB(orcldr)のロールがプライマリロールになること

【検証結果】
フェイルオーバー後、現スタンバイDB(orcldr)のロールがプライマリロールになった

【作業ログ】

1. [現プライマリDB]RMANバックアップ
現プライマリDBのデータファイルとアーカイブログのバックアップを取得します
本検証では旧プライマリDBをリストア/不完全リカバリする際、制御ファイルは現行のを使いますが、業務では制御ファイルやSPFILEもバックアップ取得することをお勧めします

RMAN> backup database plus archivelog;

backupが開始されました(開始時間: 22-11-03)
(略)
backupが完了しました(完了時間: 22-11-03)

2. [現プライマリDB]インスタンス障害発生
ABORTで疑似的にインスタンス障害を発生させます

[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行中です。
インスタンスorcl2はノードnode2で実行中です。
[oracle@node1 ~]$ srvctl stop database -db orcl -stopoption abort
[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行されていません。
インスタンスorcl2はノードnode2で実行されていません。

3. [現スタンバイDB]アーカイブギャップ取得
スタンバイDBでアーカイブログのギャップ(不足)が発生しているか確認します
ギャップが発生している場合、プライマリDBのアーカイブログをスタンバイDBにコピー・登録します

SQL> select * from v$archive_gap;

レコードが選択されませんでした。

※今回は発生していないため、スタンバイDBにコピー・登録は割愛します

4. [現スタンバイDB]MRP停止
SQL> select client_process, process, thread# ,sequence# ,status from v$managed_standby where process = 'MRP0';

CLIENT_PROCESS       PROCESS                 THREAD#  SEQUENCE# STATUS
-------------------- -------------------- ---------- ---------- --------------------
N/A                  MRP0                          1        125 APPLYING_LOG

SQL> alter database recover managed standby database cancel;

データベースが変更されました。

SQL> select client_process, process, thread# ,sequence# ,status from v$managed_standby where process = 'MRP0';

レコードが選択されませんでした。

5. [現スタンバイDB]手動フェイルオーバー
SQL> select db_unique_name, database_role from v$database;

DB_UNIQUE_NAME       DATABASE_ROLE
-------------------- ------------------------------------------------
orcldr               PHYSICAL STANDBY

SQL> alter database failover to orcldr;

データベースが変更されました。

SQL> select db_unique_name, database_role from v$database;

DB_UNIQUE_NAME       DATABASE_ROLE
-------------------- ------------------------------------------------
orcldr               PRIMARY

6. [新プライマリDB]OCRのロール、開始オプション変更
OCRに登録されている開始オプションとロールはスタンバイ時の状態のため、手動でプライマリ用に変更します

[oracle@dr-node1 ~]$ srvctl config database -db orcldr
一意のデータベース名: ORCLDR
データベース名: ORCLDR
Oracleホーム: /u01/app/oracle/product/12.1.0/dbhome_1
Oracleユーザー: oracle
spfile: +DATA/ORCLDR/PARAMETERFILE/spfileORCLDR.ora
パスワード・ファイル: +DATA/ORCLDR/PASSWORD/orapwORCLDR
ドメイン
開始オプション: mount
停止オプション: immediate
データベース・ロール: PHYSICAL_STANDBY
管理ポリシー: AUTOMATIC
サーバー・プール: 
ディスク・グループ: DATA
マウント・ポイントのパス: 
サービス: 
タイプ: RAC
開始の同時実行性: 
停止の同時実行性: 
OSDBAグループ: dba
OSOPERグループ: oper
データベース・インスタンス: orcldr1,orcldr2
構成されたノード: dr-node1,dr-node2
データベースは管理者によって管理されています
[oracle@dr-node1 ~]$ srvctl modify database -db orcldr -role PRIMARY -startoption open
[oracle@dr-node1 ~]$ srvctl config database -db orcldr
一意のデータベース名: ORCLDR
データベース名: ORCLDR
Oracleホーム: /u01/app/oracle/product/12.1.0/dbhome_1
Oracleユーザー: oracle
spfile: +DATA/ORCLDR/PARAMETERFILE/spfileORCLDR.ora
パスワード・ファイル: +DATA/ORCLDR/PASSWORD/orapwORCLDR
ドメイン
開始オプション: open
停止オプション: immediate
データベース・ロール: PRIMARY
管理ポリシー: AUTOMATIC
サーバー・プール: 
ディスク・グループ: DATA
マウント・ポイントのパス: 
サービス: 
タイプ: RAC
開始の同時実行性: 
停止の同時実行性: 
OSDBAグループ: dba
OSOPERグループ: oper
データベース・インスタンス: orcldr1,orcldr2
構成されたノード: dr-node1,dr-node2
データベースは管理者によって管理されています

7. [新プライマリDB]DB再起動
MOUNT状態のため、DB再起動します

SQL> select instance_name,status from gv$instance;

INSTANCE_NAME                                    STATUS
------------------------------------------------ ------------------------------------
orcldr1                                          MOUNTED
orcldr2                                          MOUNTED

[oracle@dr-node1 ~]$ srvctl status database -db orcldr
インスタンスorcldr1はノードdr-node1で実行中です。
インスタンスorcldr2はノードdr-node2で実行中です。
[oracle@dr-node1 ~]$ srvctl stop database -db orcldr
[oracle@dr-node1 ~]$ srvctl status database -db orcldr
インスタンスorcldr1はノードdr-node1で実行されていません。
インスタンスorcldr2はノードdr-node2で実行されていません。
[oracle@dr-node1 ~]$ srvctl start database -db orcldr
[oracle@dr-node1 ~]$ srvctl status database -db orcldr
インスタンスorcldr1はノードdr-node1で実行中です。
インスタンスorcldr2はノードdr-node2で実行中です。

SQL> select instance_name,status from gv$instance;

INSTANCE_NAME                                    STATUS
------------------------------------------------ ------------------------------------
orcldr1                                          OPEN
orcldr2                                          OPEN

 

●[新プライマリDB]SCNを進める
しばらく新プライマリDBで運用するという想定でデータ更新します

SQL> update emp set SAL = 1111 where EMPNO = 7698;

1行が更新されました。

SQL> commit;

コミットが完了しました。
SQL> update emp set SAL = 2222 where EMPNO = 7782;

1行が更新されました。

SQL> commit;

コミットが完了しました。
SQL> update emp set SAL = 3333 where EMPNO = 7839;

1行が更新されました。

SQL> commit;

コミットが完了しました。

 

②フェイルバック(リストア/不完全リカバリ)
旧プライマリDBをバックアップからリストア/不完全リカバリ後、スイッチオーバーでロールを入れ替えられるか検証します

【検証手順】
1. [新プライマリ]旧スタンバイDBが新プライマリDBに変換された時点のSCN取得
2. [旧プライマリ]リストア/不完全リカバリ
3. [旧プライマリ]インスタンス1のみMOUNTモードで起動
4. [旧プライマリ]旧プライマリDBのロールをフィジカル・スタンバイに変換
5. [旧プライマリDB]OCRのロール、開始オプション変更
6. [旧プライマリ]全インスタンスを一時的にREAD ONLYモードで起動
7. [旧プライマリ]MOUNTモードでDB再起動
8. [新プライマリ]REDO転送サービス開始
9. [新スタンバイ]MRP起動
10. スイッチオーバー手順でロールを入れ替える

【想定】
旧プライマリDBをバックアップからリストア/不完全リカバリ後、スイッチオーバーでロールを入れ替えられること
・現プライマリDB(orcldr)がスタンバイロールになること
・現スタンバイDB(orcl)がプライマリロールになること

【検証結果】
旧プライマリDBをバックアップからリストア/不完全リカバリ後、スイッチオーバーでロールを入れ替えらた
・現プライマリDB(orcldr)がスタンバイロールになった
・現スタンバイDB(orcl)がプライマリロールになった

【作業ログ】

1. [新プライマリ]旧スタンバイDBが新プライマリDBに変換された時点のSCN取得
SQL> select to_char(standby_became_primary_scn) from v$database;

TO_CHAR(STANDBY_BECAME_PRIMARY_SCN)
------------------------------------------------------------------------------------------------------------------------
5674786

2. [旧プライマリ]リストア/不完全リカバリ
フェイルオーバー検証前に取得したバックアップを使用して、データベースをリストアします
リストア完了後、不完全リカバリで「1.」で取得したSCNまでリカバリします

本検証ではインスタンス異常停止でインスタンス停止している状態なのでMOUNTモードで起動します
障害状況によっては制御ファイルをリストアしないといけないケースもあると思いますが、そのときはNOMOUNTモードで起動して制御ファイルをリストアします

[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行されていません。
インスタンスorcl2はノードnode2で実行されていません。
[oracle@node1 ~]$ srvctl start database -db orcl -startoption mount
[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行中です。
インスタンスorcl2はノードnode2で実行中です。

RMAN> run
2> {
3>   set until scn 5674787;
4>   restore database;
5>   recover database;
6>  }

実行コマンド: SET until clause

restoreが開始されました(開始時間: 22-11-03)
(略)
recoverが完了しました(完了時間: 22-11-03)
★set until scn のSCNは「STANDBY_BECAME_PRIMARY_SCN + 1」なのでご注意ください(set until scnは指定したSCNは含まれません)

3. [旧プライマリ]インスタンス1のみMOUNTモードで起動
インスタンスが起動している場合、後続の「4.」の「alter database convert to physical standby;」が失敗するため、インスタンス1のみMOUNTモードで起動します

[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行中です。
インスタンスorcl2はノードnode2で実行中です。
[oracle@node1 ~]$ srvctl stop instance -db orcl -instance orcl2
[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行中です。
インスタンスorcl2はノードnode2で実行されていません。

4. [旧プライマリ]旧プライマリDBのロールをフィジカル・スタンバイに変換
SQL> select db_unique_name, database_role, open_mode from v$database;

DB_UNIQUE_NAME       DATABASE_ROLE                                    OPEN_MODE
-------------------- ------------------------------------------------ ------------------------------------------------------------
orcl                 PRIMARY                                          MOUNTED

SQL> alter database convert to physical standby;

データベースが変更されました。

SQL> select db_unique_name, database_role, open_mode from v$database;

DB_UNIQUE_NAME       DATABASE_ROLE                                    OPEN_MODE
-------------------- ------------------------------------------------ ------------------------------------------------------------
orcl                 PHYSICAL STANDBY                                 MOUNTED

【参考】
1つのインスタンス以外が起動しているとエラー
SQL> alter database convert to physical standby;
alter database convert to physical standby;
*
行1でエラーが発生しました。:
ORA-38777: 他のインスタンスでデータベースを起動しないでください

5. [旧プライマリDB]OCRのロール、開始オプション変更
OCRに登録されている開始オプションとロールはプライマリ時の状態のため、手動でスタンバイ用に変更します

[oracle@node1 ~]$ srvctl config database -db orcl
一意のデータベース名: orcl
データベース名: orcl
Oracleホーム: /u01/app/oracle/product/12.1.0/dbhome_1
Oracleユーザー: oracle
spfile: +DATA/ORCL/PARAMETERFILE/spfileORCL.ora
パスワード・ファイル: +DATA/ORCL/PASSWORD/orapwORCL
ドメイン
開始オプション: open
停止オプション: immediate
データベース・ロール: PRIMARY
管理ポリシー: AUTOMATIC
サーバー・プール: 
ディスク・グループ: DATA
マウント・ポイントのパス: 
サービス: 
タイプ: RAC
開始の同時実行性: 
停止の同時実行性: 
OSDBAグループ: dba
OSOPERグループ: oper
データベース・インスタンス: orcl1,orcl2
構成されたノード: node1,node2
データベースは管理者によって管理されています
[oracle@node1 ~]$ srvctl modify database -db orcl -role PHYSICAL_STANDBY -startoption mount
[oracle@node1 ~]$ srvctl config database -db orcl
一意のデータベース名: orcl
データベース名: orcl
Oracleホーム: /u01/app/oracle/product/12.1.0/dbhome_1
Oracleユーザー: oracle
spfile: +DATA/ORCL/PARAMETERFILE/spfileORCL.ora
パスワード・ファイル: +DATA/ORCL/PASSWORD/orapwORCL
ドメイン
開始オプション: mount
停止オプション: immediate
データベース・ロール: PHYSICAL_STANDBY
管理ポリシー: AUTOMATIC
サーバー・プール: 
ディスク・グループ: DATA
マウント・ポイントのパス: 
サービス: 
タイプ: RAC
開始の同時実行性: 
停止の同時実行性: 
OSDBAグループ: dba
OSOPERグループ: oper
データベース・インスタンス: orcl1,orcl2
構成されたノード: node1,node2
データベースは管理者によって管理されています

6. [旧プライマリ]全インスタンスを一時的にREAD ONLYモードで起動
OPENすることでディクショナリ・チェックを使用して制御ファイルとデータベースを同期させます(整合性のチェック)
DBアラートログにエラーがなければ特に問題ありません
マニュアルでは「通常、フェイルオーバー中に古いプライマリがデータファイルを追加または削除している途中でなければ、ユーザー・アクションは必要ありません」とありますが、検証という意味で実施しました
※スタンバイDBをREAD ONLYモードでデータ同期する場合、Oracle Active Data Guardライセンスが必要になるのでご注意ください

[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行中です。
インスタンスorcl2はノードnode2で実行されていません。
[oracle@node1 ~]$ srvctl stop database -db orcl
[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行されていません。
インスタンスorcl2はノードnode2で実行されていません。
[oracle@node1 ~]$ srvctl start database -db orcl -startoption "read only"
[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行中です。
インスタンスorcl2はノードnode2で実行中です。

7. [旧プライマリ]MOUNTモードでDB再起動
[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行中です。
インスタンスorcl2はノードnode2で実行中です。
[oracle@node1 ~]$ srvctl stop database -db orcl
[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行されていません。
インスタンスorcl2はノードnode2で実行されていません。
[oracle@node1 ~]$ srvctl start database -db orcl -startoption mount
[oracle@node1 ~]$ srvctl status database -db orcl
インスタンスorcl1はノードnode1で実行中です。
インスタンスorcl2はノードnode2で実行中です。

8. [新プライマリ]REDO転送サービス開始
SQL> select inst_id, name, value from gv$parameter where name = 'log_archive_dest_3';

INST_ID NAME                           VALUE
------- ------------------------------ --------------------------------------------------
      1 log_archive_dest_3             service=ORCL ASYNC NOAFFIRM delay=0 OPTIONAL compr
                                       ession=DISABLE max_failure=0 max_connections=1 reo
                                       pen=300 db_unique_name=ORCL net_timeout=30 valid_f
                                       or=(ONLINE_LOGFILE,PRIMARY_ROLE)

      2 log_archive_dest_3             service=ORCL ASYNC NOAFFIRM delay=0 OPTIONAL compr
                                       ession=DISABLE max_failure=0 max_connections=1 reo
                                       pen=300 db_unique_name=ORCL net_timeout=30 valid_f
                                       or=(ONLINE_LOGFILE,PRIMARY_ROLE)

SQL> select inst_id, name, value from gv$parameter where name = 'log_archive_dest_state_3';

INST_ID NAME                           VALUE
------- ------------------------------ --------------------------------------------------
      1 log_archive_dest_state_3       ENABLE
      2 log_archive_dest_state_3       ENABLE

★必要に応じて下記コマンドで有効化します
alter system set log_archive_dest_state_n = enable;

9. [新スタンバイ]MRP起動
SQL> select client_process,process,thread#,sequence#,status from v$managed_standby where process = 'MRP0';

レコードが選択されませんでした。

SQL> alter database recover managed standby database disconnect;

データベースが変更されました。

SQL> select client_process,process,thread#,sequence#,status from v$managed_standby where process = 'MRP0';

CLIENT_PROCESS       PROCESS                 THREAD#  SEQUENCE# STATUS
-------------------- -------------------- ---------- ---------- --------------------
N/A                  MRP0                          1          3 APPLYING_LOG

10. スイッチオーバー手順でロールを入れ替える
スイッチオーバーでロールを入れ替えて障害発生前の状態に戻します
スイッチオーバー手順につきましてはData Guardのスイッチオーバー/スイッチバック検証 - 忘れかけのIT備忘録をご参照ください

 

■参考資料
ロールの推移

Oracle Data Guardの使用例