トップ > DBA上級 RAC > 10章
10章 サービス 基本編
本章ではRACのデータベースサービスについてご紹介していきます。

RACは複数インスタンス(複数ノード)存在していますが、
どのノードに接続するかは意識することはありません。

これはサービスを使用しており、サービスを使用して接続すれば、
Oracleが自動的にサーバ負荷状況から適切なノードに振り分けるようにしています。

この章ではサービスの役割と作成方法などの管理についてご紹介していきます。



サービスの役割


アプリケーションがRAC環境に接続するとき、複数あるインスタンスのどのインスタンスに
接続するのでしょうか。

インスタンス障害で接続できない場合、別のノードにフェイルオーバーしたり、
複数ノードの負荷の低いノードに接続させたりとアプリケーション側で考慮することがあります。

アプリケーションからのRAC DB接続
できればアプリケーション側はフェイルオーバーやロードバランスは意識しないで接続できることが
理想です。

RAC環境ではサービスと言うインスタンスのグループ化機能を使用すると
特にアプリケーション側は特にサービス名を使用して接続するだけで、
そのグループ内のインスタンスに接続を振り分けてくれます

以下のようにサービスは複数作成できるので用途別に接続するインスタンスを分けることも出来ます。

サービスを使用した接続インスタンスの振り分け

上記はBATと言うサービスはノード1,2のインスタンスを優先インスタンスで作成し、
OLTPと言うサービスはノード3,4のインスタンスを優先インスタンスで作成しています。

優先インスタンスとは優先的に使用するインスタンスです。その他に使用可能インスタンスがあり、
優先インスタンスが障害時に使用可能となるインスタンスです。

優先インスタンスが複数存在する場合は、複数のインスタンスを使用し、
1つのインスタンスに障害があった場合は、残りの優先インスタンスに接続します。

サービスを使用した接続インスタンスの振り分け

また使用可能インスタンスを含めてサービスを作成した場合は、通常は優先インスタンスに
接続しますが、障害時は使用可能が優先インスタンスに変わり、優先インスタンスの数を
保とうとします。

サービスを使用した接続インスタンスの振り分け

サービスを使用した接続インスタンスの振り分け

上記ではORCL01,02が優先インスタンス、ORCL03,04が使用可能インスタンスで
OLTPというサービスを作成しています。
その後、ORCL01インスタンスで障害が発生した為、ORCL03が優先に自動的に切り替ります。

また以下のようにアプリケーション側は意識しなくてもロードバランスを行うことも出来ます。

サービスを使用したロードバランス


サービスの作成


サービスの作成には以下の方法で作成できます。

・Enteprise Manager
・srvctl
・DBMS_SERVICE

DBMS_SERVICEのパッケージを使用して作成することは可能ですが、
データディクショナリにサービスが登録されないなどRAC環境ではお薦めしません。

今回はsrvctlコマンドを使用したサービスの作成方法を確認していきます。
また今回の環境は管理者管理のデータベースです。
ポリシー管理のサービス作成は紹介しません。次回ご紹介したいと思います。
その他の内容についてはマニュアルを参照してください。

Oracle Real Application Clusters管理およびデプロイメント・ガイド

[構文] サービスの作成
 $ srvctl add service -database DB名 -s サービス名
 -preferred 優先インスタンス [-available 使用可能インスタンス]


サービス作成の基本コマンドはシンプルです。優先インスタンスを指定し、
必要があれば使用可能インスタンスの設定を行います。

優先インスタンスは優先的に接続するインスタンスで、
使用可能インスタンスは優先インスタンスに障害が発生した場合、
使用する予備のインスタンスです。

以下の図のように複数のサービスを作成できるため、
用途に分けて接続するインスタンスを決めることが出来ます。

サービスを使用したRAC DB接続
上記はBATと言うサービスはノード1,2のインスタンスを優先インスタンスで作成し、 OLTPと言うサービスはノード3,4のインスタンスを優先インスタンスで作成しています。

サービスを使用したRAC DB接続

プラガブルデータベースの場合、上記はCDBに接続する為のサービスとなってしまうので、
その場合は、-pdbオプションでPDB名を指定します。

上記以外のオプションもありますが、基本的なサービスを作成オプションのみ記載しています。

[構文] サービスの削除
 $ srvctl remove service -d DB名 -s サービス名
※-dは-dbでも可能です。

サービスの削除はサービスを停止してから実施する必要があります。

[構文] サービスの起動/停止
 $ srvctl [start|stop] service -d DB名 -s サービス名

それではサービスを作成してみます。

   $ srvctl add service -d orcl -s test1 -preferred orcl01,orcl02

   $ crsctl stat res -t -w "TYPE = ora.service.type "
   ----------------------------------------------------------------------------
   Name           Target  State        Server                   State details
   ----------------------------------------------------------------------------
   Cluster Resources
   ----------------------------------------------------------------------------
   ora.orcl.test1.svc
         1        OFFLINE OFFLINE                               STABLE
         2        OFFLINE OFFLINE                               STABLE
   ----------------------------------------------------------------------------


サービスの構成は優先インスタンス orcl01,orcl02のCDBに接続するサービスです。
では起動してみます。

   $ srvctl start service -d orcl -s test1
   $ crsctl stat res -t -w "TYPE = ora.service.type "
   ----------------------------------------------------------------------------
   Name           Target  State        Server                   State details
   ----------------------------------------------------------------------------
   Cluster Resources
   ----------------------------------------------------------------------------
   ora.orcl.test1.svc
         1        ONLINE  ONLINE       rac01                    STABLE
         2        ONLINE  ONLINE       rac02                    STABLE
   ----------------------------------------------------------------------------

   $ lsnrctl service

   LSNRCTL for Linux: Version 12.2.0.1.0 - Production on 16-FEB-2018 16:38:32

   ・・・省略・・・
   Service "test1" has 1 instance(s).
     Instance "orcl01", status READY, has 1 handler(s) for this service...
       Handler(s):
         "DEDICATED" established:0 refused:0 state:ready
            LOCAL SERVER
   The command completed successfully


次にサービスの構成は優先インスタンス orcl01,orcl02のCDBに接続するサービスです。
サービスが起動しました。リスナーもtest1サービスを認識しています。
ではtest1で接続してみます。test1は両インスタンスに接続できます。

    $ sqlplus system/manager@scan.oracle12c.jp:1521/test1

    SQL> select instance_name,host_name from v$instance;

    INSTANCE_NAME    HOST_NAME
    ---------------- --------------------------------------------------------
    orcl02           rac02.oracle12c.jp


今回はorcl02(ノード2)に接続されました。もう一度試しに再接続してみます。

   SQL> conn system/manager@scan.oracle12c.jp:1521/test1
   Connected.

   SQL> select instance_name,host_name from v$instance;

   INSTANCE_NAME    HOST_NAME
   ---------------- --------------------------------------------------------
   orcl01           rac01.oracle12c.jp


今度はorcl01(ノード1)に接続されました。
両方のインスタンスが優先インスタンスなので想定どおりですね。

次に優先インスタンス orcl01, 使用可能インスタンスorcl02 CDBに
接続するサービスを作成します。

今度は使用可能インスタンスも含めたサービスを作成してみます。

   $ srvctl add service -d orcl -s test2 -preferred orcl01 -available orcl02
   $ crsctl stat res -t -w " TYPE = ora.service.type"
   ----------------------------------------------------------------------------
   Name           Target  State        Server                   State details
   ----------------------------------------------------------------------------
   Cluster Resources
   ----------------------------------------------------------------------------
   ora.orcl.test1.svc
         1        ONLINE  ONLINE       rac01                    STABLE
         2        ONLINE  ONLINE       rac02                    STABLE
   ora.orcl.test2.svc
         1        OFFLINE OFFLINE                               STABLE
   ----------------------------------------------------------------------------

   $ srvctl start service -d orcl -s test2

   $ crsctl stat res -t -w " TYPE = ora.service.type"
   -------------------------------------------------------------------------
   Name           Target  State        Server                   State details
   -------------------------------------------------------------------------
   Cluster Resources
   -------------------------------------------------------------------------
   ora.orcl.test1.svc
         1        ONLINE  ONLINE       rac01                    STABLE
         2        ONLINE  ONLINE       rac02                    STABLE
   ora.orcl.test2.svc
         1        ONLINE  ONLINE       rac01                    STABLE
   -------------------------------------------------------------------------



test2サービスが作成され、優先インスタンスであるrac01ノードで起動しています。


   $ sqlplus system/manager@scan.oracle12c.jp:1521/test2

   INSTANCE_NAME    HOST_NAME
   ---------------- ------------------------------------------------------
   orcl01           rac01.oracle12c.jp

   SQL> conn system/manager@scan.oracle12c.jp:1521/test2
   Connected.

   SQL> select instance_name,host_name from v$instance;

   INSTANCE_NAME    HOST_NAME
   ---------------- ------------------------------------------------------
   orcl01           rac01.oracle12c.jp


test2のサービスは何回接続してもorcl01(ノード1)に接続します。
ではSMONプロセスをKILLしてインスタンス障害を発生させてみましょう。

サービスはインスタンス障害などが発生すると使用可能インスタンスにサービスを
フェイルオーバーします。
インスタンスはクラスタウェアにより障害が検知され、自動的に起動してきます。


   $ crsctl stat res -t -w " TYPE = ora.service.type"
   ----------------------------------------------------------------------
   Name           Target  State        Server         State details
   ----------------------------------------------------------------------
   Cluster Resources
   ----------------------------------------------------------------------
   ora.orcl.test1.svc
         1        ONLINE  ONLINE       rac01          STABLE
         2        ONLINE  ONLINE       rac02          STABLE
   ora.orcl.test2.svc
         1        ONLINE  ONLINE       rac01          STABLE
   ----------------------------------------------------------------------

   $ ps -ef | grep smon
   oracle    1835 31695  0 17:34 pts/1    00:00:00 grep smon
   grid      7981     1  0 10:20 ?        00:00:00 asm_smon_+ASM1
   root      8061     1  1 10:20 ?        00:04:37 /u01/app/12.2.0/grid/bin/osysmond.bin
   grid     10156     1  0 10:22 ?        00:00:00 mdb_smon_-MGMTDB
   oracle   13187     1  0 10:24 ?        00:00:00 ora_smon_orcl01

   $ kill -9 13187

SMONをKILLしたため、インスタンス障害が発生しました。

  $ crsctl stat res -t -w " TYPE = ora.service.type"
   ---------------------------------------------------------------------------
   Name           Target  State        Server                   State details
   ---------------------------------------------------------------------------
   Cluster Resources
   ---------------------------------------------------------------------------
   ora.orcl.test1.svc
         1        ONLINE  OFFLINE                               STABLE
         2        ONLINE  ONLINE       rac02                    STABLE
   ora.orcl.test2.svc
         1        ONLINE  ONLINE       rac02                    STABLE
   ---------------------------------------------------------------------------

test2のサービスはrac02へフェイルオーバーしています。
test1はrac01のサービスはOFFLINEとなっています。


   $ crsctl stat res -t -w " TYPE = ora.service.type"
   ---------------------------------------------------------------------------
   Name           Target  State        Server                   State details
   ---------------------------------------------------------------------------
   Cluster Resources
   ---------------------------------------------------------------------------
   ora.orcl.test1.svc
         1        ONLINE  ONLINE       rac01                    STABLE
         2        ONLINE  ONLINE       rac02                    STABLE
   ora.orcl.test2.svc
         1        ONLINE  ONLINE       rac02                    STABLE
   ---------------------------------------------------------------------------

インスタンスが起動してきたらtest1のrac01側もまたONLINEに戻っています。
test2はインスタンスが起動してもrac02のままです。

こちらが使用可能インスタンスを設定した場合の動作です。
またrac01側に戻したい場合は、サービスの再配置が必要です。


サービスの再配置


サービスは一度別のノードに切替るとそのノードが障害発生するまで同じノードで起動し続けます。
サービスを再度別ノードに配置したり、優先インスタンスに戻したい場合は再配置が必要です。

[構文] サービスの再配置
 $ srvctl relocate service -d DB名 -s サービス名
 -t 移動先インスタンス名 -i 移動元インスタンス名 [-f]

-fオプションは移動元のインスタンスのセッションをすべてKILLしてから切替を行います。
ではサービスを再配置してみます。

   $ crsctl stat res -t -w " TYPE = ora.service.type"
   --------------------------------------------------------------------------------
   Name           Target  State        Server                   State details
   --------------------------------------------------------------------------------
   Cluster Resources
   --------------------------------------------------------------------------------
   ora.orcl.test1.svc
         1        ONLINE  ONLINE       rac01                    STABLE
         2        ONLINE  ONLINE       rac02                    STABLE
   ora.orcl.test2.svc
         1        ONLINE  ONLINE       rac02                    STABLE
   --------------------------------------------------------------------------------

   $ srvctl relocate service -d orcl -s test2 -t orcl01 -i orcl02

   $ crsctl stat res -t -w " TYPE = ora.service.type"
   --------------------------------------------------------------------------------
   Name           Target  State        Server                   State details
   --------------------------------------------------------------------------------
   Cluster Resources
   --------------------------------------------------------------------------------
   ora.orcl.test1.svc
         1        ONLINE  ONLINE       rac01                    STABLE
         2        ONLINE  ONLINE       rac02                    STABLE
   ora.orcl.test2.svc
         2        ONLINE  ONLINE       rac01                    STABLE
   --------------------------------------------------------------------------------

サービスがrac01に戻りました。-fは既存のセッションを終了させてから再配置なので、
本番環境で実施した場合、既存セッションが切断されるので気をつけて実施してください。


以上がサービスについてのご紹介となります。次章ももう少しサービスについてご紹介していきます。