忘れかけのIT備忘録

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

Data Guardのスナップショット・スタンバイ検証

Data Guardのスナップショット・スタンバイについて、机上の知識はあるものの、実務経験が無いため、実際の動きを検証しました。

スナップショット・スタンバイ(スナップショット・スタンバイ・データベース)は一時的にプライマリDBと同期解除された更新可能なスタンバイDBです。
フィジカル・スタンバイ(フィジカル・スタンバイ・データベース)の場合、スタンバイDBはMOUNTモードのため、問い合わせや更新はできません。(Oracle Active Data Guardライセンスを購入すればスタンバイDBもリアルタイム問合せできますが、本検証では対象外です)

フィジカル・スタンバイと同様、プライマリDBからREDOデータを受信・アーカイブしますが、適用はしません。(プライマリDBとスタンバイDBで同期されなくなるため差分が出ますが、REDOデータを受信・アーカイブするためプライマリDBのデータ保護は可能になっています)
スナップショット・スタンバイはプライマリDBからスタンバイDBを切り離してスタンバイDBに対して更新することができるため、主に本番同等のデータでテスト目的で使用されることが多いようです。
スナップショット・スタンバイがフィジカル・スタンバイに戻るタイミングでスナップショット・スタンバイの更新が破棄され、プライマリDBから受信したREDOデータが適用されます。(スナップショット・スタンバイへ変換される直前の状態に戻ります)

スナップショット・スタンバイの変換にはいくつか制約があります。(ドキュメントID 1740162.1)
・フィジカル・スタンバイ・データベースであること
・プライマリDB、スタンバイDBともに高速リカバリ領域(DB_RECOVER_FILE_DEST、DB_RECOVER_FILE_DEST_SIZE)が設定されていること
・スタンバイDBのlog_archive_dest_nパラメータでvalid_forを指定している場合、下記の組み合わせのいずれかが含まれていること
 - online_logfile, standby_role
 - all_logfile, standby_role
 - all_logfile, all_roles
※想定ですが、スタンバイDB(スタンバイ・ロール)がトランザクションの更新情報(オンラインREDOログデータ)を出力するための設定が必要なのだと思います

■検証環境

NSA (Network Server Async)
プライマリDBのREDOデータを非同期でスタンバイDBのRFSプロセスへ転送するプロセス
転送後、RFSプロセスからの応答は待たない
NSAプロセスに対してNSSプロセスというスタンバイDBと同期を取りながらREDO転送するプロセスもありますが、詳細は後日検証予定の保護モードで解説しようと思います

RFS (Remote File Server)
プライマリDBから転送されてきたREDOデータを受信後、スタンバイREDOログファイルに書き込むプロセス

MRP (Management Recovery Process)
管理リカバリプロセス
スタンバイ・REDOログファイルやアーカイブログのREDOデータをデータファイルに適用するプロセス
RACの場合、いずれかのノードに存在します

【補足】
通常、REDOデータを受信・適用する場合、スタンバイDBにスタンバイ・REDOログファイルがあれば十分ですが、スナップショット・スタンバイの場合、更新情報をオンライン・REDOログファイルに書き込むため、オンライン・REDOログが必要です
スイッチオーバーやフェイルオーバーしたときもオンライン・REDOログファイルが必要です

■前提
・プライマリDB・スタンバイDBともに2ノードRAC(管理者管理型DB)
・スタンバイDBはフィジカル・スタンバイ
・保護モードは最大パフォーマンスモード
・Data Guard Broker構成なし

■設定情報

プライマリDB
SQL> --ロール
SQL> select db_unique_name, database_role from v$database;

DB_UNIQUE_NAME       DATABASE_ROLE
-------------------- ------------------------------------------------
orcl                 PRIMARY

SQL> --適用モード(リアルタイム適用)
SQL> select dest_name, recovery_mode from v$archive_dest_status where type = 'PHYSICAL';

DEST_NAME                      RECOVERY_MODE
------------------------------ ------------------------------
LOG_ARCHIVE_DEST_3             MANAGED REAL TIME APPLY

SQL> --スイッチオーバー可否
SQL> select switchover_status from v$database;

SWITCHOVER_STATUS
------------------------------------------------------------
TO STANDBY

SQL> --保護モード
SQL> select protection_mode, protection_level from v$database;

PROTECTION_MODE                PROTECTION_LEVEL
------------------------------ ------------------------------
MAXIMUM PERFORMANCE            MAXIMUM PERFORMANCE

スタンバイDB
SQL> --ロール
SQL> select db_unique_name, database_role from v$database;

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

SQL> --管理リカバリモード
SQL> select client_process, process, thread#, sequence#, status from v$managed_standby where process like 'MRP%';

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

SQL> --スタンバイ・REDOログファイル
SQL> select group#, thread#, sequence#, archived, status from v$standby_log order by group#, thread#;

GROUP#     THREAD#    SEQUENCE#  ARCHIVED  STATUS
---------- ---------- ---------- --------- --------------------
 5         1           0         NO        UNASSIGNED
 6         1           0         NO        UNASSIGNED
 7         1          56         YES       ACTIVE
 8         2           0         NO        UNASSIGNED
 9         2           0         NO        UNASSIGNED
10         2          47         YES       ACTIVE

 

■検証パターン
①スナップショット・スタンバイへ変換(切り離し)
②プライマリDB、スタンバイDBでそれぞれデータ更新
③フィジカル・スタンバイへ変換(切り戻し)

■検証
①スナップショット・スタンバイへ変換(切り離し)
フィジカル・スタンバイからスナップショット・スタンバイへ変換できるか検証します

【検証手順】
1. [スタンバイDB]MRP停止
2. [スタンバイDB]起動モード確認
3. [スタンバイDB]高速リカバリ領域確認
4. [スタンバイDB]スナップショット・スタンバイへ変換
5. [スタンバイDB]スタンバイDBを読み書きモードでオープン

【想定】
フィジカル・スタンバイからスナップショット・スタンバイへ変換できること

【検証結果】
フィジカル・スタンバイからスナップショット・スタンバイへ変換できた

【作業ログ】

1. [スタンバイ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          56         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';

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

2. [スタンバイDB]起動モード確認
SQL> select instance_name, status from gv$instance;

INSTANCE_NAME                  STATUS
------------------------------ --------------------
orcldr1                        MOUNTED
orcldr2                        MOUNTED
★MOUNTモードになっていればOK

3. [スタンバイDB]高速リカバリ領域確認
内部でフラッシュバック・データベースを使いますが、明示的にフラッシュバック・ログを設定する必要はありません

SQL> select INST_ID,NAME,VALUE from gv$parameter where name='db_recovery_file_dest' order by INST_ID;

INST_ID NAME                                     VALUE
------- ---------------------------------------- --------------------------------------------------
      1 db_recovery_file_dest                    +FRA
      2 db_recovery_file_dest                    +FRA

SQL> select INST_ID,NAME,VALUE from gv$parameter where name='db_recovery_file_dest_size' order by INST_ID;

INST_ID NAME                                     VALUE
------- ---------------------------------------- --------------------------------------------------
      1 db_recovery_file_dest_size               5017436160
      2 db_recovery_file_dest_size               5017436160

4. [スタンバイDB]スナップショット・スタンバイへ変換
SQL> select DATABASE_ROLE from v$database;

DATABASE_ROLE
------------------------------------------------
PHYSICAL STANDBY

SQL> alter database convert to snapshot standby;

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

SQL> select DATABASE_ROLE from v$database;

DATABASE_ROLE
------------------------------------------------
SNAPSHOT STANDBY

5. [スタンバイDB]スタンバイDBを読み書きモードでオープン
SQL> select instance_name, status from gv$instance;

INSTANCE_NAME                  STATUS
------------------------------ --------------------
orcldr1                        MOUNTED
orcldr2                        MOUNTED
★MOUNTモードのままのため、DB再起動

[oracle@dr-node1 ~]$ srvctl status database -db orcldr
srvctl stop 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 -startoption "read write"
[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
★OPENモード(更新可能状態)になった

 

②プライマリDB、スタンバイDBでそれぞれデータ更新
プライマリDB、スタンバイDBでそれぞれデータを更新して下記を検証します
・プライマリDBへの更新がスタンバイDBへ反映されていないこと
・スタンバイDBへの更新がプライマリDBへ反映されていないこと

【検証手順】
1. [プライマリDB]データ更新
2. [スタンバイDB]プライマリDBの更新データ確認
3. [スタンバイDB]データ更新
4. [プライマリDB]スタンバイDBの更新データ確認

【想定】
・プライマリDBへの更新がスタンバイDBへ反映されていないこと
・スタンバイDBへの更新がプライマリDBへ反映されていないこと

【検証結果】
・プライマリDBへの更新がスタンバイDBへ反映されていなかった
・スタンバイDBへの更新がプライマリDBへ反映されていなかった

【作業ログ】

1. [プライマリDB]データ更新
SQL> select * from emp where EMPNO in(7369, 7499);

     EMPNO ENAME      JOB               MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
      7369 SMITH      CLERK            7902 80-12-17        800                    20
      7499 ALLEN      SALESMAN         7698 81-02-20       1600        300         30

SQL> update emp set SAL = 9999 where EMPNO = 7369;

1行が更新されました。

SQL> commit;

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

SQL> select * from emp where EMPNO in(7369, 7499);

     EMPNO ENAME      JOB               MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
      7369 SMITH      CLERK            7902 80-12-17       9999                    20
      7499 ALLEN      SALESMAN         7698 81-02-20       1600        300         30

2. [スタンバイDB]プライマリDBの更新データ確認
SQL> select * from emp where EMPNO in(7369, 7499);

     EMPNO ENAME      JOB               MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
      7369 SMITH      CLERK            7902 80-12-17        800                    20
      7499 ALLEN      SALESMAN         7698 81-02-20       1600        300         30
★スタンバイDBのEMPNO7369のSALは更新されていなかった

3. [スタンバイDB]データ更新
SQL> select * from emp where EMPNO in(7369, 7499);

     EMPNO ENAME      JOB               MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
      7369 SMITH      CLERK            7902 80-12-17        800                    20
      7499 ALLEN      SALESMAN         7698 81-02-20       1600        300         30

SQL> update emp set SAL = 9999 where EMPNO = 7499;

1行が更新されました。

SQL> commit;

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

SQL> select * from emp where EMPNO in(7369, 7499);

     EMPNO ENAME      JOB               MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
      7369 SMITH      CLERK            7902 80-12-17        800                    20
      7499 ALLEN      SALESMAN         7698 81-02-20       9999        300         30

4. [プライマリDB]スタンバイDBの更新データ確認
SQL> select * from emp where EMPNO in(7369, 7499);

     EMPNO ENAME      JOB               MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
      7369 SMITH      CLERK            7902 80-12-17       9999                    20
      7499 ALLEN      SALESMAN         7698 81-02-20       1600        300         30
★プライマリDBのEMPNO7499のSALは更新されていなかった

 

③フィジカル・スタンバイへ変換(切り戻し)
スナップショット・スタンバイからフィジカル・スタンバイへ変換できるか検証します

【検証手順】
1. [スタンバイDB]DB停止
2. [スタンバイDB]インスタンス1をMOUNTモード起動
3. [スタンバイDB]起動モード確認
4. [スタンバイDB]フィジカル・スタンバイへ変換
5. [スタンバイDB]DB再起動
6. [スタンバイDB]MRP起動

【想定】
スナップショット・スタンバイからフィジカル・スタンバイへ変換できること

【検証結果】
スナップショット・スタンバイからフィジカル・スタンバイへ変換できた

【作業ログ】

1. [スタンバイDB]DB停止
[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で実行されていません。

2. [スタンバイDB]インスタンス1をMOUNTモード起動
RACの場合、1つのインスタンス以外はすべて停止した状態にします

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

3. [スタンバイDB]起動モード確認
SQL> select instance_name, status from gv$instance;

INSTANCE_NAME                                    STATUS
------------------------------------------------ ------------------------------------
orcldr1                                          MOUNTED
★MOUNTモードになっていればOK

4. [スタンバイDB]フィジカル・スタンバイへ変換
SQL> select DATABASE_ROLE from v$database;

DATABASE_ROLE
------------------------------------------------
SNAPSHOT STANDBY

sql> alter database convert to physical standby;

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

SQL> select DATABASE_ROLE from v$database;

DATABASE_ROLE
------------------------------------------------
PHYSICAL STANDBY

5. [スタンバイDB]DB再起動
[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
------------------------------------------------ ------------------------------------
orcldr2                                          MOUNTED
orcldr1                                          MOUNTED

6. [スタンバイDB]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                          2         53 APPLYING_LOG
REDO適用モードに戻った

 

■参考文献
フィジカルおよびスナップショット・スタンバイ・データベースの管理

■おわりに
ログは割愛しますが、スナップショット・スタンバイ変換中もスタンバイDBのv$archived_logにはプライマリDBから受信したアーカイブログが登録され、APPLIEDはNOのままであることも確認できました。