C#.NET4アプリケーションを古い32ビットのWindows2003Serverから新しい64ビットのWindows2008Serverに移行した後、非常に奇妙なエラーが発生します。何が起こっているのかを知るために一週間を費やしましたが、アイデアが足りなくなったので、アドバイスをお願いします。
詳細:
リモートのOracleデータベースサーバーからデータを抽出する小さなC#.NET4.0アプリケーションがあります。このアプリケーションは、古い32ビットのWindows2003Serverで正常に動作していました。前回は、64ビットのWindows 2008R2Serverを搭載した新しいサーバーに移動する必要がありました。それ以降、約500k行を返すOracleデータベースへの1つのクエリが正しく機能していません。開始から約2分後、次のような例外がスローされます。
ORA-03113:通信チャネルのファイルの終わり
プロセスID:0
セッションID:288シリアル番号:43544
64ビットシステム用の最新のODACドライバーをOracleサイトからダウンロードしました:64ビットODAC 11.2リリース5(11.2.0.3.20)。インストーラーバージョンとXCOPYバージョンの両方を試しました。ODP.NET4の.batファイルを介したインストールと構成。TNSは正しく設定されています。
リモートOracleデータベースは他の国にあります。私はその管理者ではありません。Oracle9i EE、64ビット、v9.2.0.8.0です。
テスト用の私のC#アプリケーションは次のようになります。
using (OracleConnection conn = new OracleConnection("User Id=userId; Password=pass; Data Source=database;"))
{
conn.Open();
string sql = "SELECT * FROM table";
int i = 0;
using (OracleCommand cmd = new OracleCommand(sql, conn))
{
using (OracleDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
if (i++ % 100 == 0)
{
Console.WriteLine(i);
}
}
}
}
}
私は使用Adapter.Fill(dataTable)
しましたが、データリーダーをテストする方が優れています-何かが起こっているときに多かれ少なかれ表示されます。
ODP.NETディレクトリ(64ビットまたは32ビット)のOracle.DataAccess.dllを使用しています。アプリケーションは任意のCPU用にコンパイルされますが、x64およびx86のコンパイルも試しました(適切なOracle.DataAccess.dllライブラリを使用)。
タイムアウトになる可能性があると考えていたので、次のようなさまざまな接続文字列オプションを試しました。
検証接続=true
接続ライフタイム=600;接続タイムアウト=600;
Pooling = false
Enlist = false;
コマンドCommandTimeoutを600に設定しました。
アプリケーションは、サーバーの負荷に応じて、200kから300kまで異なる数の行をダウンロードし、ORA-03113例外をスローします。約120秒かかります(ただし、正確ではなく、130秒になることもあれば、それ以上になることもありますが、ほとんどの場合、約120秒かかります)。
奇妙なことに、クエリがエラーなしで正常に終了し、500k行すべてがダウンロードされることがあります。たとえば、今日、約30〜40回の試行が失敗しましたが、2回は成功しました。
また、奇妙なことに、同じバージョンのODACドライバー(32ビットシステム用)を備えた同じアプリケーションが、古い32ビットのWindows2003Serverで毎回うまく機能します。
新しい64ビットサーバーは、Windows 2008 Server R2 Standard + SP1を搭載しており、すべての実際の更新プログラムであり、ウイルス対策ソフトウェアはインストールされていません。
さまざまな構成を試しました。
-64ビットのOracleドライバーをインストールし、64ビットのOracle.DataAccessライブラリを使用して任意のCPUとx64にアプリケーションをコンパイルします。
-32ビットのOracleドライバーをインストールし、32ビットのOracleを使用して任意のCPUとx86にアプリケーションをコンパイルします。 DataAccessライブラリ、
それらのどれも動作しません。一部のライブラリがMSDTC(Distributed Transaction Coordinator)サービスによってブロックされているため、Oracleドライバディレクトリを削除/名前変更できない場合があることに気付きました。私はそれを無効にし、構成を古いものと同じに変更し、サーバー管理ツールのいくつかのパラメーターを増やしようとしました(とりわけ:Transacion Time Limit、60sから0(無制限))。しかし、私は何の改善にも気づいていません。
ファイアウォールを無効にしても試しました。
接続が切断されると(?)、Windowsイベントログに一致するアラートまたはエラーが表示されません。
私はサーバー管理の経験がないので、ほとんどデフォルト値で構成されています。アプリケーションサーバー、Webサーバー(IIS)、ファイルサービスの3つの役割が有効になっています。
Oracle Database Serverの管理者と話をしましたが、彼は、制限(タイムアウト、リソース)設定がなく、Oracleサーバーのログにエラーが表示されないことを保証しました。
そしてもう一度、同じクエリが32ビットのWindows 2003 Serverで機能していますが、64ビットのWindows2008Serverでは機能していません。また、アプリケーションサーバーとWebサーバーの役割を削除したときにサーバー上でも機能しないこともテストしました(したがって、ほぼ明らかです)。
また、自宅の64ビットWindows7ラップトップでプログラム+ 64ビットドライバーをテストしましたが、問題なく動作します。
Windows 2008 Serverにいくつかの設定がある可能性があると思います-タイムアウトまたはリソースのいずれかのために、ヒットして接続/トランザクションを強制終了する可能性がありますが、それを確認する方法やどこを探すべきかわかりません。では、何が悪いのか教えていただけますか?
-編集:
私が気付いたもう1つのこと:クエリが成功して終了したとき(前回、昨日の夜にそれを実行できたとき-サーバーの負荷と接続の負荷が低いとき)、Oracleセッションモニターを見ると、開いている接続は1つだけであり、アプリケーションが閉じられた直後に閉じられました。ただし、アプリケーションが失敗するたびに、 5つの開いている接続(nullコマンドを使用)が残ります。これらの接続は、アプリケーションを閉じた後、何分間も消えることはありません。したがって、接続プールの処理に問題がある可能性があると思います...