サーバー制御ユーティリティでリスナーの環境変数を変更する（Oracle Database 19c)

Oracle Real Application Clusters 環境のリスナーは、Oracle Grid Infrastructure の一部として提供されます。このためリスナーの起動、停止はサーバー制御ユーティリティ（srvctl コマンド）を使って行います。本記事では Oracle Grid Infrastructure 環境のリスナーが使う環境変数を変更する方法について検証します。

# プロファイル構成ファイル
プロファイル構成ファイル（sqlnet.ora）は低レベルな通信設定パラメーターを指定するためのファイルです。クライアント用にもサーバー用にも使われますが、本記事ではリスナーが使う設定を扱います。sqlnet.ora ファイルで、最もよく使われる設定のひとつがリスナーに接続を許可するクライアントのTCP/IPアドレスの制限です。

|パラメーター名|説明|デフォルト値|
|:---|:---|:---|
|TCP.VALID_NODE_CHECKING|TCP/IPアドレスによる接続制限を行うか|OFF|
|TCP.INVITED_NODES|接続を許可するTCP/IPアドレス群|-|
|TCP.EXCLUDED_NODES|接続を許可しないTCP/IPアドレス群|-|

下記の例では 192.168.1.0/24 セグメントからの接続のみ許可しています。

```sqlnet.ora
TCP.VALIDNODE_CHECKING=yes
TCP.INVITED_NODES=(192.168.1.0/24)
```

このファイルは基本的に $ORACLE_HOME/network/admin ディレクトリに作成します。デフォルトでは sqlnet.ora ファイルの設定にはリスナー名の指定がありません。このため複数のリスナーが起動する環境ではリスナー単位にアドレス制限を設定できません。リスナー単位に sqlnet.ora ファイルの場所を変更するにはリスナー単位に環境変数 TNS_ADMIN を指定することで実現します。

# リスナーの追加
リスナーの追加は Oracle Grid Infrastructure 管理ユーザー（一般的には grid）権限で srvctl add listener コマンドを実行します。ここでは sqlnet.ora ファイルを保存するディレクトリを作成してから srvctl コマンドを実行します。Real Application Clusters 環境では各ノード上にディレクトリを作成します。以下の例では TCP ポート番号 1522 のリスナー「LISTENER2」を追加しています。

```shell:
$ mkdir $ORACLE_HOME/network/admin2
$ srvctl add listener -listener listener2 -endpoints "TCP:1522"
```

# リスナーの環境変数変更
リスナーの環境変数を変更するには srvctl setenv listener コマンドを実行します。以下の例では環境変数 TNS_ADMIN に対して先ほど作成したディレクトリ　/u01/app/19.0.0/grid/network/admin2/ を指定しています。確認には srvctl getenv listener コマンドを実行します。

```shell:
$ srvctl setenv listener -l listener2 -t "TNS_ADMIN=/u01/app/19.0.0/grid/network/admin2"
$ srvctl getenv listener -l listener2
LISTENER2:
TNS_ADMIN=/u01/app/19.0.0/grid/network/admin2
$
```

# リスナーの起動
リスナーの起動には srvctl start listener コマンドを実行します。以下の例ではノード rel83-2 でディレクトリの作成を忘れたためにエラーが発生しています。ディレクトリを作成後に再実行しています。

```shell:
$ srvctl start listener -l listener2
PRCR-1079 : Failed to start resource ora.LISTENER2.lsnr
CRS-5010: 構成ファイル"/u01/app/19.0.0/grid/network/admin2/listener.ora.new.rel83-2.grid"の更新に失敗しました: 詳細は(:CLSN00014:)(/u01/app/oracle/diag/crs/rel83-4/crs/trace/crsd_oraagent_grid.trc)を参照してください
CRS-2674: 'ora.LISTENER2.lsnr'('rel83-2')の起動に失敗しました
$ ssh rel83-2 mkdir $ORACLE_HOME/network/admin2
$ srvctl start listener -l listener2
```

リスナーが起動すると、環境変数 TNS_ADMIN で指定したディレクトリに　listner.ora ファイルが生成されます。

```shell:
$ cd $ORACLE_HOME/network/admin2
$ cat listener.ora
LISTENER2=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER2))))          # line added by Agent
ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER2=ON             # line added by Agent
VALID_NODE_CHECKING_REGISTRATION_LISTENER2=SUBNET               # line added by Agent
$
```

リスナー・プロセスの環境変数が正しく変更されているかを確認します。下記の例ではプロセスID 1376969 のリスナー・プロセスについて、環境変数 TNS_ADMIN が指定されたディレクトリに変更されていることが確認できます。

```shell:
$ ps -ef | grep LISTENER2 | grep -v grep
grid     1376979       1  0 23:17 ?        00:00:00 /u01/app/19.0.0/grid/bin/tnslsnr LISTENER2 -no_crs_notify -inherit
$ strings /proc/1376979/environ | grep TNS_ADMIN
TNS_ADMIN=/u01/app/19.0.0/grid/network/admin2
```

# 環境変数の変更
環境変数の削除は srvctl unset listener コマンドを実行します。以下の例では前述の環境変数を削除しています。設定していない環境変数を指定するとエラーになります。

```shell:
$ srvctl unsetenv listener -l listener2 -t "TNS_ADMIN"
$ srvctl unsetenv listener -l listener2 -t "HOME"
PRKO-3081 : No such environment variable setting: HOME
```

削除した環境変数は srvctl コマンドからは見えなくなりますが、稼働中のプロセスから削除されるわけではありません。このため srvctl setenv listener コマンドによる設定変更を有効にするにはリスナーの再起動が必要です。以下の例では再起動後に環境変数 TNS_ADMIN が元に戻っていることを確認しています。

```shell:
$ srvctl getenv listener -l listener2
LISTENER2:
$ ps -ef|grep LISTENER2 | grep -v grep
grid     1376979       1  0 Feb15 ?        00:00:00 /u01/app/19.0.0/grid/bin/tnslsnr LISTENER2 -no_crs_notify -inherit
$ strings /proc/1376979/environ | grep TNS_ADMIN
TNS_ADMIN=/u01/app/19.0.0/grid/network/admin2　←　起動中のリスナーの環境変数設定は残っている
$
$ srvctl stop listener -l listener2
$ srvctl start listener -l listener2
$ srvctl getenv listener -l listener2
LISTENER2:
$ ps -ef|grep LISTENER2 | grep -v grep
grid     1582162       1  0 08:51 ?        00:00:00 /u01/app/19.0.0/grid/bin/tnslsnr LISTENER2 -no_crs_notify -inherit
$ strings /proc/1582162/environ | grep TNS_ADMIN
TNS_ADMIN=/u01/app/19.0.0/grid/network/admin/
$
```

Author: Noriyoshi Shinoda / Date: February 16, 2023