2007年7月27日

ORA-12571: TNS: パケット・ライターに障害が発生しました

 某所でOracleを使っていると、たまに表題のエラーが出る。「ORA-12571」でググって見ると、謎の現象で解決しない例が多く見られる。

 原因がさまざまであり、対策もさまざまなのだろう。

 ここの環境では、一定時間通信しなかったあとでクエリを投げると出るようだ。

 これはどうも、DBサーバまでの間にあるファイアウォールがTCPコネクションを切断してしまうため出ているようだ。

 ファイアウォールではNATしているので、NATテーブルの飽和を防ぐために、一定時間アイドルだったTCPコネクションをNATテーブルから消してしまう。

 また、NATしていなくても、TCPセッションハイジャックなどのリスクから回避するために、SPIでフィルタしてしまっているなんていう環境もあったりするだろう。

 ネットワーク環境的な回避方法だと、キャッシュ時間を延ばす方法が考えられるが、むやみやたらと長時間にするわけにもいかない。


 そこでクライアント側の設定での回避策。(3階層アプリならWebサーバでの設定)

 TNSNAMES.ORA に (ENABLE = BROKEN) を追加する。追加する場所は以下のとおり。

HOGE =
(DESCRIPTION =
(ENABLE = BROKEN)
(ADDRESS_LIST = 〜

 それに加えて、レジストリをいじってTCP KeepAlive パケットの送出間隔を短くする。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
KeepAliveTime DWORD:0x493E0

 ここで設定する値の単位は ms.

 上記の 0x493E0 の場合は 300000msで 300秒で、すなわち5分。これは間にあるファイアウォールのNATテーブルタイムアウト時間より短い値に設定する。

 利用者(ファイアウォール配下の端末数)が少なければ、1分とかでも問題ないだろう。それ以下にするのはちと勿体無い感じがする。

 ちなみにデフォルト値は2時間だ。長すぎる。

 これらの設定を組み合わせることにより、設定した間隔でKeepAliveパケットが流れるので、ファイアウォールがタイムアウトで切断してしまう現象が出なくなる。

 さて、例によって定型文。レジストリの書き換えは自己責任で。書き換え後は再起動が必要。

Posted by rukihena at 00:07:26
トラックバックURL

このエントリーのトラックバックURL:
http://weblog.rukihena.com/mt/mt-tb.cgi/704

コメント