管理されていないバージョンからOracle.ManagedDataAcessに移行しようとしていますが、ランダムなORA-12570 TNS:パケットリーダーエラーが発生します。
このエラーが発生する理由はわかりませんが、いったん開始すると、後続のすべてのリクエストで約10〜30分間同じエラーが発生し、その後さらに10〜30分間動作します。
したがって、それはしばらくの間、その後の失敗のランダムであり、その後の成功です
再開するために、すでに多くのことを試みました:
環境:
チェック済み:
追加情報:
構成:
サーバーsqlnet.ora
SQLNET.AUTHENTICATION_SERVICES =(NTS) NAMES.DIRECTORY_PATH =(TNSNAMES、EZCONNECT)
アプリケーションWeb.config
<connectionStrings>
<add name="XXXX" connectionString="Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(Host=xxx.xxx.com)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=xxx)));User Id=xxxxx;Password=xxxxx;" />
</connectionStrings>
<configSections>
<section name="Oracle.manageddataaccess.client" type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</configSections>
<Oracle.manageddataaccess.client>
<version number="*">
<dataSources>
<!--<dataSource alias="SampleDataSource" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(Host=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL))) " />-->
</dataSources>
<settings>
<setting name="SQLNET.AUTHENTICATION_SERVICES" value="NONE"/> <!--NTS-->
<setting name="sqlnet.crypto_checksum_server" value="rejected"/>
<setting name="sqlnet.crypto_checksum_client" value="rejected"/>
<setting name="SQLNET.ENCRYPTION_SERVER" value="rejected"/>
</settings>
</version>
</Oracle.manageddataaccess.client>
一部の参照:
https://community.Oracle.com/thread/3634263?start=0&tstart=
ODP.netマネージドドライバーがORA-12570をスローする:ネットワークセッション:予期しないパケット読み取りエラー
Oracle Advanced Securityオプションを備えたManaged Oracle Client
IISのODP.NETエラー:ORA-12357ネットワークセッションファイルの終わり
更新1
プーリングが変更された後(ここで答えとして説明したように)、実際のテストを行うためのバージョンを公開することにしました。 1日後、ユーザーがパフォーマンスについて不平を言った後、別のエラーが発生しました。パラメーター名:byteArray
参照を管理されていないバージョンに戻したところ、バイト配列エラーがなく、プーリング管理が改善され、すべてが再び高速になりました。
ですから、今のところマネージドバージョンをあきらめているだけです。多分、次のOracleリリースでもう一度試すつもりです。
ご覧のとおり、この新しいエラーに関するいくつかの参照は、別のバグのように見えます(まだ答えはありません)。
https://community.Oracle.com/thread/3676588?start=0&tstart=
EF + ODP.NET + CLOB =値をNullにすることはできません-パラメーター名:byteArray?
これまでのところ、使用しない理由:
@ bdn02が示唆したように、プーリングを無効にした後(Pooling = False)、それが機能していることを確認できました。しかし、それはパフォーマンスに影響するはずだと思い、プールなしでこのコードを本番環境に公開することを心配していました(標準値は大丈夫だと思いました)。
そのため、多くの構成を試してみましたが、どういうわけか(あまり明確ではありません)、Oracleのプール管理でORA-12570エラーが発生し、しばらくしてセッションが閉じられ、アプリケーションが再び動作しました。
プーリングを有効にして最適な構成を見つけるには、テストアプリケーションを作成して50スレッド(各50ミリ秒ごとに1テストを実行)を開始し、エラーが停止するまでデフォルトのプール値を減らしました。このようにして、エラーなしで安定した最適な構成を取得できました。
明らかにすべてのサーバーに適用されるわけではありませんが、これは私の最終的な接続文字列構成です。
Pooling=true;Min Pool Size=1;Connection Lifetime=180;Max Pool Size=50;Incr Pool Size=5
同様のエラー12570(リーダーとライター)の私の経験では、このエラーの原因は1つだけです。ネットワーク上の何かがアイドルTCP接続を終了しています。通常、これはファイアウォール/管理スイッチです。あなたはすでにファイアウォールを除外していると言いましたが、どうすればいいかわかりません。 db自体が接続を終了している可能性があります(dbaスクリプト)が、別のエラーであることを思い出します。
Ora-12571はわずかに異なる場合があります。それでも、問題は同じであることがわかったので、プール接続が長く確立されているという点で、これからも続けていきます。
できることがいくつかあります。
私はこれを何年も何度も見てきましたが、初めて起こったとき、さまざまな期間の接続を作成して正確なタイムアウト時間を決定するために基本的にバイナリ検索を行うユーティリティを作成しました。一貫して同じ終了時刻に到達する場合、これを引き起こしている設定がどこかにあると推測できます。不安定な場合は、何らかのインフラストラクチャの不安定さがあります。
残念ながら、C#フォームアプリとして作成したため、フォームコードとデザイナーコードの両方を以下に貼り付けました。
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Oracle.ManagedDataAccess.Client;
namespace TimeoutTest
{
public partial class Form1 : Form
{
List<TestConnection> connections;
Int32 connectionCount;
Int32 multiplier;
Int32 initialConnectionWait;
TestConnection controlConnection = null;
public Form1()
{
InitializeComponent();
}
private void BtStart_Click(object sender, EventArgs e)
{
connectionCount = Int32.Parse(InConnections.Text);
multiplier = Int32.Parse(InMultiplier.Text);
initialConnectionWait = Int32.Parse(InInitialWait.Text);
DisplayMessage("Starting control connection\r\n");
controlConnection = new TestConnection();
controlConnection.ErrorOccured += new EventHandler(controlConnection_ErrorOccured);
controlConnection.IsControlConnection = true;
controlConnection.StartTest(2);
connections = new List<TestConnection>();
DisplayMessage("Spinning up {0} connections...\r\n", connectionCount);
for (int i = 0, idleTime=initialConnectionWait; i < connectionCount; i++, idleTime*=multiplier)
{
TestConnection connection = new TestConnection();
connection.Notified += new TestConnection.NotificationEventHandler(connection_Notified);
connection.ErrorOccured += new EventHandler(connection_ErrorOccured);
connection.TestCompleted += new EventHandler(connection_TestCompleted);
connection.StartTest(idleTime);
connections.Add(connection);
}
DisplayMessage("");
}
void controlConnection_ErrorOccured(object sender, EventArgs e)
{
DisplayMessage("\r\nControl connection error, aborting!!!");
BtCancel_Click(this, EventArgs.Empty);
}
void connection_TestCompleted(object sender, EventArgs e)
{
TestConnection currentConnection = (TestConnection)sender;
if (currentConnection == connections.Last())
DisplayMessage("\r\nAll tests complete. Done");
}
void connection_ErrorOccured(object sender, EventArgs e)
{
//stop any active connection.
foreach(TestConnection tc in connections)
{
tc.CompletionTimer.Enabled=false;
}
TestConnection currentConnection = (TestConnection)sender;
Int32 upperTime = currentConnection.IdleTime;
Int32 lowerTime = 0;
Int32 index = connections.IndexOf(currentConnection);
//if this is not the first connection...
if(index > 0)
{
//...then set the lower time based on the previous connection
lowerTime = connections[index-1].IdleTime;
}
//get the difference between the lower and upper as the new range to work on
Int32 range = upperTime - lowerTime;
//divide the range over the number of connections to get the new interval
Int32 interval = range / this.connectionCount;
connections.Clear();
//if the interval is too small try to reduce the number of connections
while (interval < 2 && this.connectionCount > 2)
{
this.connectionCount--;
DisplayMessage("\r\nConnections too high for current resolution. Reducing to {0} connections.", this.connectionCount);
interval = range / this.connectionCount;
}
if(interval < 2)
{
DisplayMessage("\r\nResolution cannot be increased. Done.");
}
else
{
DisplayMessage("\r\nRestarting test with min:{0}, max{1}, resolution{2}.", lowerTime, upperTime, interval);
//create the new connections
for (int i = connectionCount-1, idleTime = upperTime-interval; i >= 0; i--, idleTime-=interval)
{
TestConnection connection = new TestConnection();
connection.Notified += new TestConnection.NotificationEventHandler(connection_Notified);
connection.ErrorOccured += new EventHandler(connection_ErrorOccured);
connection.TestCompleted += new EventHandler(connection_TestCompleted);
connection.StartTest(idleTime);
connections.Insert(0,connection);
}
this.connectionCount = connections.Count;
}
}
private void BtCancel_Click(object sender, EventArgs e)
{
//stop any active connection.
foreach (TestConnection tc in connections)
{
tc.CompletionTimer.Enabled = false;
tc.Command.Connection.Close();
}
DisplayMessage("Stopped running tests.");
}
void connection_Notified(object o, Form1.TestConnection.NotificationEventArgs e)
{
DisplayMessage(e.Message);
}
private void DisplayMessage(String message)
{
DisplayMessage("{0}", message);
}
private void DisplayMessage(String message, params Object[] args)
{
OutStatus.AppendText(String.Format(message, args) + "\r\n");
}
public class TestConnection
{
public Boolean IsControlConnection { get; set; }
public OracleCommand Command { get; private set; }
public Timer CompletionTimer { get; private set; }
public String ConnectionId { get; private set; }
public Int32 IdleTime
{
get
{
return CompletionTimer.Interval / 1000;
}
set
{
CompletionTimer.Interval = value * 1000;
}
}
#region Events and Delegates
public event EventHandler ErrorOccured;
public event EventHandler TestCompleted;
public class NotificationEventArgs : EventArgs
{
public NotificationEventArgs(String message)
{
this.Message = message;
}
public String Message { get; set; }
}
public delegate void NotificationEventHandler(object o, NotificationEventArgs e);
public event NotificationEventHandler Notified;
private void Notify(String message)
{
if (Notified != null)
{
Notified(this, new NotificationEventArgs(message));
}
}
public void Notify(String format, params object[] args)
{
this.Notify(String.Format(format, args));
}
#endregion
public TestConnection()
{
CompletionTimer = new Timer();
CompletionTimer.Tick += new EventHandler(CompleteTest);
Command = new OracleCommand(
"select 'saddr:' || saddr || '-sid:' || sid || '-serial#:' || serial# || '-audsid:' || audsid || '-paddr:' || paddr || '-module:' || module from gv$session where audsid=Userenv('SESSIONID')");
Command.Connection = new OracleConnection(Configuration.OracleConnectionString);
}
public String StartTest(Int32 idleTime)
{
Command.Connection.Open();
ConnectionId = (String)Command.ExecuteScalar();
Notify("Started test with idle time={0}, id={1}.", idleTime, ConnectionId);
IdleTime = idleTime;
CompletionTimer.Enabled = true;
return ConnectionId;
}
private void CompleteTest(object sender, EventArgs e)
{
if (!IsControlConnection)
CompletionTimer.Enabled = false;
try
{
Command.ExecuteScalar();
Notify("Test complete on connection with idle time={0}, id={1}.", IdleTime, ConnectionId);
if (TestCompleted != null)
TestCompleted(this, EventArgs.Empty);
}
catch (OracleException ex)
{
if (ex.Number == 12571)
{
if (ErrorOccured != null)
{
Notify("Found error on connection with idle time={0}, id={1}.", IdleTime, ConnectionId);
ErrorOccured(this, EventArgs.Empty);
}
}
else
{
Notify("Unknown error occured on connection with timeout {0}, Error: {1}, \r\n{2}",(IdleTime).ToString(), ex, ConnectionId);
}
}
catch (Exception ex)
{
Notify("Unknown error occured on connection with timeout {0}, Error: {1}, \r\n{2}", (IdleTime).ToString(), ex, ConnectionId);
}
finally
{
if(!IsControlConnection)
Command.Connection.Close();
}
}
}
private void InConnections_TextChanged(object sender, EventArgs e)
{
Int32.TryParse(InConnections.Text,out connectionCount);
Int32.TryParse(InMultiplier.Text,out multiplier);
Int32.TryParse(InInitialWait.Text, out initialConnectionWait);
OutLongestConnection.Text = (Math.Pow(multiplier,connectionCount-1) * initialConnectionWait).ToString();
}
private void Form1_Load(object sender, EventArgs e)
{
InConnections_TextChanged(this, EventArgs.Empty);
}
}
}
Form1.designer.cs:
namespace TimeoutTest
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.BtStart = new System.Windows.Forms.Button();
this.OutStatus = new System.Windows.Forms.TextBox();
this.InConnections = new System.Windows.Forms.MaskedTextBox();
this.label1 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.InInitialWait = new System.Windows.Forms.MaskedTextBox();
this.InMultiplier = new System.Windows.Forms.MaskedTextBox();
this.label2 = new System.Windows.Forms.Label();
this.BtCancel = new System.Windows.Forms.Button();
this.label4 = new System.Windows.Forms.Label();
this.OutLongestConnection = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// BtStart
//
this.BtStart.Location = new System.Drawing.Point(13, 394);
this.BtStart.Name = "BtStart";
this.BtStart.Size = new System.Drawing.Size(75, 23);
this.BtStart.TabIndex = 0;
this.BtStart.Text = "Start";
this.BtStart.UseVisualStyleBackColor = true;
this.BtStart.Click += new System.EventHandler(this.BtStart_Click);
//
// OutStatus
//
this.OutStatus.Location = new System.Drawing.Point(13, 13);
this.OutStatus.Multiline = true;
this.OutStatus.Name = "OutStatus";
this.OutStatus.ReadOnly = true;
this.OutStatus.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.OutStatus.Size = new System.Drawing.Size(766, 375);
this.OutStatus.TabIndex = 1;
//
// InConnections
//
this.InConnections.Location = new System.Drawing.Point(180, 397);
this.InConnections.Mask = "00";
this.InConnections.Name = "InConnections";
this.InConnections.Size = new System.Drawing.Size(22, 20);
this.InConnections.TabIndex = 2;
this.InConnections.Text = "10";
this.InConnections.TextChanged += new System.EventHandler(this.InConnections_TextChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(108, 400);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(66, 13);
this.label1.TabIndex = 3;
this.label1.Text = "Connections";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(289, 399);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(113, 13);
this.label3.TabIndex = 5;
this.label3.Text = "Initial Connection Wait";
//
// InInitialWait
//
this.InInitialWait.Location = new System.Drawing.Point(408, 396);
this.InInitialWait.Mask = "00";
this.InInitialWait.Name = "InInitialWait";
this.InInitialWait.Size = new System.Drawing.Size(21, 20);
this.InInitialWait.TabIndex = 4;
this.InInitialWait.Text = "60";
this.InInitialWait.TextChanged += new System.EventHandler(this.InConnections_TextChanged);
//
// InMultiplier
//
this.InMultiplier.Location = new System.Drawing.Point(262, 396);
this.InMultiplier.Mask = "0";
this.InMultiplier.Name = "InMultiplier";
this.InMultiplier.Size = new System.Drawing.Size(21, 20);
this.InMultiplier.TabIndex = 2;
this.InMultiplier.Text = "2";
this.InMultiplier.TextChanged += new System.EventHandler(this.InConnections_TextChanged);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(208, 400);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(48, 13);
this.label2.TabIndex = 3;
this.label2.Text = "Multiplier";
//
// BtCancel
//
this.BtCancel.Location = new System.Drawing.Point(13, 436);
this.BtCancel.Name = "BtCancel";
this.BtCancel.Size = new System.Drawing.Size(75, 23);
this.BtCancel.TabIndex = 6;
this.BtCancel.Text = "Cancel";
this.BtCancel.UseVisualStyleBackColor = true;
this.BtCancel.Click += new System.EventHandler(this.BtCancel_Click);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(451, 399);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(102, 13);
this.label4.TabIndex = 7;
this.label4.Text = "Longest Connection";
//
// OutLongestConnection
//
this.OutLongestConnection.AutoSize = true;
this.OutLongestConnection.Location = new System.Drawing.Point(559, 399);
this.OutLongestConnection.Name = "OutLongestConnection";
this.OutLongestConnection.Size = new System.Drawing.Size(102, 13);
this.OutLongestConnection.TabIndex = 8;
this.OutLongestConnection.Text = "Longest Connection";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(791, 582);
this.Controls.Add(this.OutLongestConnection);
this.Controls.Add(this.label4);
this.Controls.Add(this.BtCancel);
this.Controls.Add(this.label3);
this.Controls.Add(this.InInitialWait);
this.Controls.Add(this.label2);
this.Controls.Add(this.InMultiplier);
this.Controls.Add(this.label1);
this.Controls.Add(this.InConnections);
this.Controls.Add(this.OutStatus);
this.Controls.Add(this.BtStart);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button BtStart;
private System.Windows.Forms.TextBox OutStatus;
private System.Windows.Forms.MaskedTextBox InConnections;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.MaskedTextBox InInitialWait;
private System.Windows.Forms.MaskedTextBox InMultiplier;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button BtCancel;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label OutLongestConnection;
}
}
データベース接続の確認に使用するPowerShellスクリプトを提供します。 $baselogpath = "" $filesuffix = "_GetDBConnection" $dbuser ="" $dbpassword ="" $dbalias = ""; $command = new-Object Oracle.DataAccess.Client.OracleCommand($queryString, $connection); $connection.Open(); $count = $command.ExecuteScalar(); $connection.Close();
$message = "Records found: " + $count; $esito = "OK"; } Catch { $message = $_.Exception.Message; $esito = "KO"; } $now = Get-Date $filename = $baselogpath + $now.Year + $now.Month.Tostring("00") + $now.Day.Tostring("00") + $filesuffix + ".log" if (!(Test-Path($filename))) { $fileheader = "Time Esito, Elapsed, Message" $fileheader > $filename } $Time.Stop(); $Elapsed = $Time.Elapsed; $row = $now.Hour.toString("00") + ":" + $now.Minute.toString("00") + ":" + $now.Second.toString("00") + " " + $esito + "," + $Elapsed.Hours.toString("00") + ":" + $Elapsed.Minutes.toString("00") + ":" + $Elapsed.Seconds.toString("00") + "," + $message; $row >> $filename
Oracle管理DLLの管理バージョンを使用して、1分ごとにこのスクリプトをスケジュールできますか?問題がWebアプリケーションのみにあるのか、Oracle管理ドライバーに関連するのかを理解できます。高度なテストを行う場合は、管理されていないバージョンのOracle.dataaccessを使用するこのスクリプトのコピーをスケジュールできます。
幸運を
アプリケーション例外でこのエラーを受け取りました。内部の例外には、これ以上役立つ情報はありませんでした。プーリングオプションを変更しても問題は解決せず、プーリングを無効にすることもできませんでした。トレースを有効にすると、トレースファイルに別のエラー「 ORA-12537ネットワークセッションファイルの終わり 」が表示されました(アプリケーション例外に反映されません)。そのスレッドは、Oracleドライバーの古いバージョンが原因であることを示唆しています。私はチェックし、2014年のバージョンを使用していました。2017/ 12.2c/12.2.0.1.0バージョンにアップグレードすると、問題は解決しました。
ODAC 12cリリース4でSQL Server Reporting Services 2016を使用すると、この同じ断続的なエラーが発生しました。
Error:
An error has occurred during report processing. (rsProcessingAborted)
Query execution failed for dataset 'TermPrompt'. (rsErrorExecutingCommand)
ORA-12570: Network Session: Unexpected packet read error
ORA-12570: Network Session: Unexpected packet read error
ORA-12537: Network Session: End of file
プーリングパラメーターの追加Data Source="myOracleDB";Pooling="false"
SSRSのOracleデータソースに問題を完全に解決しました。
レポートの即時再実行は正常に機能します。
プールを使用するのではなく、毎回新しい接続を作成する際に潜在的なパフォーマンスの問題があることを認識していますが、Oracleがこれを修正するまで、ユーザーがこのエラーに遭遇することは望ましくありません。