【Oracle】ORA-03135の原因と解決方法|connection lost contact・Oracle接続が途中で切れる時の確認ポイント

【Oracle】ORA-03135の原因と解決方法|connection lost contact・Oracle接続が途中で切れる時の確認ポイント Oracle

ORA-03135: connection lost contact は、Oracleクライアントとデータベースサーバーの接続が途中で失われた時に発生するエラーです。接続時ではなく、SQL実行中、バッチ処理中、長時間アイドル後、DBリンク経由の処理中などに出ることがあります。

Oracle公式のエラーメッセージでは、サーバーが予期せず終了した、または接続がタイムアウトしたことが原因として説明されています。そのため、ORA-03135はSQL文だけを直すエラーではなく、DB側、ネットワーク側、アプリ側の接続管理を順番に切り分ける必要があります。

先に結論
ORA-03135が出たら、まず発生タイミングを見ます。接続直後なら接続設定やリスナー、長時間放置後ならアイドルタイムアウト、SQL実行中ならDBサーバー側のセッション終了、ネットワーク断、アプリ接続プールの古い接続を疑います。DBだけ、アプリだけで決めつけず、同じ時刻のアラートログ、リスナーログ、アプリログを突き合わせます。
スポンサーリンク

ORA-03135とは

ORA-03135は、Oracleとの通信が途中で切れたことを示します。たとえば、アプリが接続プールから古い接続を取り出した、ファイアウォールがアイドル接続を切断した、DBサーバープロセスが終了した、ネットワークが瞬断した、といった場合に発生します。

似たエラーに ORA-03113 があります。どちらも通信断に近いエラーですが、ORA-03135は「接続が失われた」という文脈で、アイドルタイムアウトやネットワーク機器による切断でもよく見ます。

長時間放置後に出る

ファイアウォール、ロードバランサ、NAT、接続プールのアイドルタイムアウトを疑います。

重いSQLの途中で出る

DBサーバープロセス終了、SQLタイムアウト、ネットワーク断、アプリ側キャンセルを確認します。

特定端末だけで出る

クライアント側のネットワーク、VPN、Oracle Client、sqlnet.ora、セキュリティソフトを確認します。

DBリンク経由で出る

ローカルDBとリモートDBの間のネットワーク、DBリンク接続先、相手側リスナーやタイムアウトを確認します。

よくある原因

サーバー側セッションが終了した

DBプロセスが強制終了、異常終了、タイムアウト終了した可能性があります。アラートログやトレースを確認します。

ファイアウォールがアイドル接続を切った

一定時間通信がないTCP接続をネットワーク機器が切断し、アプリ側は古い接続を使おうとしてORA-03135になります。

アプリの接続プールが古い接続を返した

検証なしでプール接続を再利用すると、既に切れた接続を使って失敗することがあります。

SQLNET.EXPIRE_TIMEが未設定

Oracle Net側の死活確認がなく、ネットワーク機器にアイドル接続として切られやすくなることがあります。

VPNや不安定なネットワーク

リモート接続、VPN、無線LAN、拠点間通信でパケットロスや瞬断があると発生しやすくなります。

まず確認すること

ORA-03135は原因範囲が広いため、発生状況を先に分けます。ログを探す前に、次の情報をそろえると調査が進みやすくなります。

  • 発生時刻
  • 接続元ホスト、アプリ名、ユーザー名
  • 接続直後か、長時間放置後か、SQL実行中か
  • 単発か、同じ時間帯に複数発生しているか
  • 特定端末、特定APサーバー、特定バッチだけか
  • DB側アラートログ、リスナーログ、アプリログに同時刻の記録があるか
時刻をそろえて見る
ORA-03135の調査では、DBサーバー、APサーバー、クライアント端末、ネットワーク機器の時刻差があると原因を追いにくくなります。ログを突き合わせる時は、タイムゾーンと時刻同期も確認してください。

DB側ログを確認する

同じ時刻にDB側でプロセス異常、セッション強制終了、DB再起動、ORA-00600、ORA-07445などが出ていないか確認します。アラートログやトレースファイルの場所は環境によって異なるため、ADRの場所を確認します。

check-diagnostic-dest.sql
SHOW PARAMETER diagnostic_dest;

SELECT name, value
FROM v$diag_info
WHERE name IN ('Diag Trace', 'Diag Alert');

リスナー側に接続切断や接続元情報が残る場合もあります。リスナーログの場所や読み方は リスナーログの記事、リスナー状態の確認は リスナー確認の記事 も参考になります。

listener-status.sh
lsnrctl status
lsnrctl services

最小構成で再現確認する

アプリ経由でだけORA-03135が出る場合、まずSQL*Plusなどの単純な接続で再現するかを確認します。アプリ、接続プール、ORM、APサーバーを外しても再現するなら、DBまたはネットワーク側の可能性が高まります。逆にSQL*Plusでは安定していてアプリだけで出るなら、接続プールやタイムアウト設定を重点的に見ます。

tnsping-and-sqlplus-test.sh
tnsping ORCLPDB1

sqlplus app_user/password@ORCLPDB1

-- 接続後、一定時間放置してから簡単なSQLを実行する
SELECT SYSDATE FROM dual;

接続識別子の解決で失敗する場合はORA-03135ではなく、ORA-12154 のような接続前エラーになることがあります。SQL*Plusの基本操作は SQL*Plusの記事 も参考になります。

セッション状態を確認する

発生中に確認できる場合は、対象ユーザーやAPサーバーのセッションが残っているかを見ます。ORA-03135が出た後はセッションが消えていることもあるため、再現する場合は発生前後で確認します。

check-session-by-client.sql
SELECT
    sid,
    serial#,
    username,
    status,
    machine,
    program,
    module,
    event,
    last_call_et
FROM v$session
WHERE username IS NOT NULL
ORDER BY last_call_et DESC;

セッション確認の基本は セッション確認・強制切断の記事 にまとめています。権限がない場合は、発生時刻、接続ユーザー、接続元ホスト、アプリ名をDBAに渡して確認してもらいます。

SQLNET.EXPIRE_TIMEを確認する

アイドル接続がネットワーク機器に切られている疑いがある場合、サーバー側の sqlnet.oraSQLNET.EXPIRE_TIME を確認します。これはOracle Netが一定間隔で接続確認を行う設定で、ファイアウォールなどに完全なアイドル接続と見なされにくくする目的で使われます。

sqlnet-expire-time.ora
SQLNET.EXPIRE_TIME = 10

値は分単位です。たとえば 10 なら10分間隔です。ただし、設定変更は全接続に影響するため、DBAと相談し、ネットワーク機器のアイドルタイムアウト値より短い間隔にするかを検討します。Oracleネットワーク設定全体は ネットワーク設定の記事 も参考になります。

アプリ側接続プールを確認する

WebアプリやバッチでORA-03135が出る場合、接続プールが切断済みの接続を返していないか確認します。プールから取り出す前の検証、アイドル接続の破棄、最大寿命、タイムアウト値が重要です。

接続検証

プールから借りる前に接続が生きているか確認します。検証SQLやドライバの検証機能を使います。

最大寿命

ネットワーク機器やDB側のタイムアウトより短い時間で接続を入れ替える設計にします。

アイドル破棄

長時間使われていない接続をプール内に残し続けないようにします。

リトライ設計

参照処理など安全に再実行できる処理は、接続再取得後のリトライを検討します。

connection-pool-checklist.txt
確認する設定例:
- connection validation / test on borrow
- idle timeout
- max lifetime
- connection timeout
- retry policy
- keepalive

Javaの接続プールでは、製品ごとに名前は違いますが、考えることはほぼ同じです。ネットワーク機器のアイドルタイムアウトより短い時間で接続を破棄し、借用時またはバックグラウンドで接続検証する設計にします。

hikaricp-example.properties
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.validation-timeout=5000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.keepalive-time=300000

# 実際の値はDB・ネットワーク機器・アプリ要件に合わせて調整する
接続プール設定は環境に合わせる
上の値は考え方を示す例です。ネットワーク機器のアイドルタイムアウト、DB側の制限、アプリの同時接続数、ドライバの仕様によって適切な値は変わります。本番では変更前後で接続数、待ち時間、エラー件数を監視してください。

ファイアウォール・ロードバランサを確認する

DBサーバーとAPサーバーの間にファイアウォール、NAT、ロードバランサ、VPNがある場合、TCPアイドルタイムアウトで接続が切られることがあります。典型的には、30分、60分、2時間など決まった時間放置した後、次のSQLでORA-03135が出ます。

毎回同じ放置時間で出る

ネットワーク機器や接続プールのアイドルタイムアウトが疑わしいです。

特定拠点だけで出る

拠点間VPN、プロキシ、セキュリティ機器、回線品質を確認します。

バッチ時間帯だけで出る

ネットワーク負荷、DB負荷、長時間SQL、ジョブのタイムアウトを合わせて確認します。

DBリンクだけで出る

ローカルDBからリモートDBまでの経路、相手側のタイムアウト、DBリンク先サービスを確認します。

DBリンクでORA-03135が出る場合

DBリンク経由の処理では、アプリからローカルDBへの接続だけでなく、ローカルDBからリモートDBへの接続も見ます。リモート側のリスナー、ネットワーク、DBリンク定義、相手側セッションのタイムアウトが原因になることがあります。

check-db-link.sql
SELECT owner, db_link, username, host, created
FROM dba_db_links
ORDER BY owner, db_link;

SELECT *
FROM dual@target_link;

DBリンクの作成や確認は データベースリンクの記事 を参照してください。DBリンクでは、ローカル側だけでなく相手側DBAやネットワーク担当者とのログ突き合わせが必要になることがあります。

似た接続エラーとの違い

Oracleの接続エラーは似た番号が多いため、発生タイミングで切り分けると分かりやすいです。ORA-03135は、接続後に途中で失われる文脈で見ることが多いです。

ORA-03135

接続が途中で失われました。サーバーセッション終了、タイムアウト、ネットワーク断、接続プールの古い接続を確認します。

ORA-03113

通信チャネルの終端です。DBプロセス異常、サーバー側エラー、強制終了なども含めて確認します。ORA-03135と同じくログ突き合わせが必要です。詳しくは ORA-03113の記事 を参照してください。

ORA-12154

接続識別子を解決できないエラーです。tnsnames.oraや接続文字列を確認します。詳しくは ORA-12154の記事 を参照してください。

ORA-12560

TNSプロトコル・アダプタエラーです。Windowsローカル接続やORACLE_SID、リスナー周りで見ます。詳しくは ORA-12560の記事 を参照してください。

SQL*Plus接続

SQL*Plusで再現確認する場合は、接続文字列や環境変数の違いも見ます。基本操作は SQL*Plusの記事 も参考になります。

対応手順まとめ

  1. 発生時刻、接続元、アプリ名、ユーザー名を確認する
  2. 接続直後、長時間放置後、SQL実行中、DBリンク経由のどれで出たか分類する
  3. SQL*Plusなど最小構成で再現するか確認する
  4. 同時刻のアラートログ、トレース、リスナーログ、アプリログを確認する
  5. 発生中なら V$SESSION で対象セッションの状態を確認する
  6. 長時間アイドル後なら、ファイアウォールや接続プールのアイドルタイムアウトを確認する
  7. SQLNET.EXPIRE_TIME の設定をDBAと確認する
  8. アプリの接続プールで接続検証、最大寿命、アイドル破棄を設定する
  9. DBリンク経由なら、相手側DBとネットワーク経路も含めて確認する

ORA-03135は、SQLを直せば必ず解決するタイプのエラーではありません。接続がどの時点で、どの経路で、誰によって切られたのかを追う必要があります。決まった時間放置後に出るならタイムアウト、SQL実行中に出るならDB側ログとネットワーク断、接続プール経由で出るなら古い接続の再利用を重点的に確認してください。

よくある質問

ORA-03135はDB障害ですか?

DB障害のこともありますが、ネットワーク機器のタイムアウトや接続プールの古い接続でも発生します。DB側ログとアプリログ、ネットワーク経路を合わせて確認します。

SQLNET.EXPIRE_TIMEを設定すれば直りますか?

アイドル接続の切断対策として有効なことがあります。ただし、アプリ接続プールの検証設定やネットワーク機器のタイムアウト値も合わせて確認が必要です。

長時間SQLの途中で出る場合は何を見ますか?

DB側アラートログ、トレース、セッション状態、SQLタイムアウト、ネットワーク断、APサーバー側のリクエストタイムアウトを確認します。

再実行してよいですか?

SELECTなら再実行しやすいですが、更新処理や外部連携を含むバッチでは、処理済み範囲とコミット状況を確認してから再実行します。

参考