Überprüfen der Verbindungspooling-Serverseite mit aktiviertem CONTEXT_INFO


7

Ich arbeite mit einer dreistufigen Anwendung, Microsoft Dynamics AX, bei der die mittlere Schicht Verbindungen zu einem SQL Server aufrechterhält. Mehrere Clients stellen eine Verbindung zu diesem Server der mittleren Ebene her.

Auf dem Middle Tier-Server sind normalerweise mehrere Verbindungen zum SQL Server geöffnet, daher bin ich mir ziemlich sicher, dass sie zusammengefasst werden. Es ist jedoch keine Dokumentation verfügbar, wie dies implementiert wird.

Normalerweise können wir SPIDs nicht mit Benutzern oder Clientanwendungen verknüpfen, aber es gibt eine Option, bei der wir einen Registrierungsschlüssel (spezifisch für Microsoft Dynamics AX) festlegen können, der diese Informationen im context_infoFeld verfügbar macht sys.dm_exec_sessions.

Auch hier gibt es keine Dokumentation darüber, wie dies implementiert wird. Die einzige Information, die wir dazu haben, ist ein vager Blogeintrag auf MSDN.

Der Beitrag erwähnt

Das Hinzufügen dieser Informationen hat einen geringen Leistungsaufwand.

Da wir keine Implementierungsdetails kennen, wie zum Beispiel:

  1. Sind die Informationen irgendwie in der Verbindungszeichenfolge enthalten oder wird dies von SET CONTEXT_INFO durchgeführt?
  2. Wann werden Verbindungen wiederverwendet?
  3. Welche genauen Auswirkungen sind zu erwarten?

Gibt es eine Möglichkeit, serverseitig zu bestimmen, wie das Verbindungspooling funktioniert und welche Auswirkungen die context_info hat?

Update:
Verwenden Sie diese Abfrage von hier

SELECT des.program_name,
       des.login_name,
       des.host_name,
--       der.database_id,
       COUNT(des.session_id) AS [Connections]
FROM sys.dm_exec_sessions des
INNER JOIN sys.dm_exec_connections DEC
        ON des.session_id = DEC.session_id
WHERE des.is_user_process = 1
--AND des.status <> 'running'
GROUP BY des.program_name,
         des.login_name,
         des.host_name
--         ,der.database_id
HAVING COUNT(des.session_id) > 2
ORDER BY COUNT(des.session_id) DESC

Ich kann sehen, dass Verbindungspooling verwendet wird.

Antworten:


6

Erstens CONTEXT_INFOist eine Eigenschaft der Sitzung, nicht die Verbindung. Es wird durch sp_reset_connection zurückgesetzt, wenn dieselbe Sitzung wiederverwendet und der erste Stapel ausgeführt wird. Es scheint , dass CONTEXT_INFOwurde nicht in SQL Server 2000 zurückgesetzt und möglicherweise frühere Versionen, aber ausgehend von SQL Server 2005 wird auf jeden Fall zurückgesetzt NULL.

Ein Teil der Verwirrung hier ist, dass die Frage spezifisch für "Microsoft Dynamics AX" ist, da bei der allgemeinen .NET-Programmierung der in diesem Blog-Artikel angegebene Registrierungsschlüssel nicht vorhanden wäre. Die Informationen, in denen Microsoft Dynamics dann speichert CONTEXT_INFO, sind die Details der Anwendungssitzung, die nichts mit SQL Server-SPIDs zu tun haben und nicht verwendet werden können, um darauf zu schließen, dass ein Verbindungspooling stattfindet, da die Anwendungssitzung natürlich mehrere Verbindungen sowie SPIDs umfasst .

Der Mechanismus, der zum CONTEXT_INFOFestlegen verwendet wird, muss eine separate, zusätzliche Abfrage sein, die vor allen anderen Abfragen für diese Sitzung ausgeführt wird. Etwas in der Art von:

SqlConnection _Connection = new SqlConnection("{connection-string}");
_Connection.Open();

if(_IsConnectionContextRegistryKeySet)
{
  SqlCommand _Command = _Connection.CreateCommand();
  _Command.CommandType = CommandType.Text;

  _Command.CommandText = @"DECLARE @BinaryInfo VARBINARY(128);
                           SET @BinaryInfo = CONVERT(VARBINARY(128), @StringInfo);
                           SET CONTEXT_INFO @BinaryInfo;";

  SqlParameter _ParamInfo = new SqlParameter("@StringInfo", SqlDbType.VarChar, 100);
  _ParamInfo.Value = String.Format("{0} {1} {2}...", AXuserID, AXsessionID, ...);
  _Command.Parameters.Add(_ParamInfo);

  _Command.ExecuteNonQuery();
  _Command.Dispose();
}

Daher ergibt sich der geringe zusätzliche Aufwand für das Festlegen dieser Informationen aus der Ausführung dieser zusätzlichen Abfrage.

Zweitens können Sie das Verbindungspooling mithilfe von SQL Server Profiler testen. Wählen Sie das Ereignis "RPC: Abgeschlossen" in der Kategorie "Gespeicherte Prozeduren" aus und stellen Sie sicher, dass "TextData", "ClientProcessID" und "SPID" für dieses Ereignis aktiviert sind (Sie können zumindest andere Spalten auswählen, wenn Sie möchten ). Gehen Sie dann zu "Spaltenfilter", wählen Sie "TextData" und fügen Sie in der Bedingung "Gefällt mir" die folgende Bedingung hinzu : exec sp[_]reset[_]connection. Führen Sie nun diesen Trace aus. Wenn Instanzen von exec sp_reset_connection eingehen , liegt dies daran, dass das Verbindungspooling verwendet wird.

Darüber hinaus gibt es zwei Nebenwirkungen des Verbindungspoolings, die in den DMVs auftreten können oder nicht, je nachdem, wie viele Verbindungen angefordert werden. Die folgende Abfrage sollte viele / die meisten der gepoolten Verbindungen erfassen (bitte beachten Sie, dass dies nichts mit CONTEXT_INFO zu tun hat):

SELECT sssn.login_time,
       DATEDIFF(MILLISECOND, conn.connect_time, sssn.login_time)
                  AS [MillisecondsBetweenConnectionAndSessionStart],
       conn.*
FROM sys.dm_exec_connections conn
INNER JOIN sys.dm_exec_sessions sssn
        ON sssn.session_id = conn.session_id
WHERE conn.session_id <> conn.most_recent_session_id
OR    DATEDIFF(MILLISECOND, conn.connect_time, sssn.login_time) > 50
ORDER BY conn.connect_time;

Diese Abfrage sucht nach den folgenden Hinweisen für das verwendete Verbindungspooling:

  • Die aktuelle Sitzungs-ID ist nicht mit der vorherigen Sitzungs-ID identisch. Wenn diese beiden IDs identisch sind, kann es sich um eine Verbindung handeln, die Pooling verwendet, da dieselbe SPID wiederverwendet werden kann. Wenn sie sich jedoch unterscheiden, kann dies nur das Ergebnis eines Verbindungspoolings sein.
  • Die Zeit zwischen dem Herstellen der Verbindung und dem Start der Sitzung beträgt mehr als 50 Millisekunden (obwohl dieser Schwellenwert je nach System variieren kann). Normalerweise dauert die erste Sitzung, die bei einer Verbindung erstellt wird, weniger als 30 Millisekunden nach der Verbindung, sie sollte jedoch "im Allgemeinen" nicht über 50 liegen, selbst wenn mehrere SqlCommands ausgeführt werden.

In ähnlicher Weise sollte es auch möglich sein, das Verbindungspooling durch Erstellen einer temporären Tabelle zu testen und alle paar Sekunden sowohl [session_id](INT) als auch [connection_id](UNIQUEIDENTIFIER) von zu erfassen sys.dm_exec_connections. Suchen Sie dann einfach nach Zeilen mit derselben Verbindungs-ID, aber unterschiedlicher Sitzungs-ID.

Schließlich ist die in der Frage veröffentlichte Abfrage nicht gültig, um das Verbindungspooling in Bezug auf die meisten Webanwendungen anzuzeigen. Das Problem hierbei ist, dass die Eigenschaften von "Programmname", "Anmeldename" und "Hostname" normalerweise für alle vom Web- / App-Server hergestellten Verbindungen gleich sind (daher sind die Lizenzierungsmodelle pro Prozessor / pro Kern erforderlich anstatt nur das CAL-Modell zu haben).


1

In Bezug auf das Verbindungspooling hat Thomas Stringer Folgendes veröffentlicht: http://blogs.msdn.com/b/sql_pfe_blog/archive/2013/10/08/connection-pooling-for-the-sql-server-dba.aspx

Das Einfache ist: "Die Antwort, die Unternehmens-Datenbankadministratoren auf diese Anfragen geben müssen, ist, dass sie anbieterspezifisch sind. Mit anderen Worten, auf der Client- / Anwendungsseite wird das Verbindungspooling abgewickelt."

Der CONTEXT_INFO, der binär gespeichert ist, muss von der Anwendung festgelegt werden. CONTEXT_INFO ist nur ein kleiner Bucket, der nützliche Informationen wie den Namen / die ID / den Login des Benutzers enthält. (Oder was auch immer Sie sonst in dem kleinen verfügbaren Raum stopfen möchten.)

Der Overhead ist gering, aber es ist ein zusätzlicher Schritt, die BINARY-Daten in CONTEXT_INFO einzufügen und zu extrahieren. (Aber nützlich für Systeme, die unter einem Dienstkonto ausgeführt werden, damit Sie wissen, wessen Verbindung dies im Moment ist.)

Vielen Dank an srutzky für die Klarstellung, dass eine Poolverbindung zurückgesetzt, aber nicht getrennt wird. Zumindest nicht sofort.

Ein Beitrag von Nacho Alonso Portillo bietet Klarstellung: http://blogs.msdn.com/b/ialonso/archive/2012/06/04/how-to-determine-whether-a-connection-is-pooled-or-nonpooled .aspx

Zum Teil heißt es, dass "sp_reset_connection ... die folgenden Aufgaben ausführt: 1) Bereinigt den Sitzungskontext ... einschließlich ... setzt den CONTEXT_INFO zurück; ... 2) benachrichtigt sie über das Auftreten einer erfolgreichen Abmeldung. 3) leitet den Vorgang des Wiederherstellens der Anmeldung ein. "


Wenn ich es also richtig verstehe, wenn die Verbindungen gepoolt sind, die Sitzungen jedoch den Benutzernamen anzeigen, sollte die context_info bei jeder Anforderung festgelegt werden, da unterschiedliche Anforderungen aus der mittleren Ebene Verbindungen aus demselben Pool wiederverwenden können.
Tom V - versuchen Sie topanswers.xyz

1
Wenn Sie das Verbindungspooling verwenden, wird der Inhalt von CONTEXT_INFO nicht zurückgesetzt, wenn die Verbindung wiederverwendet wird. Sie müssen also CONTEXT_INFO mit den Informationen der aktuellen Verbindung aktualisieren.
RLF

@RLF Die Aussage in Ihrem obigen Kommentar zu "CONTEXT_INFO wird nicht zurückgesetzt, wenn die Verbindung wiederverwendet wird" ist ab SQL Server 2005 nicht wahr oder zumindest nicht mehr wahr.
Solomon Rutzky
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.