Oracleの接続の切断/停止を検出する方法は?
-
07-07-2019 - |
質問
server / client-setupで、奇妙な動作が発生しています。クライアントは、OCIを使用してOracleサーバーに接続するC / C ++アプリケーションです( OTL ライブラリを使用) 。
DBサーバーは時々死にます(はい、これがコアの問題ですが、アプリケーション側からは解決できませんが、とにかく対処する必要があります)、マシンはもう応答しません新しいリクエスト/接続への接続。ただし、Oracle接続などの既存の接続はドロップまたはタイムアウトしません。 DBに送信されたクエリが正常に返されることはありません。
クライアントアプリケーション側からのこれらのストールされた接続を検出し、多かれ少なかれ安全な方法で回復するために、オラクルはどのような可能性を提供しますか(もしあれば)?
解決
これは11.1.0.6までのOracleのバグ(または機能と呼ばれます)であり、修正を含むOracle 11gリリース1(パッチ11.1.0.7)のパッチについて述べていました。それを見る必要があります。 その場合は、このアクションを実行しているスレッドをキャンセル(kill)する必要があります。 しかし、良いアプローチではありません
他のヒント
すべてのDBスキーマには、1つの定数レコードを持つテーブルがあります。単純なSQL要求により、このようなテーブルを定期的にポーリングするだけです。他のすべての方法は信頼できません。
これに役立つ可能性のあるOTLには set_timeout
APIがあります。
編集:実際、それは無視してください。 set_timeout
はOCIでは機能しません。 こちらの set_timeout
の説明をご覧ください。 OCIで使用できるテクニック
データベースへのクエリを実行する必要があるように思えます(例: SELECT * FROM dual;
)。指定された時間内にデータベースが応答しない場合は、サーバーが死亡し、それに応じて反応します。 C / C ++を知らないのではないかと思いますが、マルチスレッドを使用してステートメントを起動し、アプリケーションをハングさせずに応答を待つことができますか?
これは動作します-あなたが探しているものを正確に実行しました。 親プロセス(A)に子プロセス(B)を作成させます。子プロセス(B)はデータベースに接続し、 クエリを実行します( "select 1 from a_table" "のようなもの-これに"デュアル "を使用せずに独自のテーブルを作成するとパフォーマンスが向上します)。 (B)が成功した場合、成功したことを書き出して終了します。 (A)は指定された時間待機しています。 15秒使用しました。 (A)が(B)がまだ実行中であることを検出した場合-データベースがハングしていると見なすことができます-それは(B)を強制終了し、必要なアクションを実行します(SMSで電話で私に電話するように)
タイムアウトを使用するようにSQL * NETを構成すると、おそらくそれが原因で大きなクエリが失敗することに気付くでしょう。 OCI set_timeout構成もこれを引き起こします。
これを手動で回避する方法があります。ファイアウォールを開いて、指定された期間ごとにデータベースにpingなどを行うことができます。これにより、データベース接続が失われることはありません。
idea
If (current_time - lastPingTime > configuredPingTime)
{
//Dummy query
select 1 from dual;
}