サービスのTAF(透過的アプリケーションフェイルオーバー)について、机上の知識はあるものの、実務経験が無いため、実際の動きを検証してみました。
■検証環境
OS:Oracle Linux 6.5
GI:Oracle Grid Infrastructure 12c Release 1 (12.1.0.2.0) Enterprise Edition
DB:Oracle Database 12c Release 1 (12.1.0.2.0) Enterprise Edition
※2ノードRAC(管理者管理型DB)
■前提
・SCANを使用しています
・DNSサーバはdnsmasqを使用しています
・ノード1を疑似クライアントとしています (※1)
(※1) 本来ならクライアント用のアプリケーションサーバを建てて、JDBCやOCI等のドライバを入れるべきですが割愛しました
■設定情報
[root@node1 ~]# /u01/app/12.1.0/grid/bin/crsctl stat res -t
--------------------------------------------------------------------------------
Name Target State Server State details
--------------------------------------------------------------------------------
Local Resources
--------------------------------------------------------------------------------
ora.DATA.dg
ONLINE ONLINE node1 STABLE
ONLINE ONLINE node2 STABLE
ora.FRA.dg
ONLINE ONLINE node1 STABLE
ONLINE ONLINE node2 STABLE
ora.LISTENER.lsnr
ONLINE ONLINE node1 STABLE
ONLINE ONLINE node2 STABLE
ora.asm
ONLINE ONLINE node1 Started,STABLE
ONLINE ONLINE node2 Started,STABLE
ora.net1.network
ONLINE ONLINE node1 STABLE
ONLINE ONLINE node2 STABLE
ora.ons
ONLINE ONLINE node1 STABLE
ONLINE ONLINE node2 STABLE
--------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
ora.LISTENER_SCAN1.lsnr
1 ONLINE ONLINE node1 STABLE
ora.LISTENER_SCAN2.lsnr
1 ONLINE ONLINE node1 STABLE
ora.LISTENER_SCAN3.lsnr
1 ONLINE ONLINE node1 STABLE
ora.MGMTLSNR
1 ONLINE ONLINE node1 169.254.105.185 192.
168.100.101,STABLE
ora.cvu
1 ONLINE ONLINE node2 STABLE
ora.mgmtdb
1 ONLINE ONLINE node1 Open,STABLE
ora.node1.vip
1 ONLINE ONLINE node1 STABLE
ora.node2.vip
1 ONLINE ONLINE node2 STABLE
ora.oc4j
1 ONLINE ONLINE node2 STABLE
ora.orcl.db
1 ONLINE ONLINE node1 Open,STABLE
2 ONLINE ONLINE node2 Open,STABLE
ora.orcl.fuga.svc ★検証用のサービス
1 ONLINE ONLINE node1 STABLE
2 ONLINE ONLINE node2 STABLE
ora.scan1.vip
1 ONLINE ONLINE node1 STABLE
ora.scan2.vip
1 ONLINE ONLINE node1 STABLE
ora.scan3.vip
1 ONLINE ONLINE node1 STABLE
--------------------------------------------------------------------------------
リスナーの登録情報
#ノード1
[grid@node1 ~]$ lsnrctl status LISTENER
サービスのサマリー...
サービス"+ASM"には、1件のインスタンスがあります。
インスタンス"+ASM1"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"-MGMTDBXDB"には、1件のインスタンスがあります。
インスタンス"-MGMTDB"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"_mgmtdb"には、1件のインスタンスがあります。
インスタンス"-MGMTDB"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"fuga"には、1件のインスタンスがあります。
インスタンス"orcl1"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"node_cluster"には、1件のインスタンスがあります。
インスタンス"-MGMTDB"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"orcl"には、1件のインスタンスがあります。
インスタンス"orcl1"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"orclXDB"には、1件のインスタンスがあります。
インスタンス"orcl1"、状態READYには、このサービスに対する1件のハンドラがあります...
#ノード2
[grid@node2 ~]$ lsnrctl status LISTENER
サービスのサマリー...
サービス"+ASM"には、1件のインスタンスがあります。
インスタンス"+ASM2"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"fuga"には、1件のインスタンスがあります。
インスタンス"orcl2"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"orcl"には、1件のインスタンスがあります。
インスタンス"orcl2"、状態READYには、このサービスに対する1件のハンドラがあります...
サービス"orclXDB"には、1件のインスタンスがあります。
インスタンス"orcl2"、状態READYには、このサービスに対する1件のハンドラがあります...
疑似クライアントのネットサービス名情報
#ノード1、ノード2
[oracle@node1 ~]$ cat /u01/app/oracle/product/12.1.0/dbhome_1/network/admin/tnsnames.ora
ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = scan.oracle12c.jp)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)
FUGA =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = scan.oracle12c.jp)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = fuga)
)
)
■検証パターン
①フェイルオーバータイプNONEの検証
②フェイルオーバータイプSESSIONの検証
③フェイルオーバータイプSELECTの検証
■検証
①フェイルオーバータイプNONEの検証
疑似クライアントからfugaサービス(failovertype:NONE)に接続後、接続先インスタンスで疑似障害を発生させ、セッションがフェイルオーバーされるか検証します
サービスの情報
[oracle@node1 ~]$ srvctl config service -db orcl -service fuga
サービス名: fuga
サーバー・プール:
カーディナリティ: 2
切断: false
サービス・ロール: PRIMARY
管理ポリシー: AUTOMATIC
DTPトランザクション: false
AQのHA通知: false
グローバル: false
コミット結果: false
フェイルオーバー・タイプ:
フェイルオーバー・メソッド:
TAFフェイルオーバー再試行:
TAFフェイルオーバー遅延:
接続ロード・バランシングの目標: LONG
ランタイム・ロード・バランシングの目標: NONE
TAFポリシー仕様: NONE
エディション:
プラガブル・データベース名:
最大タイム・ラグ: ANY
SQL翻訳プロファイル:
保存時間: 86400秒
リプレイ開始時間: 300秒
セッション状態一貫性:
GSMフラグ: 0
サービスは有効です
優先インスタンス: orcl1,orcl2
使用可能なインスタンス:
【検証手順】
1. 疑似クライアントで「sqlplus system/XXXXX@fuga」を実行する
2. 接続先インスタンス(本検証ではインスタンス2)のSMONプロセスをキルして疑似障害を発生させる
3. 接続中のセッションでSELECT(インスタンス情報取得)を実行する
→たぶん実行できないので、いったんセッションを終了してインスタンスへ再接続する
4. インスタンスへ再接続
【想定】
セッションはフェイルオーバーされないが、SMONプロセスが再起動され、任意のインスタンスへ再接続できるはず
【検証結果】
インスタンスへ再接続できた
【作業ログ】
[oracle@node1 ~]$ sqlplus system/password@fuga
SQL> select instance_name from v$instance;
INSTANCE_NAME
------------------------------------------------
orcl2 ★インスタンス2へ接続中
※別セッションで接続中のセッション情報確認
SQL> select inst_id, username, sid, service_name, failover_type, failover_method, failed_over from gv$session where username='SYSTEM';
INST_ID USERNAME SID SERVICE_NAME FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER
---------- -------------------- ---------- -------------------- --------------------------------------- ------------------------------ -----------
2 SYSTEM 249 fuga NONE NONE NO
2. 接続先インスタンス(本検証ではインスタンス2)のSMONプロセスをキル
[root@node2 ~]# ps -ef | grep smon | grep -v grep
grid 3831 1 0 14:18 ? 00:00:00 asm_smon_+ASM2
root 3896 1 0 14:18 ? 00:00:20 /u01/app/12.1.0/grid/bin/osysmond.bin
oracle 4990 1 0 14:19 ? 00:00:00 ora_smon_orcl2
[root@node2 ~]# kill -9 4990
3. 接続中のセッションでSELECT(インスタンス情報取得)を実行
SQL> select instance_name from v$instance;
select instance_name from v$instance
*
行1でエラーが発生しました。:
ORA-03113: 通信チャネルでend-of-fileが検出されました プロセスID:
22335
セッションID: 249、シリアル番号: 14843
SQL> select instance_name from v$instance;
ERROR:
ORA-03114: Oracleに接続されていません。
4. インスタンスへ再接続
[oracle@node1 ~]$ sqlplus system/password@fuga
SQL> select instance_name from v$instance;
INSTANCE_NAME
------------------------------------------------
orcl1
★インスタンスへ再接続できた(たまたまorcl1ですが、ロードバランスでorcl1に接続されただけでフェイルオーバーされたわけではありません)
※別セッションで接続中のセッション情報確認
SQL> select inst_id, username, sid, service_name, failover_type, failover_method, failed_over from gv$session where username='SYSTEM';
INST_ID USERNAME SID SERVICE_NAME FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER
---------- -------------------- ---------- -------------------- --------------------------------------- ------------------------------ -----------
1 SYSTEM 260 fuga NONE NONE NO
②フェイルオーバータイプSESSIONの検証
疑似クライアントからfugaサービス(failovertype:SESSION)に接続後、接続先インスタンスで疑似障害を発生させ、セッションがフェイルオーバーされるか検証します
サービスの情報
[oracle@node1 ~]$ srvctl config service -db orcl -service fuga
サービス名: fuga
サーバー・プール:
カーディナリティ: 2
切断: false
サービス・ロール: PRIMARY
管理ポリシー: AUTOMATIC
DTPトランザクション: false
AQのHA通知: false
グローバル: false
コミット結果: false
フェイルオーバー・タイプ: SESSION
フェイルオーバー・メソッド: BASIC
TAFフェイルオーバー再試行: 180
TAFフェイルオーバー遅延: 5
接続ロード・バランシングの目標: LONG
ランタイム・ロード・バランシングの目標: NONE
TAFポリシー仕様: BASIC
エディション:
プラガブル・データベース名:
最大タイム・ラグ: ANY
SQL翻訳プロファイル:
保存時間: 86400秒
リプレイ開始時間: 300秒
セッション状態一貫性:
GSMフラグ: 0
サービスは有効です
優先インスタンス: orcl1,orcl2
使用可能なインスタンス:
【検証手順】
1. 疑似クライアントで「sqlplus system/XXXXX@fuga」を実行する
2. 接続先インスタンス(本検証ではインスタンス2)のSMONプロセスをキルして疑似障害を発生させる
3. 接続中のセッションでSELECT(インスタンス情報取得)を実行する
【想定】
セッションはフェイルオーバーされるはず(インスタンスへ再接続しなくてもSELECT(インスタンス情報取得)を実行できるはず)
【検証結果】
セッションはフェイルオーバーされた(インスタンスへ再接続しなくてもSELECT(インスタンス情報取得)を実行できた)
【作業ログ】
[oracle@node1 ~]$ sqlplus system/password@fuga
SQL> select instance_name from v$instance;
INSTANCE_NAME
------------------------------------------------
orcl2 ★インスタンス2へ接続中
※別セッションで接続中のセッション情報確認
SQL> select inst_id, username, sid, service_name, failover_type, failover_method, failed_over from gv$session where username='SYSTEM';
INST_ID USERNAME SID SERVICE_NAME FAILOVER_TYPE FAILOVER_METHOD FAILED_OV
---------- -------------------- ---------- -------------------- --------------------------------------- ------------------------------ ---------
2 SYSTEM 131 fuga SESSION BASIC NO
2. 接続先インスタンス(本検証ではインスタンス2)のSMONプロセスをキル
[root@node2 ~]# ps -ef | grep smon | grep -v grep
grid 3831 1 0 14:18 ? 00:00:00 asm_smon_+ASM2
root 3896 1 0 14:18 ? 00:00:30 /u01/app/12.1.0/grid/bin/osysmond.bin
oracle 23542 1 0 15:01 ? 00:00:00 ora_smon_orcl2
[root@node2 ~]# kill -9 23542
3. 接続中のセッションでSELECT(インスタンス情報取得)を実行
SQL> --kill直後
SQL> select instance_name from v$instance;
select instance_name from v$instance
*
行1でエラーが発生しました。:
ORA-25408: 安全にコールを再実行することはできません。
SQL> --killから5秒後(failoverdelayに指定した時間)
SQL> select instance_name from v$instance;
INSTANCE_NAME
------------------------------------------------
orcl1
★セッションがインスタンス1へフェイルオーバーしましたが、セッションは継続して使用可能
※別セッションで接続中のセッション情報確認
SQL> select inst_id, username, sid, service_name, failover_type, failover_method, failed_over from gv$session where username='SYSTEM';
INST_ID USERNAME SID SERVICE_NAME FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER
---------- -------------------- ---------- -------------------- --------------------------------------- ------------------------------ -----------
1 SYSTEM 370 fuga SESSION BASIC YES
★フェイルオーバーされたので「FAILED_OVER」列が「YES」に変わっています
③フェイルオーバータイプSELECTの検証
疑似クライアントからfugaサービス(failovertype:SELECT)に接続後、接続先インスタンスでSELECT(テストテーブルのフルスキャン)実行中に疑似障害を発生させ、セッションがフェイルオーバーされ、SELECT(テストテーブルのフルスキャン)が継続して実行されるか検証します
※事前にSELECT用のテストテーブル(約10MB)を作成しています
サービスの情報
[oracle@node1 ~]$ srvctl config service -db orcl -service fuga
サービス名: fuga
サーバー・プール:
カーディナリティ: 2
切断: false
サービス・ロール: PRIMARY
管理ポリシー: AUTOMATIC
DTPトランザクション: false
AQのHA通知: false
グローバル: false
コミット結果: false
フェイルオーバー・タイプ: SELECT
フェイルオーバー・メソッド: BASIC
TAFフェイルオーバー再試行: 180
TAFフェイルオーバー遅延: 5
接続ロード・バランシングの目標: LONG
ランタイム・ロード・バランシングの目標: NONE
TAFポリシー仕様: BASIC
エディション:
プラガブル・データベース名:
最大タイム・ラグ: ANY
SQL翻訳プロファイル:
保存時間: 86400秒
リプレイ開始時間: 300秒
セッション状態一貫性:
GSMフラグ: 0
サービスは有効です
優先インスタンス: orcl1,orcl2
使用可能なインスタンス:
【検証手順】
1. 疑似クライアントで「sqlplus system/XXXXX@fuga」を実行する
2. 接続中のセッションでテストテーブルをSELECTする
3. SELECT実行中の状態で、接続先インスタンス(本検証ではインスタンス2)のSMONプロセスをキルして疑似障害を発生させる
【想定】
セッションはフェイルオーバーされるはず(インスタンスへ再接続しなくてもテストテーブルのSELECTは継続されるはず)
【検証結果】
セッションはフェイルオーバーされた(インスタンスへ再接続しなくてもテストテーブルのSELECTは継続された)
【作業ログ】
[oracle@node1 ~]$ sqlplus system/password@fuga
SQL> select instance_name from v$instance;
INSTANCE_NAME
------------------------------------------------
orcl2 ★インスタンス2へ接続中
※別セッションで接続中のセッション情報確認
SQL> select inst_id, username, sid, service_name, failover_type, failover_method, failed_over from gv$session where username='SYSTEM';
INST_ID USERNAME SID SERVICE_NAME FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER
---------- -------------------- ---------- -------------------- --------------------------------------- ------------------------------ -----------
2 SYSTEM 372 fuga SELECT BASIC NO
2. 接続中のセッションでテストテーブルをSELECTする
SQL> select * from taf_test;
TEXT
----------------------------------------------------------------------------------------------------
DEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEAD
DEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEAD
DEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEAD
・
・
・
★SELECT完了まで10秒ぐらいかかります
3. SELECT実行中の状態で、接続先インスタンス(本検証ではインスタンス2)のSMONプロセスをキルして疑似障害を発生させる
[root@node2 ~]# ps -ef | grep smon | grep -v grep
grid 3831 1 0 14:18 ? 00:00:00 asm_smon_+ASM2
root 3896 1 0 14:18 ? 00:01:02 /u01/app/12.1.0/grid/bin/osysmond.bin
oracle 6662 1 0 15:51 ? 00:00:00 ora_smon_orcl2
[root@node2 ~]# kill -9 6662
※テストテーブルをSELECT中のセッション画面
・
・
・
DEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEAD
DEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEAD
DEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEADBEAFDEAD
60000行が選択されました。
SQL> select instance_name from v$instance;
INSTANCE_NAME
------------------------------------------------
orcl1
★セッションがインスタンス1へフェイルオーバーしましたが、テストテーブルのSELECTは継続されていました
※別セッションで接続中のセッション情報確認
SQL> select inst_id, username, sid, service_name, failover_type, failover_method, failed_over from gv$session where username='SYSTEM';
INST_ID USERNAME SID SERVICE_NAME FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER
---------- -------------------- ---------- -------------------- --------------------------------------- ------------------------------ -----------
1 SYSTEM 251 fuga SELECT BASIC YES
★フェイルオーバーされたので「FAILED_OVER」列が「YES」に変わっています
■おわりに
今回はTAF(透過的アプリケーションフェイルオーバー)の具体的な動きを確認することができました。
ただし、12c Release 1のため、AC(アプリケーション・コンティニュイティ:INSERT、UPDATE等のトランザクションの自動再実行)は検証できませんでした。
機会があれば検証してみようと思います。