Ich versuche, zu Oracle.ManagedDataAcess von einer nicht verwalteten Version zu migrieren und Randoms ORA-12570 TNS: Paketleserfehler zu empfangen.
Ich weiß nicht, warum dieser Fehler auftritt, aber wenn er einmal gestartet wird, gibt jede nachfolgende Anforderung ungefähr 10 bis 30 Minuten denselben Fehler aus, dann funktioniert sie erneut für weitere 10 bis 30 Minuten und so weiter.
Es ist also eine zufällige Folge von Ausfällen für einige Zeit, dann der Erfolg
Vieles schon versucht, wieder aufzunehmen:
Die Umgebung:
Geprüft:
Zusätzliche Informationen:
Aufbau:
Server sqlnet.ora
SQLNET.AUTHENTICATION_SERVICES = (NTS) NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT)
Anwendung 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>
Einige Referenzen:
https://community.Oracle.com/thread/3634263?start=0&tstart=0
Von ODP.net verwalteter Treiber wirft ORA-12570: Netzwerksitzung: Unerwarteter Paketlesefehler
Verwalteter Oracle-Client mit erweiterten Sicherheitsoptionen von Oracle
ODP.NET-Fehler in IIS: ORA-12357-Netzwerksitzung Ende der Datei
UPDATE 1
Nachdem sich das Pooling geändert hatte (wie ich hier als Antwort beschrieben habe), entschied ich mich, eine Version zu veröffentlichen, um einen echten Test durchzuführen. Nach einem Tag und Benutzer, die sich über die Leistung beschweren, wurde ein weiterer Fehler angezeigt: Der Wert kann nicht null sein. Parametername: byteArray
Ich habe den Verweis wieder auf die nicht verwaltete Version geändert und alles war wieder in Ordnung, schneller, ohne Fehler und besseres Pooling-Management.
Deshalb gebe ich die verwaltete Version erst jetzt auf, vielleicht werde ich die nächste Version von Oracle erneut versuchen.
Hier sehen Sie einige Hinweise zu diesem neuen Fehler wie ein anderer Fehler (immer noch ohne Antwort).
https://community.Oracle.com/thread/3676588?start=0&tstart=0
EF + ODP.NET + CLOB = Wert kann nicht Null sein - Parametername: ByteArray?
Gründe für nicht verwenden:
Nach dem Deaktivieren des Poolings (Pooling = False), wie @ bdn02 vorschlug, konnte ich bestätigen, dass es funktioniert hat. Ich denke jedoch, dass dies Auswirkungen auf die Leistung haben sollte, und ich war besorgt, diesen Code ohne Pooling in der Produktion zu veröffentlichen (ich dachte, die Standardwerte waren in Ordnung).
Ich habe also viele Konfigurationen ausprobiert und sieht irgendwie aus (es ist nicht ganz klar), dass das Pool-Management von Oracle einen ORA-12570-Fehler auslöste und nach einiger Zeit die Sitzungen geschlossen wurden und die Anwendung wieder funktionierte.
Um die beste Konfiguration mit aktiviertem Pooling zu finden, habe ich eine Testanwendung zum Starten von 50 Threads (von denen jeder 1 Test alle 50 ms durchführt) erstellt und die Standard-Pool-Werte verringert, bis der Fehler beendet wurde. Auf diese Weise konnte ich eine optimale Konfiguration erhalten, stabil und fehlerfrei.
Offensichtlich gilt dies nicht für jeden Server, aber dies ist meine endgültige Konfiguration der Verbindungszeichenfolge:
Pooling=true;Min Pool Size=1;Connection Lifetime=180;Max Pool Size=50;Incr Pool Size=5
Nach meiner Erfahrung mit einem ähnlichen Fehler 12570 (Leser vs. Schreiber) gibt es nur einen Grund für diesen Fehler - etwas in Ihrem Netzwerk beendet inaktive TCP-Verbindungen. In der Regel handelt es sich hierbei um eine Firewall/einen verwalteten Switch. Sie sagten, Sie hätten die Firewall bereits ausgeschlossen, aber ich weiß nicht, wie. Es ist möglich, dass die Datenbank selbst die Verbindungen beendet (dba-Skript), aber ich erinnere mich daran, dass dies ein anderer Fehler ist.
Ora-12571 könnte etwas anders sein. Aber nachdem Sie festgestellt haben, dass das Problem dasselbe ist, da es sich seit langem um Poolverbindungen handelt, werde ich weitermachen.
Es gibt ein paar Dinge, die Sie tun können:
Ich habe dies im Laufe der Jahre oft gesehen und als ich das erste Mal geschah, habe ich ein Hilfsprogramm erstellt, das im Grunde eine binäre Suche durchführt, um die genaue Timeout-Zeit zu ermitteln, indem Verbindungen unterschiedlicher Dauer erstellt werden. Wenn es ständig zur gleichen Beendigungszeit landet, können Sie vermuten, dass irgendwo eine Einstellung vorliegt, die dies verursacht. Wenn es unberechenbar ist, haben Sie möglicherweise eine Art Infrastruktur-Flakiness.
Leider habe ich es als C # -Formulare-App erstellt, daher habe ich sowohl den Formularcode als auch den Designercode unten eingefügt:
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;
}
}
Ich gebe Ihnen ein Powershell-Skript, mit dem ich die Datenbankkonnektivität prüfe .
$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
Können Sie versuchen, dieses Skript jede Minute mit der verwalteten Version der von Oracle verwalteten DLL zu planen? Ich verstehe, ob das Problem nur in einer Webanwendung liegt oder ob ein verwalteter Oracle-Treiber in Beziehung steht Bei einem erweiterten Test können Sie eine Kopie dieses Skripts planen, das die nicht verwaltete Version von Oracle.dataaccess verwendet.
Viel Glück
Ich habe diesen Fehler in einer Anwendungsausnahme erhalten. Es gab keine hilfreichen Details in der inneren Ausnahme. Durch das Ändern der Pooling-Optionen wurde das Problem nicht behoben, und das Pooling wurde nicht deaktiviert. Nachdem die Ablaufverfolgung aktiviert war, wurde in der Ablaufverfolgungsdatei ein anderer Fehler " ORA-12537-Netzwerksitzung " angezeigt (nicht an die Anwendungsausnahme weitergegeben). Dieser Thread deutet darauf hin, dass eine alte Version des Oracle-Treibers Schuld ist. Ich habe geprüft, und ich habe die Version von 2014 verwendet. Durch das Upgrade auf die Version 2017/12.2c/12.2.0.1.0 wurde das Problem behoben.
Bei der Verwendung von SQL Server Reporting Services 2016 mit ODAC 12c Release 4 ist dieser zeitweilige Fehler aufgetreten:
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
Das Hinzufügen des Pooling-Parameters Data Source="myOracleDB";Pooling="false"
zur Oracle-Datenquelle in SSRS hat das Problem vollständig gelöst.
Eine sofortige erneute Ausführung des Berichts funktioniert einwandfrei.
Ich bin mir bewusst, dass beim Erstellen einer neuen Verbindung jedes Mal potenzielle Leistungsprobleme auftreten, anstatt den Pool zu verwenden. Wenn Oracle dies jedoch nicht behoben hat, möchte ich nicht, dass meine Benutzer diesen Fehler erhalten.