前回の記事で、Oracle RACのサービスを用いたフェイルオーバー順序の制御について触れましたが、今回はサーバ障害などでサービスがフェイルオーバーした後にサーバが復帰した際の、サービスのフェイルバック関連の挙動について調べてみました。
1. サービスは自動フェイルバックするのか
サービスを構成する際は、優先インスタンス(正常時にサービスを稼働させるインスタンス)と、使用可能インスタンス(優先インスタンスがダウンしている場合に稼働させるインスタンス)を定義する必要があります。
優先インスタンスで稼働していたサービスは、サーバ障害等で優先インスタンスが停止すると、使用可能インスタンスにフェイルオーバーして稼働しますが、優先インスタンスが復旧・起動した場合、フェイルオーバーしていたサービスは、デフォルトでは、自動的に優先インスタンスにフェイルバックしません。フェイルバックしない理由は、マニュアル「Real Application Clusters管理およびデプロイメント・ガイド」で、以下の様に記載されています。
なお、Oracle 19.3以降のリリースでは、サービスのfailback属性にyesを設定すると、自動的に優先インスタンスにフェイルバックさせることができます(デフォルトはnoで自動フェイルバックしない)。
2. サービスの自動フェイルバック設定(19.3以降)
2ノードRAC環境で、優先インスタンスをインスタンス#1(ORCL1)、使用可能インスタンスをインスタンス#2(ORCL2)として、自動フェイルバックを有効にしたサービスORCL_SVC_ONと、自動フェイルバックを無効にしたサービスORCL_SVC_OFFを作成するコマンド例を以下に記載します。
自動フェイルバックONにする場合
サービス作成時に「-failback yes」を指定することで、自動フェイルバックが有効になります。
srvctl add service -d ORCL -s ORCL_SVC_ON -failback yes -preferred ORCL1 -available ORCL2 -pdb orclpdb
自動フェイルバックOFFにする場合
サービス作成時に「-failback no」を指定する、またはfailbackパラメータを指定しないことで、自動フェイルバックが無効になります。
srvctl add service -d ORCL -s ORCL_SVC_OFF -failback no -preferred ORCL1 -available ORCL2 -pdb orclpdb または srvctl add service -d ORCL -s ORCL_SVC_OFF -preferred ORCL1 -available ORCL2 -pdb orclpdb
3. 既存サービスに対する自動フェイルバック有無の確認
サービスに設定された自動フェイルバックの状態を確認したい場合は、srvctl config serviceコマンドを使用することで確認できます。
自動フェイルバックONの場合の出力例
出力項目に「フェイルバック:true」が含まれていることから、自動フェイルバックONであることが確認できます。
srvctl config service -d ORCL -service ORCL_SVC_ON サービス名: ORCL_SVC_ON サーバー・プール: … 保存時間: 86400秒 フェイルバック : true リプレイ開始時間: 300秒 サービスは有効です … 優先インスタンス: ORCL1 使用可能なインスタンス: ORCL2 CSSクリティカル: no
自動フェイルバックOFFの場合の出力例
ONのときに出力された「フェイルバック」が、出力項目に含まれないことで、自動フェイルバックOFFであることが確認できます。
※サービス作成時にfailbackパラメータにnoを設定しても、「フェイルバック」項目が出力されません。
srvctl config service -d ORCL -service ORCL_SVC_OFF サービス名: ORCL_SVC_OFF サーバー・プール: … 保存時間: 86400秒 リプレイ開始時間: 300秒 サービスは有効です … 優先インスタンス: ORCL1 使用可能なインスタンス: ORCL2 CSSクリティカル: no
4. サービスをフェイルバックさせた後のDBコネクションについて
インスタンスダウン等によりサービスがフェイルオーバーした後に、フェイルオーバー先でDBコネクションを生成し、保持し続ける様なことをする場合(例: コネクションプールなど)、ダウンしたインスタンスが復活した後にサービスがフェイルバックした際に、保持されたDBコネクションがどうなるか実機確認した結果、自動フェイルバック、手動フェイルバック共に、接続済みの既存DBコネクションは、フェイルオーバー先にそのまま接続された状態で、SQLも実行できました。
確認は、サービスの自動フェイルバック設定の説明で使用したサービスORCL_SVC_ONとORCL_SVC_OFFを用いて、以下の手順で確認しました。
(1) インスタンス#1が稼働するサーバ#1を強制停止し、各サービスがフェイルオーバーしていることを確認する
grid$ crsctl stat res -w "NAME en svc" -t -------------------------------------------------------------------------------- Name Target State Server State details -------------------------------------------------------------------------------- Cluster Resources -------------------------------------------------------------------------------- ora.orcl.orcl_svc_off.svc 2 ONLINE ONLINE dbsrv02 STABLE ora.orcl.orcl_svc_on.svc 2 ONLINE ONLINE dbsrv02 STABLE --------------------------------------------------------------------------------
サービスがサーバ#2で稼働していることが確認できました。
(2) 各サービスに対してそれぞれ接続する
サービス毎にターミナルを(計2つ)起動します。特段記載のないコマンドは、両ターミナルで実行します。
oracle$ sqlplus /nolog SQL*Plus: Release 19.0.0.0.0 - Production on 水 1月 1 23:03:56 2025 Version 19.22.0.0.0 Copyright (c) 1982, 2023, Oracle. All rights reserved. ■ORCL_SVC_ON用のターミナルでは以下を実行 SQL> conn test/xxxxx@orcl_svc_on 接続されました ■ORCL_SVC_OFF用のターミナルでは以下を実行 SQL> conn test/xxxxx@orcl_svc_off 接続されました
(3) 各接続先のインスタンス名をv$instanceにアクセスして確認する
SQL> SELECT instance_name FROM v$instance; INSTANCE_NAME ---------------- ORCL2
どちらのターミナルも、インスタンス#2に接続されていることが確認できました。
(4) サーバ#1を起動してインスタンス#1を起動させ、各サービスの起動インスタンスを確認する
grid$ crsctl stat res -w "NAME en svc" -t -------------------------------------------------------------------------------- Name Target State Server State details -------------------------------------------------------------------------------- Cluster Resources -------------------------------------------------------------------------------- ora.orcl.orcl_svc_off.svc 2 ONLINE ONLINE dbsrv02 STABLE ora.orcl.orcl_svc_on.svc 1 ONLINE ONLINE dbsrv01 STABLE --------------------------------------------------------------------------------
自動フェイルバックONのORCL_SVC_ONサービスは、サーバ#1にフェイルバックしていることが確認できました。
(5) サービスを手動フェイルバックする
自動フェイルバックOFFのORCL_SVC_OFFサービスを手動でフェイルバックします。
※oracleユーザにスイッチまたは、oracleユーザで接続したターミナルから実行 oracle$ srvctl stop service -d ORCL -s ORCL_SVC_OFF oracle$ srvctl start service -d ORCL -s ORCL_SVC_OFF ※gridユーザにスイッチまたは、gridユーザで接続したターミナルから実行 grid$ crsctl stat res -w "NAME en svc" -t -------------------------------------------------------------------------------- Name Target State Server State details -------------------------------------------------------------------------------- Cluster Resources -------------------------------------------------------------------------------- ora.orcl.orcl_svc_off.svc 1 ONLINE ONLINE dbsrv01 STABLE ora.orcl.orcl_svc_on.svc 1 ONLINE ONLINE dbsrv01 STABLE --------------------------------------------------------------------------------
自動フェイルバックOFFのORCL_SVC_OFFサービスも、サーバ#1にフェイルバックしていることが確認できました。
(6) (2)で接続したセッションで、再度v$instanceにアクセスする
SQL> SELECT instance_name FROM v$instance; INSTANCE_NAME ---------------- ORCL2
どちらのターミナルも、インスタンス#2に接続されたままで、SQLが実行できることが確認できました。
サービスのフェイルバック後に生成されたDBコネクションは、復活したインスタンスに接続される様になるため、フェイルバック中に生成されたDBコネクションが残存していると、同一サービスに対しての接続であるにも関わらず、接続先インスタンスが異なるDBコネクションが混在するため、サービスを用いたAPパーティショニングを実装する場合は問題となる可能性があります。
5. サービスのフェイルバックに合わせてDBコネクションを切断可能か?
サービスのフェイルバックに合わせてDBコネクションを切断したい場合は、サービスを作成する際に、-stopoptionパラメータにIMMEDIATEやTRANSACTIONALを指定する事で切断できることがマニュアルに記載されています。
IMMEDIATE: サービスの停止前にセッションの排出を許可します。
TRANSACTIONAL: -drain_timeoutパラメータで指定した時間までセッションの排出を許可します。サービスは、制限時間に達したとき、および残っているセッションが終了したときに停止されます。
-stopoptionパラメータのデフォルト値はNONEですが、マニュアルに記載されているNONEの内容については注意が必要です。マニュアルには下記の様に記載されていますが、実際の挙動はセッションが継続されており矛盾していたためです。
NONEを指定すると、セッションは終了されます。
英語版のマニュアルを確認したところ、下記の様に記載されていたため、日本語版のマニュアル誤記かと思われます。
If you specify NONE, then no sessions are terminated.
サービスのフェイルバックに合わせてDBコネクションを切断する設定を導入した場合、ダウンしたインスタンス(サーバ)を復旧すると、自動フェイルバックONのサービス経由で接続したDBコネクションは切断されてしまうため、オンライン開局中など、DB処理が発生する可能性の高い時間帯にはインスタンスの復旧を実施しない様な、運用上の考慮が必要となる可能性があるかと思います。
次の記事:開発環境におけるDB構成パターンについて考えてみた ~ その1 ~