Oracle Database の Data Guard を使ったレプリケーションを調べたので、その時のメモです。

環境

Oracle は Rocky Linux への Oracle Database インストール方法 に記載された方法でインストールされている前提です。

※説明を単純にするため Non-CDB 構成でインストールした Oracle Database を使用しています。

Oracle Database のレプリケーション概要

“レプリケーション” とは、あるデータベースに行われた更新を別のデータベースサーバーへリアルタイムで適用する機能です。Oracle では、データ更新が行われるサーバーを Primary と呼び、Primary から更新データを受け取り適用するサーバーを Standby と呼びます。データがリアルタイムで複製されることで、Primary サーバーが障害等で停止した場合も、Standby データベースを使ってシステムを停止することなく運用することができます。

Oracle Database のレプリケーションは色々な方法があり、例えば自前のスクリプト等でアーカイブログをリモートデータベースにコピーしてリカバリする、と全て自前で実装することも可能ではあります。ただ現在は Data Guard という機能を使ってレプリケーションを行うのが一般的なため、この記事でも Data Guard を使った方法を紹介します。なお Data Guard の使用には Enterprise Edition ライセンスが必要です。

Data Guard を使ったレプリケーションは Active – Cold Standby 構成となります。Primary データベースではデータの読み込み/書き込みが常に可能ですが、Standby データベースでは読み込み/書き込みはできません。

Data Guard を元にした Active Data Guard という機能を使うと、Standby データベースで読み込み (SELECT クエリの実行) が可能となり、Read Replica として使うことができます。ただし Active Data Guard は追加ライセンスの購入が必要となり、この記事では扱いません。

Primary が何らかの障害で停止してしまった場合、Standby を Primary に昇格します。昇格するとそのデータベースでは読み込み/書き込みが可能となり、新しい Primary として動作します。初めに Primary だったサーバーの障害が復旧したら、新しい Standby としてレプリケーションに再度参加できます。そのため初めに Primary とするサーバーでも、Standby 用の設定を初めに行っておくのがベストプラクティスとなります。

レプリケーションの種類

Data Guard では “論理レプリケーション” と “物理レプリケーション” を選択できます。通常は物理レプリケーションが使われ、この記事でも物理レプリケーションの手順を紹介します。

論理レプリケーションは、実行された SQL を Standby に適用する方法です。そのためデータファイルの物理的な構成/構造は Primary と Standby で異なる可能性があります。

物理レプリケーションはアーカイブログファイルをそのまま Standby に適用する方法で、データファイルのブロック単位で Primary のデータが複製されます。

REDO 転送サービス

Data Guard では、Primary が Standby へ REDO ログを送信し、Standby が受け取った REDO ログを適用してデータを復元します。Primary サーバー上で、REDO ログの送信を行うコンポーネントを REDO 転送サービスと呼びます。REDO 転送サービスの設定は LOG_ARCHIVE_DEST_n パラメータに転送先の Standby の情報を指定することで行います ("n" には 1~10 までの数字が入ります)。転送モードには 同期モード非同期モードがあります。

REDO 適用サービス – REDO Apply

Standby サーバーで、受け取った REDO ログをデータベースを適用するサービスを REDO 適用サービスまたは REDO Apply と呼びます。(ちなみに、論理レプリケーションでは SQL 文が適用されるため、SQL 適用サービス (SQL Apply) という名前になりますが、この記事では扱いません)

物理レプリケーションでは、REDO Apply が REDO ログを受け取ったらリアルタイムで即時に REDO ログがデータベースに適用されます。論理レプリケーションでは、オプションを指定しない限り 受信した REDO ログがスタンバイログファイルにアーカイブされるまで変更は適用されません。

FAL (Fetch Archive Log)

先に “Primary が Standby にログファイルを送信する” と書きましたが、一時的なネットワークの問題等でログファイルの送信に失敗することはありえます。非同期モードだとログファイルの送信が完了する前にトランザクションはコミットされていますので、この場合 Standby はログファイルを受け取れていない状態になります。

その後ネットワークの問題が解消して Standby が新しいログファイルを受信した時、新しいログファイルが前回受信したログファイルの続きでは無く、いくつかのログが抜けていることを検知します。そして前回受信したログファイルから、今回受信したログファイルまでの間の REDO ログを Primary へ問い合わせて取得します。

この Standby から Primary へ足りない REDO ログを問い合わせるプロセスを “Fetch Archive Log (FAL)” と呼び、レプリケーションの構成時に FAL の問い合わせ先サーバーを指定します。

Primary から Standby へのリモートアクセス

先に記載した通り、Data Guard では Primary が Standby に対して REDO ログを送信します (MySQL や PostgreSQL では Oracle と異なり、レプリカがマスターに対してトランザクションログを要求します)。

Primary が Standby にアクセスする際、デフォルトでは SYS ユーザーが使われます。REDO_TRANSPORT_USER パラメータを設定することで別のユーザーを使用することもできますが、指定するユーザーは SYSDBA または SYSOPER 権限を持っている必要があります。

Oracle Database 接続時の認証方法には、大きく “OS 認証” と “パスワード認証” の2つがあります。

OS 認証” は OS に登録されているユーザー (Linux であれば useradd コマンドで作成されたユーザー) を使って追加の認証無く Oracle に接続できるというもので、例えば oracle ユーザーで sqlplus を使って以下のように接続する場合、OS 認証が使われています (sqlplus のパラメータでユーザー名、パスワードが空になっています)。

$ sudo su oracle
$ sqlplus / as sysdba

OS 認証はローカル接続にしか使えないため、リモート接続にはパスワード認証を使う必要があります。ローカル接続/リモート接続に関わらず、SYSDBA または SYSOPER 権限のユーザーでパスワード認証を行う場合、”パスワードファイル“というものが必要になります。

パスワードファイルには SYSDBA および SYSOPER 権限を持つユーザーの認証情報が保存されています。Oracle インストール時にデフォルトで作成されており、初期状態では SYS ユーザーのみ登録されています。ユーザーに SYSDBA または SYSOPER 権限を付与する度に、新しいユーザーがパスワードファイルに追加され、逆にユーザーからこれらの権限を剥奪するとパスワードファイルからも削除されます。

SYS ユーザーを使い、パスワード認証でリモートデータベースにアクセスする場合、その SYS ユーザーが登録されているパスワードファイルをリモートデータベースに配置しておく必要があります。今回説明する手順で、Primary のパスワードファイルを Standby にコピーしているのはこのような理由からです。

データベースの名前について

Oracle ではデータベースを識別するための 名前/ID が複数あります。Data Guard で使われる名前について、以下に概要を記載します。

Data Guard レプリケーション設定手順

今回 Primary ではデフォルトの DB_NAME を使うこととし、以下の名前を想定します。Standby の DB_UNIQUE_NAME を変更するため、それに合わせて SERVICE_NAME も変更されます。

TypeIP AddressSIDDB_NAMEDB_UNIQUE_NAMESERVICE_NAME
Primary172.16.11.8ORCLCDBORCLCDBORCLCDBORCLCDB
Standby172.16.11.9ORCLCDBORCLCDBORCLCDBREPLORCLCDBREPL

1). Primary の設定手順

1-1). 事前準備

まず Primary サーバーに OS をインストールして、Oracle Database をインストールします。インストール方法は Rocky Linux への Oracle Database インストール方法 を参照してください。

次にレプリケーションに必要な設定をします。レプリケーションでは Archive Log が使用されるため、Primary で Archive Log が有効になっている必要があります。また、同時に FORCE LOGGING も有効にします。これを設定することで、デフォルトでは REDO ログに書かれない操作も REDO ログに記録されるようになり、全ての操作が Standby へ適用することができるようになります。

Primary サーバー

$ sudo su oracle
$ sqlplus / as sysdba
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> ALTER DATABASE ARCHIVELOG;
SQL> ALTER DATABASE FORCE LOGGING;
SQL> ALTER DATABASE OPEN;

テスト用のテーブルも作成しておきます。

Primary サーバー

SQL> CREATE USER vagrant IDENTIFIED BY vagrant DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP;
SQL> GRANT ALL PRIVILEGES TO vagrant;
SQL> CREATE TABLE vagrant.test1 (id NUMBER, value NVARCHAR2(255));
SQL> INSERT INTO vagrant.test1 (id, value) SELECT level, CONCAT('value ', level) FROM dual CONNECT BY level <= 10;
10 rows created.

SQL> commit;
Commit complete.

SQL> exit
$ exit  # exit from oracle user

また、Standby データベースを構築する際に Primary データベースのバックアップが必要になります。そのため先にバックアップファイルの保存先フォルダを作成しておきます。

Primary サーバー

$ sudo mkdir /backup
$ sudo chown oracle:oinstall /backup
$ sudo chmod 775 /backup

1-2). Primary から Standby への接続設定

リモート接続する時、クライアント側で接続設定に名前を付けて管理することができます。この接続設定に付けられた名前を “ネットサービス名” と呼び、Primary / Standby 間の接続設定で使用します。

そのため先に Primary サーバー上で、Standby サーバーへの接続設定を記述しておきます。接続設定は tnsnames.ora というファイルに記述され、ファイルの場所は $ORACLE_HOME/network/admin/tnsnames.ora となります。

Primary サーバー

$ sudo su oracle
$ vim /opt/oracle/product/19c/dbhome_1/network/admin/tnsnames.ora
---
# 以下を追記
ORCLCDBREPL=
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCP)(HOST=172.16.11.9)(PORT=1521))
    (CONNECT_DATA=
      (SERVER=DEDICATED)
      (SERVICE_NAME=ORCLCDBREPL)  # <-- Standby の SERVICE_NAME を指定
    )
  )
---

今回は Standby の DB_UNIQUE_NAME に合わせて ネットサービス名を “ORCLCDBREPL” としました。”ADDRESS” の部分で Standby の IP アドレスを、”SERVICE_NAME” の部分で Standby の SERVICE_NAME を指定しています。

1-3). パスワードファイルのバックアップ

先に説明したように、Primary から Standby への接続のため、Primary のパスワードファイルを Standby にコピーしておく必要があります。後で Primary のバックアップを Standby にコピーして復元するため、先にパスワードファイルもバックアップフォルダにコピーしておきます。

パスワードファイルのある場所は $ORACLE_HOME/dbs/orapwORCLCDB です。

Primary サーバー

# パスワードファイルをバックアップ先フォルダにコピー
$ cp /opt/oracle/product/19c/dbhome_1/dbs/orapwORCLCDB /backup/

1-4). Standby REDO ログの設定

上記にも記載しましたが、Primary サーバーも一度障害が発生した後は Standby になる可能性があるため、初めに Standby 用の設定をしておくのがベストプラクティスです。

Standby では Standby 用の REDO ログが使われるため、Standby REDO ログファイルを作成しておく必要があります。Standby REDO ログファイルは、各 REDO ログスレッド毎に 通常の REDO ログ + 1 個を作成します。

※ RAC 環境では複数の REDO ログスレッドがあることがありますが、スタンドアロン環境ではデフォルトでは 1つの REDO ログスレッドしかありません。

スレッド毎の REDO ログファイルの数は V$LOG を使って確認することができます。

Primary サーバー

$ sqlplus / as sysdba

# REDO スレッドとグループ数、サイズを確認
SQL> SELECT THREAD#, GROUP#, MEMBERS, BYTES FROM V$LOG;
   THREAD#     GROUP#	   BYTES
---------- ---------- ----------
	 1	    1  209715200   # <-- 200MB
	 1	    2  209715200
	 1	    3  209715200

# 各グループの REDO ログファイルの数を確認
SQL> SELECT GROUP#, MEMBER, STATUS FROM V$LOGFILE;
 GROUP#                                  MEMBER  STATUS
------- --------------------------------------- -------
      3  /opt/oracle/oradata/ORCLCDB/redo03.log           
      2  /opt/oracle/oradata/ORCLCDB/redo02.log
      1  /opt/oracle/oradata/ORCLCDB/redo01.log


# Standby REDO ログファイルを作成
# 今回 3 つの REDO ログファイルがあるため、+1 して 4 個の Standby REDO ログファイルを作成する
SQL> ALTER DATABASE ADD STANDBY LOGFILE ('/opt/oracle/oradata/ORCLCDB/redo04.log') SIZE 200M;
SQL> ALTER DATABASE ADD STANDBY LOGFILE ('/opt/oracle/oradata/ORCLCDB/redo05.log') SIZE 200M;
SQL> ALTER DATABASE ADD STANDBY LOGFILE ('/opt/oracle/oradata/ORCLCDB/redo06.log') SIZE 200M;
SQL> ALTER DATABASE ADD STANDBY LOGFILE ('/opt/oracle/oradata/ORCLCDB/redo07.log') SIZE 200M;

# 作成した Standby REDO ログファイルを確認
SQL> SELECT GROUP#, BYTES FROM V$STANDBY_LOG;
    GROUP#	BYTES
---------- ----------
	 4  209715200
	 5  209715200
	 6  209715200
	 7  209715200

1-5). デフォルトのアーカイブログ出力先の確認

Oracle ではアーカイブログを同時に複数の場所にコピーすることができ、レプリケーション設定ではそのコピー先の 1つに Standby サーバーを指定することで、アーカイブログを Standby へ送信します。そのためアーカイブログの出力設定で、明示的に デフォルト (ローカル) の出力先と Standby への出力先の 2つを設定する必要があり、まずデフォルトの出力先を確認しておきます。

Primary サーバー

SQL> ARCHIVE LOG LIST;
Database log mode	       No Archive Mode
Automatic archival	       Disabled
Archive destination	       /opt/oracle/product/19c/dbhome_1/dbs/arch   
Oldest online log sequence     6
Current log sequence	       8

# または以下の方法でも確認できます
SQL> SELECT dest_id, dest_name, destination FROM V$ARCHIVE_DEST WHERE dest_id = 1;
 DEST_ID           DEST_NAME                               DESTINATION
-------- ------------------- -----------------------------------------
       1  LOG_ARCHIVE_DEST_1 /opt/oracle/product/19c/dbhome_1/dbs/arch

上記より、今回の環境では /opt/oracle/product/19c/dbhome_1/dbs/arch がアーカイブログのデフォルトの出力先となります。

1-6). 初期化パラメータの設定

それでは Primary サーバーの設定を行います。デフォルト設定のままで良いものは設定していませんが、必要な設定項目の一覧は以下を参照してください。

Primary サーバー

# いくつかの項目は Database がオープン状態では変更できないため、SCOPE=SPFILE を指定
SQL> ALTER SYSTEM SET DB_UNIQUE_NAME=ORCLCDB SCOPE=SPFILE;
SQL> ALTER SYSTEM SET LOG_ARCHIVE_CONFIG='DG_CONFIG=(ORCLCDB,ORCLCDBREPL)';
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=/opt/oracle/product/19c/dbhome_1/dbs/arch VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=ORCLCDB';
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=ORCLCDBREPL ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=ORCLCDBREPL';
SQL> ALTER SYSTEM SET FAL_SERVER=ORCLCDBREPL;
SQL> ALTER SYSTEM SET DB_FILE_NAME_CONVERT='/ORCLCDBREPL/','/ORCLCDB/' SCOPE=SPFILE;
SQL> ALTER SYSTEM SET LOG_FILE_NAME_CONVERT='/ORCLCDBREPL/','/ORCLCDB/' SCOPE=SPFILE;
SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;

# データベースを再起動して設定を反映
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP OPEN;

レプリケーションに必要な設定項目一覧:

パラメータ名説明
DB_NAME(設定不要) データベース名。デフォルトでインスタンス名 (ORCLCDB) が設定されていますので、追加設定は不要です。
CONTROL_FILES(設定不要) 制御ファイルの場所。追加設定は不要です。
LOG_ARCHIVE_FORMAT(設定不要) アーカイブログ ファイル名のフォーマット。Primary と Standby で同じフォーマットを指定します。今回はデフォルトのフォーマット (“%t_%s_%r.dbf”) をそのまま使用します。
REMOTE_LOGIN_PASSWORDFILE(設定不要) リモートログインにパスワードファイルを使用するかの設定。デフォルトで “EXCLUSIVE” が設定されているため追加設定は不要。
DB_UNIQUE_NAME一意のデータベース名。今回 Primary では “ORCLCDB” と設定しています。
LOG_ARCHIVE_CONFIGData Guard で REDO ログの送信元/受信先となる DB_UNIQUE_NAME を指定。Primary と Standby の両方を含めます。
LOG_ARCHIVE_DEST_1デフォルトのアーカイブログ出力先。DB_UNIQUE_NAME に自身の DB_UNIQUE_NAME を指定します。
LOG_ARCHIVE_DEST_2Standby へのアーカイブ出力設定。”SERVICE” に Standby への接続に使うネットサービス名、”DB_UNIQUE_NAME” に Standby の DB_UNIQUE_NAME を指定します。
また “ASYNC” を指定して非同期モードで REDO 転送を行うよう設定しています。
LOG_ARCHIVE_FORMATアーカイブログのファイルフォーマット。Primary と Standby で同じフォーマットを指定します。今回はデフォルトのフォーマットを指定しています。
FAL_SERVER(Standby 用の設定) Standby がアーカイブログを Fetch する際に接続するネットサービス名を指定します。
DB_FILE_NAME_CONVERT(Standby 用の設定) Primary でデータファイルが追加された時、その情報は Standby にも送信され Standby でもデータファイルが作成されます。Primary と Standby でデータファイルパスが異なる場合、このパラメータでファイル名の変換方法を指定します。
LOG_FILE_NAME_CONVERT(Standby 用の設定) Primary で REDO ログファイルが追加された時、その情報は Standby にも送信され Standby でもログファイルが作成されます。Primary と Standby でREDO ログのファイルパスが異なる場合、このパラメータでファイル名の変換方法を指定します。
STANDBY_FILE_MANAGEMENT(Standby 用の設定) Primary データベース上で行われたファイルの追加と削除が Standby に自動で適用されるかを指定します。今回は自動管理 (“AUTO”) を指定しています。

1-7). Primary のバックアップを取得

最後に Primary データベースのバックアップを取得します。今回必要となるのは、制御ファイル、パラメータファイル、データファイル、そしてアーカイブログファイルの 4つです。

  1. 制御ファイル: Standby 用の制御ファイルとしてバックアップしておく必要があります。”ALTER DATABASE CREATE STANDBY CONTROLFILE” コマンドを使用します。
  2. パラメータファイル: PFILE に書き出すことで、テキストエディタでパラメータを編集できます。今回は Standby をリストアする前にパラメータを変更しておく必要があるため、PFILE に書き出して Standby へコピーします。
  3. データファイル: 今回は RMAN を使って Image Copy Backup を取得します。Image Copy Backup は圧縮等をせずにデータファイルをそのままコピーしたもので、Standby サーバーの所定のディレクトリにファイルを配置することで簡単に復元できます。
  4. アーカイブログファイル: ファイルをそのまま cp コマンドでコピーします。データファイルと同様、Standby の所定のディレクトリに配置することで簡単に復元できます。

Primary サーバー

# 制御ファイルを Standby 用制御ファイルとしてコピー
$ sqlplus / as sysdba
SQL> ALTER DATABASE CREATE STANDBY CONTROLFILE AS '/backup/ORCLCDBREPL.ctl';

# パラメータファイルを PFILE として書き出す
SQL> CREATE PFILE='/backup/initORCLCDBREPL.ora' FROM SPFILE;

# データファイルをバックアップ
$ mkdir /backup/oradata
$ rman target /
RMAN> BACKUP AS COPY DATABASE FORMAT '/backup/oradata/%b';
RMAN> exit

# アーカイブログをバックアップ
$ mkdir /backup/dbs
$ cp /opt/oracle/product/19c/dbhome_1/dbs/arch* /backup/dbs/

# バックアップファイルの確認
$ ls /backup
dbs
oradata
initORCLCDBREPL.ora
orapwORCLCDB
ORCLCDBREPL.ctl

$ ls /backup/dbs
arch1_7_1118127276.dbf
arch1_8_1118127276.dbf

$ ls /backup/oradata
sysaux01.dbf
system01.dbf
undotbs01.dbf
users01.dbf

最終的に /backup フォルダには、パスワードファイル、Standby 用の制御ファイル、パラメータファイル、データファイル、そしてアーカイブログファイルのバックアップが保存されます。バックアップが終わったら、Standby サーバーに /backup フォルダのファイルをコピーしておきます。

2). Standby の設定手順

2-1). Oracle インストールとデータベースのシャットダウン

まず Oracle を Standby サーバーにインストールします。インストール手順は Rocky Linux への Oracle Database インストール方法 を参照してください。

Oracle をインストールしたら、データベースをシャットダウンします。

Standby サーバー

$ sudo su oracle
$ sqlplus / as sysdba
SQL> SHUTDOWN IMMEDIATE;

SQL> exit
$ exit  # exit from oracle user

2-2). Primary のバックアップファイルをコピー

Primary で取得したバックアップファイルは Standby にコピーしておきます。今回は Standby サーバーの /backup ディレクトリにバックアップファイルをコピーしてきたと想定します。

Standby サーバー

$ sudo mkdir /backup

# Primary のバックアップファイルを、ローカルの /backup フォルダにコピー

$ sudo chown -R oracle:oinstall /backup
$ sudo chmod -R 775 /backup

2-3). Standby から Primary への接続設定

Standby サーバーでも、Primary への接続設定を tnsnames.ora に記述します。Primary への接続の ネットサービス名 は “ORCLCDBPRIM” としています。

また併せてバックアップで取得したパスワードファイルも所定の場所に配置しておきます。

Standby サーバー

# Primary への接続設定
$ sudo su oracle
$ vim /opt/oracle/product/19c/dbhome_1/network/admin/tnsnames.ora
---
# 以下を追記
ORCLCDBPRIM=
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCP)(HOST=172.16.11.8)(PORT=1521))
    (CONNECT_DATA=
      (SERVER=DEDICATED)
      (SERVICE_NAME=ORCLCDB)
    )
  )
---

# バックアップからパスワードファイルをコピー
$ cp /backup/orapwORCLCDB /opt/oracle/product/19c/dbhome_1/dbs/

2-4). パラメータファイルの編集

Primary で取得したパラメータファイル (PFILE) の設定内容を、Standby 用に編集します。

Primary でバックアップした PFILE の主要な部分は以下のようになっています。

Standby サーバー

$ cat /backup/initORCLCDBREPL.ora
...
*.audit_file_dest='/opt/oracle/admin/ORCLCDB/adump'
*.control_files='/opt/oracle/oradata/ORCLCDB/control01.ctl','/opt/oracle/oradata/ORCLCDB/control02.ctl'
*.db_file_name_convert='/ORCLCDBREPL/','/ORCLCDB/'
*.db_name='ORCLCDB'
*.db_unique_name='ORCLCDB'
*.fal_server='ORCLCDBREPL'
*.log_archive_config='DG_CONFIG=(ORCLCDB,ORCLCDBREPL)'
*.log_archive_dest_1='LOCATION=/opt/oracle/product/19c/dbhome_1/dbs/arch VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=ORCLCDB'
*.log_archive_dest_2='SERVICE=ORCLCDBREPL ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=ORCLCDBREPL'
*.log_archive_format='%t_%s_%r.dbf'
*.log_file_name_convert='/ORCLCDBREPL/','/ORCLCDB/'
*.remote_login_passwordfile='EXCLUSIVE'
*.standby_file_management='AUTO'

これを Standby の DB_UNIQUE_NAME 等の設定にあわせて以下のように変更します。

Standby サーバー

$ vim /backup/initORCLCDBREPL.ora
---
# 以下を変更
*.audit_file_dest='/opt/oracle/admin/ORCLCDBREPL/adump'
*.control_files='/opt/oracle/oradata/ORCLCDBREPL/control01.ctl','/opt/oracle/oradata/ORCLCDBREPL/control02.ctl'
*.db_file_name_convert='/ORCLCDB/','/ORCLCDBREPL/'
*.db_unique_name='ORCLCDBREPL'
*.fal_server='ORCLCDBPRIM'
*.log_archive_config='DG_CONFIG=(ORCLCDB,ORCLCDBREPL)'
*.log_archive_dest_1='LOCATION=/opt/oracle/product/19c/dbhome_1/dbs/arch VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=ORCLCDBREPL'
*.log_archive_dest_2='SERVICE=ORCLCDBPRIM ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=ORCLCDB'
*.log_file_name_convert='/ORCLCDB/','/ORCLCDBREPL/'

各設定項目の概要は 1-6 を参照してください。Standby では DB_UNIQUE_NAME が “ORCLCDBREPL” となり、Primary 接続のネットサービス名が “ORCLCDBPRIM” になるため、それに合わせて設定を変えています。

以下注意する点のある項目です。

2-5). Primary のバックアップからデータベースを復元

それでは Primary のバックアップから Standby データベースを復元します。

※ なお手順通りに進めていると、この時点で Standby データベースはシャットダウン状態になっています。もしシャットダウンされていない場合は、先にシャットダウンしてください。

2-4). パラメータファイルの編集” でも触れましたが、DB_UNIQUE_NAME の変更に合わせて監査ログおよび制御ファイルのディレクトリが変更されます。

そのため まず監査ログおよび制御ファイル用のディレクトリを作成し、その後データベースをリストアします。(今回は Image Copy Backup のため、データファイルやアーカイブログは所定の場所にファイルを配置するだけで復元できます)

Standby サーバー

# 監査ログおよび制御ファイル用のディレクトリ作成
$ mkdir -p /opt/oracle/admin/ORCLCDBREPL/adump
$ mkdir /opt/oracle/oradata/ORCLCDBREPL

# 制御ファイルをコピー
$ cp /backup/ORCLCDBREPL.ctl /opt/oracle/oradata/ORCLCDBREPL/control01.ctl
$ cp /backup/ORCLCDBREPL.ctl /opt/oracle/oradata/ORCLCDBREPL/control02.ctl

# データファイルをコピー
# データファイルは制御ファイルと同じディレクトリに配置します
$ cp /backup/oradata/* /opt/oracle/oradata/ORCLCDBREPL/

# アーカイブファイルをコピー
$ cp /backup/dbs/* /opt/oracle/product/19c/dbhome_1/dbs/

# PFILE から SPFILE を作成
$ sqlplus / as sysdba
SQL> CREATE SPFILE FROM PFILE='/backup/initORCLCDBREPL.ora';
SQL> exit

2-6). Standby データベースを開始し REDO Apply を開始

これで Standby を起動する準備が整ったので、データベースを開始し REDO Apply プロセスを開始します。

なお Data Guard では Cold Standby となるため、Standby データベースは OPEN 状態にすることはできませんので注意してください。

REDO Apply は ALTER DATABASE RECOVER MANAGED STANDBY DATABASE コマンドで開始します。この時 DOSCONNECT FROM SESSION を付けると、REDO Apply をバックエンドプロセスとして実行することができます。

なおサーバー OS のシャットダウン等で Oracle インスタンスが停止した場合、Oracle インスタンスを再起動した後、再度 REDO Apply を開始する必要がありますので注意してください (REDO Apply は自動起動しません)。

Standby サーバー

$ sqlplus / as sysdba

# Standby データベースを MOUNT 状態で開始
SQL> STARTUP MOUNT

# REDO Apply を開始
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

3). レプリケーション状態の確認

先にも触れましたが、Standby データベースは OPEN できないため、Standby データベースで SELECT クエリを実行してレプリケーションが正常に行われているかを確認することはできません。

レプリケーションの状態は Primary および Standby それぞれで確認できますので、その方法を紹介します。

3-1). Primary 側での REDO 転送サービスの状態確認

Primary 側で REDO 転送が正常に行われているかは、V$ARCHIVE_DEST_STATUS で確認できます。”RECOVERY_MODE” に “MANAGED REAL TIME APPLY” と表示され、”STATUS” が “VALID” であれば正常に動作しています。

Primary サーバー

SQL> SELECT dest_name, status, recovery_mode FROM V$ARCHIVE_DEST_STATUS WHERE dest_id IN (1, 2) ORDER BY 1;
DEST_NAME           STATUS    RECOVERY_MODE
------------------- --------- ----------------------------------
LOG_ARCHIVE_DEST_1  VALID     IDLE
LOG_ARCHIVE_DEST_2  VALID     MANAGED REAL TIME APPLY

3-2). Standby 側でのレプリケーション状態の確認

3-2-1). Standby データベースの状態確認

Standby データベースとして起動したデータベースは、V$DATABASE の “DATABASE_ROLE” に “PHYSICAL_STANDBY” と表示されます。また V$DATABASE では “CURRENT_SCN” を確認できるため、Primary の SCN と比べることでレプリケーションが行われているのを確認できます。

Standby サーバー

# V$DATABASE で Standby データベースの状態を確認
SQL> SELECT NAME, LOG_MODE, OPEN_MODE, DATABASE_ROLE, FORCE_LOGGING, CURRENT_SCN FROM V$DATABASE;
NAME     LOG_MODE    OPEN_MODE  DATABASE_ROLE    FORCE_LOGGING  CURRENT_SCN
-------- ----------- ---------- ---------------- -------------- -----------
ORCLCDB  ARCHIVELOG  MOUNTED    PHYSICAL STANDBY YES            2395869

3-2-2). REDO Apply の状態確認

REDO Apply の状態は V$DATAGUARD_PROCESS で確認できます。”NAME” が “MRP0“, “ROLE” が “managed recovery” と表示されているプロセスの “ACTION” に “APPLYING_LOG” と表示されていれば、REDO Apply が動作しているのを確認できます。

※なお、公式ドキュメントでは “recovery logmerger” という ROLE のプロセスが “APPLYING LOG” になると書かれていますが、今回の環境ではこのプロセスは確認できませんでした。このプロセスは “PR00” という名前で Paralell Media Recovery process 呼ばれるようです。調べた感じだと、環境によっては MRP0 が複数の子プロセスを並列に実行して REDO ログのリカバリを行う場合があり、PR00 はこの子プロセスのコーディネーターとして動作するようです。今回はこの PR00 プロセスは起動していないので、レプリケーションの状態を見るのにMRP0 のみを確認しています。

Standby サーバー

SQL> SELECT NAME, ROLE, THREAD#, SEQUENCE#, ACTION FROM V$DATAGUARD_PROCESS;
NAME  ROLE              THREAD#  SEQUENCE#  ACTION
----- ----------------- -------- ---------- ------------
...
MRP0  managed recovery         1         12 APPLYING_LOG
...

4). Primary から Standby へのフェイルオーバー

Primary に何らかの障害が発生した場合、Standby を昇格して新しい Primary とし、システムの動作を継続させることができます。Primary から Standby にデータの書き込み先 / 読み子み先を変更することを “フェイルオーバー” と呼びます。

なお、Oracle では Primary サーバーをメンテナンス等で一時的に停止する必要がある場合など、一時的な役割の変更を “スイッチオーバー” と呼んでいます。この場合、Primary はすぐにまたマスターデータベースとして復帰するため、フェイルオーバーと比べて手順が単純です。この記事では扱いませんので、詳細は 公式ドキュメント を確認してください。

4-1). 事前準備

フェイルオーバーを行うと、Standby データベースを OPEN 状態にできるため、SELECT クエリを実行できるようになります。

レプリケーションによりデータが正常に Standby に伝搬されていたかを確認したいので、フェイルオーバーを行う前に Primary データベースにデータを追加登録しておきます。

なお、アーカイブログに書き出されないとレプリケーションされないため、手動でログスイッチを行ってアーカイブログに書き出します。

Primary サーバー

# テストデータの登録
SQL> INSERT INTO vagrant.test1 (id, value) SELECT level, CONCAT('value ', level) FROM dual CONNECT BY level <= 20;
20 rows created.

SQL> commit;
Commit complete.

# 手動でログスイッチを行いアーカイブログに書き出す
SQL> ALTER SYSTEM SWITCH LOGFILE;

上記 1-1 で既に 10件登録しており、今回 20件登録したので、合計 30レコードが登録されている状態になります。

4-2) フェイルオーバーの実行

フェイルオーバーを行うには、まず REDO Apply を停止した後、ALTER DATABASE FAILOVER TO コマンドを実行します。

Standby サーバー

# REDO Apply プロセスを停止
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

# Standby の DB_UNIQUE_NAME を指定して FAILOVER コマンドを実行
SQL> ALTER DATABASE FAILOVER TO ORCLCDBREPL;

# もし上記コマンドで ORA-16472 エラーが発生した場合は、以下のコマンドで強制的に FAILOVER できる
# SQL> ALTER DATABASE ACTIVATE PHYSICAL STANDBY DATABASE;

# データベースをオープン
SQL> ALTER DATABASE OPEN

これで Standby データベースが OPEN 状態になったため、読み込み/書き込みを行えるようになります。

先ほど登録したテストデータが SELECT できるのを確認します。

SQL> SELECT * FROM vagrant.test1;
...
30 rows selected. 

以上が Data Guard の設定手順となります。その他詳細は公式ドキュメントをご確認ください。