忘れかけのIT備忘録

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

サービスのTAF(透過的アプリケーションフェイルオーバー)検証

サービスの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プロセスが再起動され、任意のインスタンスへ再接続できるはず

【検証結果】
インスタンスへ再接続できた

【作業ログ】

1. 疑似クライアントからインスタンスへ接続
[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(インスタンス情報取得)を実行できた)

【作業ログ】

1. 疑似クライアントからインスタンスへ接続
[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は継続された)

【作業ログ】

1. 疑似クライアントからインスタンスへ接続
[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等のトランザクションの自動再実行)は検証できませんでした。
機会があれば検証してみようと思います。