Oracle接続を図解する＜動的サービス登録＞

##Oracleに接続するための「サービス登録」
Oracleに限らずデータベースは基本的に、何らかのクライアントからネットワーク経由で接続して利用されます。

クライアントからOracleデータベースに接続するにあたっては、
リスナープロセスがいったん接続要求を受け付けて、クライアントが要求する「サービス」の名前を見て、最終目的地であるインスタンス(データベース)に転送してくれます。
郵便に例えるなら「サービス名」は表札、名札のようなもの、「インスタンス(データベース)」は本当の宛先、おうちです。
そして「リスナー」は郵便配達人。

リスナーがクライアントの要求通りデータベースにリクエストを転送できるのは、
「どのサービスをどのOracleインスタンスが提供しているか」の情報を知っているからです。
言い換えると、どのおうちに、何という名前の名札がかかっているかを知っている、ということ。

これらのサービス(≒名札)の情報は、listener.oraファイルにあらかじめ書いておくか、動的にリスナーに登録する仕組みを利用することができます。
後者の仕組みは「動的サービス登録」と呼ばれます。

![listener_abstract.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468682/d01847ed-9caa-55a2-6524-e925977cd270.png)


##サービスとは

 * クライアントがインスタンスに接続するための名前
 * Oracleインスタンスが提供するサービスの名前(≒データベース名)


##動的サービス登録とは

 * インスタンスが、自身の担当しているサービスの情報をOracleリスナーに登録するための仕組み
 * 60秒間隔で動くLREGというプロセスが、初期化パラメータ「LOCAL_LISTENER」「REMOTE_LISTENER」で指定したネットワーク・アドレスに接続して、サービス情報を送信します

###動的サービス登録におけるサービス追加のイメージ
![service_add_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468682/62f0076a-90b2-6605-c4e9-f32ff9b0e81e.png)



 * 初期化パラメータ SERVICE_NAMES には、サービス名を複数定義することができます
 * 「サービス名」は、あるOracleインスタンス(データベース) に対して、名札をつけるイメージです。名札は１つだけでも、複数あっても構いません
 * 「サービス名」が名札なら、「リスナー」は郵便配達人に例えることができます
 * Oracleのバックグラウンド・プロセスの1つであるLREGプロセスが、データベースにかけられている1つ以上の「名札（サービス名）」の情報を「郵便配達人（リスナー）」にあらかじめ教えてあげることによって、クライアントから接続要求が届いたときに、「郵便配達人（リスナー）」は接続要求にかかれた「名札（サービス）」を読み取り、正しいデータベース宛に転送することができるようになります
 * クライアントは、複数あるサービス名のうち1つの名札を指定すれば、データベースに接続することができます


###「動的サービス登録」の行われるタイミング
* デフォルトでは、サービス情報を登録するLREG検出ルーチンは、60秒ごとに起動されます
* Oraleインスタンスの起動時や 「ALTER SYSTEM REGISTER ;」コマンドを発行することで、データベースから リスナー へとサービス名が通知されてリスナーの動的構成に使用されます

**Oracle Help Center：**
>リスナーの起動直後にALTER SYSTEM REGISTER文を実行するスクリプトを作成することをお薦めします。
https://docs.oracle.com/cd/E82638_01/riwin/database-init-parameters-for-service-registration.html#GUID-689D76EF-2E98-468D-90AF-B97AB6255821


### Oracleインスタンスにおけるサービス名の追加/確認方法
 * 初期化パラメータ「SERVICE_NAMES」を alter system コマンドで更新します
 * show parameter コマンドで現行値の確認ができます

```
SQL> alter system set service_names=orcl,orcl2;

システムが変更されました。

SQL> show parameter service_names

NAME                                 TYPE
------------------------------------ ----------------------
VALUE
------------------------------
service_names                        string
ORCL, ORCL2
SQL>
```

###「動的サービス登録」されたサービス名の確認

* 登録されたサービスの情報はファイルには記録されません
* サービスの登録状況は、lsnrctl status や lsnrctl service コマンド等で確認できます
* 下の「lsntctl services」コマンド出力に、「動的サービス登録」されている「orcl」「ORCL2」が出力されています
* 動的サービス登録されたインスタンスのうち、状態が「READY」であるものは接続受付可能とわかります

```
C:\Users\KANAKOUTSUMI>lsnrctl services

LSNRCTL for 64-bit Windows: Version 19.0.0.0.0 - Production on 05-8月 -2019 19:15:59

Copyright (c) 1991, 2019, Oracle.  All rights reserved.

(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=DESKTOP-5RC350R)(PORT=1521)))に接続中
サービスのサマリー...
サービス"CLRExtProc"には、1件のインスタンスがあります。
  インスタンス"CLRExtProc"、状態UNKNOWNには、このサービスに対する1件のハンドラがあります...
    ハンドラ:
      "DEDICATED" 確立:0 拒否:0
         LOCAL SERVER
サービス"ORCL2"には、1件のインスタンスがあります。
  インスタンス"orcl"、状態READYには、このサービスに対する1件のハンドラがあります...
    ハンドラ:
      "DEDICATED" 確立:0 拒否:0 状態:ready
         LOCAL SERVER
サービス"orcl"には、1件のインスタンスがあります。
  インスタンス"orcl"、状態READYには、このサービスに対する1件のハンドラがあります...
    ハンドラ:
      "DEDICATED" 確立:0 拒否:0 状態:ready
         LOCAL SERVER
サービス"orclXDB"には、1件のインスタンスがあります。
  インスタンス"orcl"、状態READYには、このサービスに対する1件のハンドラがあります...
    ハンドラ:
      "D000" 確立:0 拒否:0 現行:0 最大:1022 状態:ready
         DISPATCHER <machine: DESKTOP-5RC350R, pid: 3288>
         (ADDRESS=(PROTOCOL=tcp)(HOST=DESKTOP-5RC350R)(PORT=54124))
コマンドは正常に終了しました。

C:\Users\KANAKOUTSUMI>

```

###インスタンスの「状態」

「状態」フィールドは、インスタンスが接続を受け入れられるかどうかを示します。
動的サービス登録されている場合は、UNKNOWN以外のいずれかの状態が表示されます。

 * READYは、インスタンスが接続を受け入れられることを意味します。
 * BLOCKEDは、インスタンスが接続を受け入れられないことを意味します。
 * READY/SECONDARYは、これがOracle Real Application Clustersのプライマリ/セカンダリ構成のセカンダリ・インスタンスであり、接続を受け入れられることを意味しています。
 * RESTRICTEDは、そのインスタンスが制約のあるモードであることを示しています。リスナーは、このインスタンスへの接続をすべて阻止します。
 * UNKNOWNは、インスタンスが、サービス登録を使用して動的に登録されているのではなく、listener.oraファイルに静的に登録されていることを意味します。このため、ステータスは不明です。

###サービス登録に関わる構成情報
* LREGがサービス登録の時の接続先アドレスとして認識する「LOCAL_LISTENER」のネットワークアドレスは、デフォルトではサーバ側の tnsnames.ora ファイルに記述されています
* (初期化パラメータ「LOCAL_LISTENER」の値としてネットワークアドレスを直接書いても良い)

【tnsnames.ora抜粋】

```
LISTENER_ORCL =
  (ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-5RC350R)(PORT = 1521))
```


<BR>
<BR>

「静的な登録」の方法は[「Orace接続＜静的なサービス登録＞」](https://qiita.com/mi-kana/items/6b1a39736df30ab21e35)に書きました。