Oracle Dataguard
以下の構成の前提でOracle Data Guard を構築する。
OS ホスト名
* プライマリ:ora1
* スタンバイ:ora2
DB_UNIQUE_NAME
* 両方ともに DG
Oracle Netサービス名
* プライマリ向け: PROD
* スタンバイ向け: DR
1.構築前事前準備
DataGuard の通信の受け口になるネットサービス名をまずはローカルネーミングで登録する。
RMAN での duplicate database
コマンド時、及び、アーカイブログの転送で受け口となる。
なお、プライマリ/スタンバイ両方で同一の定義しておかないと、RMAN での duplicate database
コマンド時に内部的にプライマリ/スタンバイ間で双方向通信するようなのでエラーとなってしまうため注意。
①-1_ネットサービス名登録(プライマリ/スタンバイ共通)(tnsnames.ora)
PROD =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = ora1)(PORT = 9999))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = DG)
(UR=A)
)
)
DR =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = ora2)(PORT = 9999))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = DG)
(UR=A)
)
)
(参考) NOMOUNT状態のスタンバイDBにつなぐためには(UR=A)が必須
①-2_リスナーへの静的サービス登録(プライマリ/スタンバイ共通)(listener.ora)
DATAGUARD =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = ora1 or ora2)(PORT = 9999))
)
)
SID_LIST_DATAGUARD =
(SID_LIST =
(SID_DESC =
(SID_NAME = DG)
(ORACLE_HOME = /opt/app/oracle/product/dbhome_1/19.3.0)
)
)
①-3_強制ロギング有効化(プライマリ側)
alter database force logging;
①-4_スタンバイREDOログファイル作成(プライマリ側)
--スタンバイREDO作成。
--スタンバイREDOを確認。1行以上出力があれば作成されている状態と判断。
COL STATUS FOR A20
SELECT GROUP#,THREAD#,SEQUENCE#,ARCHIVED,STATUS FROM V$STANDBY_LOG;
①-5_sysdbaで繋げるようにパスワードファイル作成(プライマリ/スタンバイ共通)
orapwd file=orapwDG password=P#ssw0rd entries=10 force=y format=19.3
①-6_適切な初期化パラメータ設定(プライマリ側)
alter system set LOG_ARCHIVE_CONFIG='DG_CONFIG=(PROD,DR)'scope=spfile;
alter system set LOG_ARCHIVE_DEST_STATE_2='ENABLE' scope=spfile;
alter system SET LOG_ARCHIVE_DEST_2='service=DR LGWR ASYNC NOAFFIRM delay=0 compression=disable max_failure=0 reopen=5 db_unique_name=DR net_timeout=30 valid_for=(online_logfile,all_roles)' scope=spfile;
alter system set STANDBY_FILE_MANAGEMENT='AUTO' scope=spfile;
alter system set FAL_SERVER='DR' scope=spfile;
alter system set FAL_CLIENT='PROD' scope=spfile;
alter system set REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE scope=spfile;
alter system set LOG_ARCHIVE_MAX_PROCESSES=2 scope=spfile;
①-6_適切な初期化パラメータ設定(スタンバイ側(プライマリ側との差異は以下のRMANコマンドで自動的にスタンバイ構築時に反映可能))
alter system set LOG_ARCHIVE_CONFIG='DG_CONFIG=(PROD,DR)'scope=spfile;
alter system set LOG_ARCHIVE_DEST_STATE_2='ENABLE' scope=spfile;
alter system set log_archive_dest_2="service=PROD ASYNC NOAFFIRM delay=0 compression=disable max_failure=0 reopen=5 db_unique_name=PROD net_timeout=30 valid_for=(online_logfile,all_roles)" scope=spfile;
alter system set STANDBY_FILE_MANAGEMENT='AUTO' scope=spfile;
alter system set FAL_SERVER='PROD' scope=spfile;
alter system set FAL_CLIENT='DR' scope=spfile;
alter system set REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE scope=spfile;
alter system set LOG_ARCHIVE_MAX_PROCESSES=2 scope=spfile;
- (ご参考)初期化パラメータ: https://docs.oracle.com/cd/E82638_01/sbydb/creating-oracle-data-guard-physical-standby.html#GUID-0FD317D6-1A49-4DB3-A141-D00CB3089E84
- COMPRESSION オプションは、Advanced Compression オプションが必要。
- LOG_ARCHIVE_MAX_PROCESSESは通常レプリケーション先+1でOK
2.スタンバイデータベース作成(プライマリ側)(RMANアクティブデータベースコピー)
インスタンス作成sample
rman TARGET SYS/P#ssw0rd@PROD AUXILIARY SYS/P#ssw0rd@DR;
DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE DORECOVER
SPFILE
SET DB_UNIQUE_NAME='DG'
SET FAL_SERVER='PROD'
SET FAL_CLIENT='DR'
SET LOG_ARCHIVE_DEST_2='service=PROD ASYNC NOAFFIRM delay=0 compression=disable max_failure=0 reopen=5 db_unique_name=DG net_timeout=30 valid_for=(online_logfile,all_roles)'
NOFILENAMECHECK;
- duplicate先にすでにspfileが存在するとエラー(
RMAN-05537: DUPLICATE without TARGET connection when auxiliary instance is started with spfile cannot use SPFILE clause
) - CRSのリソース登録されているとエラーになる。(
ORA-65500: could not modify DB_UNIQUE_NAME, resource exists
) - NOFILENAMECHECKは、プライマリ・スタンバイサーバの同一パスに制御ファイル、REDOログ、データファイルを配置する場合は付与要。
- フラッシュデータベースはソースDBで有効化されていてもターゲットDBで初期状態として無効化される
3.スタンバイREDO作成
リアルタイム適用する場合は作成
スタンバイREDOログ作成。
-- プライマリで実行して出力した以下のSQL実行結果をスタンバイで実行。
select 'alter database add standby logfile group ' ||
to_number((select count(*) from v$log) + rownum) || '(''/opt/app/oracle/oradata/dg/REDO0' ||
to_number((select count(*) from v$log) + rownum) || '.LOG'') SIZE ' ||
(select max( bytes/1024/1024) from v$log) || 'M;' as standbyredo
from v$log
union all
select 'alter database add standby logfile group ' ||
((select max(group#) from v$log) + (select count(*) from v$log) + 1) || '(''/opt/app/oracle/oradata/dg/REDO0' ||
((select max(group#) from v$log) + (select count(*) from v$log) + 1) || '.LOG'') SIZE ' ||
(select max( bytes/1024/1024) from v$log) || 'M;'
from dual;
- スタンバイREDOログは、REDOログと同じサイズである必要があり、REDOログよりも少なくとも1つ多くのスタンバイログのグループが必要。この条件を満たさないとリアルタイム適用ができず、単純にプライマリでログスイッチが発生した際にそのREDOがスタンバイに転送され、その内容が適用されるのでスタンバイへの反映が遅れる
- 参考URL
https://www.it-swarm-ja.tech/ja/oracle-11g-r2/%E6%96%B0%E3%81%97%E3%81%84%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8C%E3%83%97%E3%83%A9%E3%82%A4%E3%83%9E%E3%83%AA%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AB%E6%8C%BF%E5%85%A5%E3%81%95%E3%82%8C%E3%81%9F%E3%81%A8%E3%81%8D%E3%81%AB%E3%80%81%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8C%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%90%E3%82%A4%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AB%E5%8F%8D%E6%98%A0%E3%81%95%E3%82%8C%E3%82%8B%E3%81%BE%E3%81%A7%E3%81%AB%E3%81%8B%E3%81%8B%E3%82%8B%E6%A8%99%E6%BA%96%E7%9A%84%E3%81%AA%E6%99%82%E9%96%93%E9%81%85%E5%BB%B6%E3%81%AF%E3%81%A9%E3%82%8C%E3%81%8F%E3%82%89%E3%81%84%E3%81%A7%E3%81%99%E3%81%8B%E3%80%82/l966400523/
4.スタンバイデータベース作成後の状態確認、及び、REDO APPLY
インスタンスのロールを確認
COL DB_UNIQUE_NAME FOR A20
COL DATABASE_ROLE FOR A20
COL OPEN_MODE FOR A30
SELECT DB_UNIQUE_NAME,DATABASE_ROLE,OPEN_MODE FROM V$DATABASE;
REDO-APPLYの起動・停止・状態確認(スタンバイ側実行)
-- フォアグラウンド起動(起動状態=上記OPEN_MODEがスタンバイDB側でREAD ONLY WITH APPLY)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE;
-- バックグラウンド起動(起動状態=上記OPEN_MODEがスタンバイDB側でREAD ONLY WITH APPLY)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
-- 停止(停止状態=上記OPEN_MODEがスタンバイDB側でREAD ONLY)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
-- 状態確認(MPR0プロセスの状態)
SELECT PROCESS, STATUS FROM V$MANAGED_STANDBY WHERE PROCESS LIKE 'MRP%';
-- プライマリ側でアーカイブREDOログ化されたものがスタンバイ側に転送されて逐次適用される。適用完了自体がAPPLIED列から判別可能
col NAME format a80;
col APPLIED format a15;
SELECT SEQUENCE#,NAME,FIRST_TIME, NEXT_TIME,APPLIED FROM V$ARCHIVED_LOG ORDER BY SEQUENCE#;
-- 表示されたLOW~HIGHの番号のアーカイブREDOが適用されていない
SELECT * FROM V$ARCHIVE_GAP;
-- FAL 機構関連初期化パラメータをスタンバイDB側で設定することで自動でアーカイブギャップは解消する。定期的に転送されていないREDOが無いかプライマリ側に確認しにいってくれる
FAL_SERVER=<プライマリDBへのネットサービス名>
- DB再起動により、REDO-APPLYは停止状態に遷移
- MOUNTモードかつREDO-APPLY起動中にopenは出来ない。インスタンスをopenしたい場合は、一度REDO-APPLYを停止→open→REDO-APPLYを起動とする。ただ、スタンバイDBのデータの読み取りにはライセンスとして Active Data Guard が必要。
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-10456: cannot open standby database; media recovery session may be in progress
4.フェイルオーバー
スイッチオーバー実行手順
1.プライマリDBがスタンバイロールに変換可能か確認(プライマリ側)
select switchover_status from v$database;
SWITCHOVER_STATUS
--------------------
TO STANDBY
2.プライマリDBをスタンバイロールにスイッチオーバー(プライマリ側)
alter database commit to switchover to standby with session shutdown;
3.プライマリDBをスタンバイロールとして起動(プライマリ側)
shutdown abort;
startup mount;
select database_role from v$database;
DATABASE_ROLE
----------------
PHYSICAL STANDBY
4.スタンバイDBをプライマリロールに変換可能か確認(スタンバイ側)
select switchover_status from v$database;
SWITCHOVER_STATUS
--------------------
TO PRIMARY
5.スタンバイDBをプライマリロールとして起動(スタンバイ側)
alter database commit to switchover to primary with session shutdown;
alter database open;
select database_role from v$database;
DATABASE_ROLE
----------------
PRIMARY
6.Redo Applyを開始(スタンバイ側)
フェイルオーバー実行手順
1.プライマリDBからスタンバイDBに未送信のREDO全部送付(プライマリ側)
ALTER SYSTEM FLUSH REDO TO <target_db_name>;
※target_db_nameは送信先のdb_unique_name
2.Redo-Applyの適用状態確認(スタンバイ側)
col NAME format a80;
col APPLIED format a15;
SELECT SEQUENCE#,NAME,FIRST_TIME, NEXT_TIME,APPLIED FROM V$ARCHIVED_LOG ORDER BY SEQUENCE#;
3.Redo-Apply停止(スタンバイ側)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
4-1.残存REDOを全て適用しきる(スタンバイ側)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;
→4-1実施の場合は5に遷移
4-2.即時にプライマリDBへと移行する(スタンバイ側)
ALTER DATABASE ACTIVATE PHYSICAL STANDBY DATABASE;
→4-2実施の場合は7に遷移。この場合その時点で未適用のREDOは無視される。
未適用REDO分のデータはロストする形になるので実施するかは要件による。この処理を実施するとDBはマウントモードになる。
5.プライマリに遷移可能かを確認(スタンバイ側)
SELECT SWITCHOVER_STATUS FROM V$DATABASE;
SWITCHOVER_STATUS
-----------------
TO PRIMARY
6.プライマリDBへとスイッチオーバー(スタンバイ側)
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;
7.データベースOPEN(スタンバイ側)
8.データベースバックアップ(スタンバイ側)
保護モード確認
select protection_mode from v$database;
PROTECTION_MODE
------------------------------------------------------------
MAXIMUM PERFORMANCE
-- MAXIMUM PROTECTION - 保護モード
-- MAXIMUM AVAILABILITY - 可用性モード
-- MAXIMUM PERFORMANCE - パフォーマンスモード
-- RESYNCHRONIZATION - 再同期化モード
-- UNPROTECTED - 保護対象外
-- (プライマリがマウント済だがオープンされていない場合に発生)
モード変更
alter database set standby database to MAXIMIZE<???>;
dgmgrlでの Data Guard 管理
dgmgrl sys/P#ssw0rd@prod << EOF
disable configuration;
remove configuration;
create configuration 'Broker' as primary database is PROD connect identifier is PROD;
ADD DATABASE DR AS CONNECT IDENTIFIER IS DR;
enable configuration;
edit database prod set property StaticConnectIdentifier = 'PROD';
edit database dr set property StaticConnectIdentifier = 'DR';
EOF