Oracle DatabaseのKeepAlive設定について
対応バージョン
10.1 - 12.2
2017-04-04記事公開
Oracle Databaseにおけるクライアント及びサーバのKeepAlive機能について説明します。クライアントがサーバからのエラーが受け取れず、ハングしてしまう場合などの回避に利用できる機能です。
KeepAlive(キープアライブ)について
KeepAliveとは
KeepAliveとはネットワーク接続が有効であるか確認するために、定期的に行われる通信のことを指します。
接続先がハングや強制停止された時にエラーを戻さなかった場合でも、接続元からの定期的なチェックにより、エラーとして検知できるようになります。
また、長時間応答待ちを行うSQLの待機中でも、KeepAliveのパケットが一定間隔で送信されます。そのため、非アクティブ状態が一定時間続いた場合に強制切断する設定を入れている環境での、意図しない切断の回避などにも有効です。
クライアント側のKeepAliveの設定について
デフォルトの動作について
クライアントからの要求に対してデータベースから応答がない場合、クライアントは待機を続けます。データベース側の終了を連絡するパケットが届かずにサーバプロセスが停止した場合でも、クライアントは待機を続けるため、デフォルトの設定ではそのままハングアップしたような状態となります。
例としては以下のような状況があります。
- Javaクライアントがデータベースに接続を確立します。
- クライアントからデータベースへSQLを発行し、データを要求します。
- データ要求中にケーブル断線し、接続が無効となります。
- サーバプロセスが強制終了します。
- 強制終了時にエラーのパケットをクライアントに飛ばしますが、失敗します。
- クライアントはエラーに気づかずデータ要求の結果を待ち続けます。
KeepAliveの利用による効果
KeepAliveの機能を利用することにより、接続先が無効であるか定期的に確認し、無効である場合にエラー(ORA-03113)を戻すことが出来ます。
KeepAliveは接続先が終了済みであることや、応答しないことに対してエラーと判断するため、単純に待機状態やIdle状態であるプロセスに関して切断するようなものではありません。
KeepAliveの設定
tnsnames.oraにENABLE=brokenを追加することで、追加したエントリを使用したクライアント接続時、TCP転送のKeepAlive機能を有効にします。
1 2 3 4 5 6 |
net_service_name= (DESCRIPTION= (ENABLE=broken) (ADDRESS=(PROTOCOL=tcp)(HOST=sales1-svr)(PORT=1521)) (ADDRESS=(PROTOCOL=tcp)(HOST=sales2-svr)(PORT=1521))) (CONNECT_DATA=(SERVICE_NAME=sales.us.example.com)) |
参考資料
Oracle(R) Database Net Servicesリファレンス
12c リリース2 (12.2)
E72891-02
6 tnsnames.oraファイル内のローカル・ネーミング・パラメータ
6.8 アドレス・リストのオプション・パラメータ
6.8.1 ENABLE
https://docs.oracle.com/cd/E82638_01/NETRF/local-naming-parameters-in-tnsnames-ora-file.htm#GUID-7A18022A-E40D-4880-B3CE-7EE9864756CA
KeepAliveのチェック間隔値変更
KeepAliveの通信時間の間隔は、OSの設定に準拠します。例えば、Oracle Linux 6では、以下カーネルパラメータによりkeepaliveの設定値を変更します。
※ KeepAliveの設定方法はOSによって異なります。
現在値の確認
1 2 3 4 |
# sysctl -a | grep keepalive net.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_keepalive_probes = 9 |
- 7200秒に1回死活確認(プローブ・パケットの送信)を行う
(net.ipv4.tcp_keepalive_time) - 応答がなかった場合、75秒で確認を繰り返す
(net.ipv4.tcp_keepalive_intvl) - 75秒を9回繰り返して応答がなかった場合、接続を無効とみなす
(net.ipv4.tcp_keepalive_probes)
※接続を無効とみなすまでの最大間隔(秒) = 7200 + ( 75 * 9 )
試行間隔なので、毎回ピッタリこの時間というわけではありません。
設定の変更
1 2 3 4 5 6 |
# vi /etc/sysctl.conf # 以下の記載を追記 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_probes = 9 net.ipv4.tcp_keepalive_intvl = 75 |
設定の反映と確認
1 2 |
# sysctl -p # sysctl -a | grep keepalive |
データベースサーバ側のKeepAliveの設定について
データベースサーバのKeepAlive設定
データベースサーバー側(サーバプロセス)の設定は、デフォルトでOSのKeepAliveが適用されています。
sqlnet.oraに SQLNET.EXPIRE_TIME が設定されている場合はそちらが優先されます。 SQLNET.EXPIRE_TIME に指定した数値(分単位)の間隔で、KeepAlive(プローブ・パケットの送信)を実行します。
チェック間隔を短くする場合、特にプロセス数が多い場合などはネットワークへの負荷が微量なりとも増加するため、パフォーマンスにも気を付ける必要があります。
参考資料
Oracle(R) Database Net Servicesリファレンス
12c リリース2 (12.2)
E72891-02
5 sqlnet.oraファイルのパラメータ
5.2 プロファイル・パラメータ(sqlnet.ora)
5.2.35 SQLNET.EXPIRE_TIME
https://docs.oracle.com/cd/E82638_01/NETRF/parameters-for-the-sqlnet-ora-file.htm#GUID-1070805B-0703-457C-8D2E-4EEC26193E5F
データベースサーバにおいても、クライアントとして利用する場合は、クライアント側と同一の設定が必要です。例えばtnsnames.oraのエントリを利用して接続するSQL*Plusのプロセスや、データベースサーバから別のデータベースへ接続するDBLINKのプロセスが対象となります。
接続に利用しているtnsnames.oraのエントリに"ENABLE=broken"が記述されている場合、OSのKeepAlive設定値が適用されます。先述した通り、この時のクライアント側のKeepAliveと、データベースサーバ側のデフォルトのKeepAliveは、OSのKeepAliveの設定値を利用しているため、チェック間隔値が共有されていることに気を付けてください。
OSのKeepAliveの設定については、クライアント側の設定と同一のため割愛します。