Ich habe eine Always On Availability-Gruppe eingerichtet und möchte sicherstellen, dass meine Benutzer ApplicationIntent = ReadOnly in ihren Verbindungszeichenfolgen verwenden.
Kann ich vom SQL Server über DMVs (oder Extended Events oder was auch immer) feststellen, ob ein mit ApplicationIntent = ReadOnly verbundener Benutzer in seiner Verbindungszeichenfolge enthalten ist?
Bitte antworten Sie nicht, wie Sie Verbindungen VERMEIDEN - darum geht es in dieser Frage nicht. Ich kann nicht einfach Verbindungen beenden, da es bereits Anwendungen gibt, die keine Verbindung mit der richtigen Zeichenfolge herstellen, und ich muss wissen, um welche es sich handelt, damit ich mit den Entwicklern und Benutzern zusammenarbeiten kann, um sie im Laufe der Zeit schrittweise zu reparieren.
Angenommen, Benutzer haben mehrere Anwendungen. Bob stellt beispielsweise eine Verbindung zu SQL Server Management Studio und Excel her. Er stellt eine Verbindung zu SSMS her, wenn Aktualisierungen erforderlich sind, und Excel, wenn Lesevorgänge erforderlich sind. Ich muss sicherstellen, dass er ApplicationIntent = ReadOnly verwendet, wenn er eine Verbindung mit Excel herstellt. (Das ist nicht das genaue Szenario, aber es ist nah genug, um es zu veranschaulichen.)
quelle
sqlserver.read_only_route_complete
da es nur auf primären ausgelöst wird.Antworten:
Das
sqlserver.read_only_route_complete
von Kin und Remus erwähnte Extended Event ist ein nettes Debug- Ereignis, das jedoch nicht viele Informationen enthält - standardmäßig nurroute_port
(z. B. 1433) undroute_server_name
(z. B. sqlserver-0.contoso.com) . Dies würde auch nur dazu beitragen, festzustellen, wann eine Nur-Lese-Verbindung erfolgreich war. Es gibt einread_only_route_fail
Ereignis, aber ich konnte es nicht auslösen. Wenn ein Problem mit der Routing-URL aufgetreten ist, schien es nicht ausgelöst zu werden, als die sekundäre Instanz nicht verfügbar war / heruntergefahren wurde, soweit ich das beurteilen konnte.Ich hatte jedoch einige Erfolge, als ich das
sqlserver.login
Ereignis- und Kausalitäts-Tracking aktivierte und einige Aktionen (wiesqlserver.username
), um es nützlich zu machen.Schritte zum Reproduzieren
Erstellen Sie eine erweiterte Ereignissitzung, um relevante Ereignisse sowie nützliche Aktionen und die Kausalität zu verfolgen:
Führen Sie die XE-Sitzung aus (betrachten Sie das Sampling als Debug-Ereignis) und sammeln Sie einige Anmeldungen:
Beachten Sie, dass sqlserver-0 meine lesbare sekundäre und sqlserver-1 die primäre ist. Hier verwende ich den
-K
Schalter vonsqlcmd
, um schreibgeschützte Anmeldungen mit Anwendungsabsicht und einige SQL-Anmeldungen zu simulieren. Das schreibgeschützte Ereignis wird bei einer erfolgreichen Nur-Lese-Anmeldung ausgelöst.Wenn ich die Sitzung pausiere oder stoppe, kann ich sie abfragen und versuchen, die beiden Ereignisse zu verknüpfen, z.
Die Abfrage sollte die Anmeldungen mit und ohne Nur-Lese-Absicht der Anwendung anzeigen:
read_only_route_complete
ist ein Debug-Ereignis, verwenden Sie es daher sparsam. Betrachten Sie zum Beispiel Stichproben.Ich habe versucht, das
pair_matching
Ziel zum Arbeiten zu bringen , aber mir ging die Zeit davon. Hier gibt es ein gewisses Entwicklungspotential, so etwas wie:quelle
Nein, anscheinend gibt es keine DMV-exponierte Verbindungseigenschaft (entweder in sys.dm_exec_connections oder sys.dm_exec_sessions ) oder sogar CONNECTIONPROPERTY , die sich auf das
ApplicationIntent
ConnectionString-Schlüsselwort bezieht .Es kann sich jedoch lohnen, über Microsoft Connect anzufordern, dass diese Eigenschaft zur
sys.dm_exec_connections
DMV hinzugefügt wird, da sie anscheinend eine Eigenschaft der Verbindung ist, die auf der Grundlage der folgenden Informationen auf der MSDN-Seite für irgendwo im Speicher von SQL Server gespeichert ist SqlClient-Unterstützung für Hochverfügbarkeit und Notfallwiederherstellung (Hervorhebung kursiv gedruckt ):Wenn eine
USE
Anweisung überprüft werden kann,ApplicationIntent
muss sie nach dem ersten Verbindungsversuch vorhanden sein. Ich habe dieses Verhalten jedoch nicht persönlich überprüft.PS Ich hatte gedacht, wir könnten die Fakten nutzen, die:
USE
Anweisung ausgeführt wird.Die Idee war, eine neue Datenbank zu erstellen, um diese Einstellung zu testen und zu verfolgen. Die neue Datenbank würde in einer neuen Verfügbarkeitsgruppe verwendet, die nur
READ_WRITE
Verbindungen zulässt . Die Theorie war, dass innerhalb eines Logon-Triggers, einesEXEC(N'USE [ReadWriteOnly]; INSERT INTO LogTable...;');
innerhalb einesTRY...CATCH
Konstrukts, mit im Wesentlichen nichts imCATCH
Block, entweder kein Fehler für ReadWrite-Verbindungen (die sich in der neuen DB anmelden würden) oder der Fehler für ReadOnly-Verbindungen erzeugt würdeUSE
, aber dann würde nichts passieren, da der Fehler abgefangen und ignoriert wird (und dieINSERT
Aussage niemals erreicht würde). In beiden Fällen wird das tatsächliche Anmeldeereignis nicht verhindert / verweigert. Der Anmelde-Trigger-Code wäre effektiv:Leider stellte ich beim Testen der Auswirkung der Ausgabe einer
USE
Anweisung inEXEC()
einemTRY...CATCH
Inneren einer Transaktion fest, dass die Zugriffsverletzung ein Abbruch auf Stapelebene und kein Abbruch auf Anweisungsebene war. Und die EinstellungXACT_ABORT OFF
hat nichts geändert. Ich habe sogar eine einfache gespeicherte SQLCLR-Prozedur erstellt, die verwendetContext Connection = true;
und dannSqlConnection.ChangeDatabase()
innerhalb von a aufgerufen wurde,try...catch
und die Transaktion wurde dennoch abgebrochen. Und Sie können nichtEnlist=false
für die Kontextverbindung verwenden. Die Verwendung einer regulären / externen Verbindung in SQLCLR zum Verlassen der Transaktion würde nicht helfen, da es sich um eine ganz neue Verbindung handeln würde.Es gibt eine sehr, sehr geringe Möglichkeit, dass HAS_DBACCESS anstelle der
USE
Anweisung verwendet werden könnte, aber ich habe wirklich keine großen Hoffnungen, dass es in der Lage ist, aktuelle Verbindungsinformationen in seine Prüfungen einzubeziehen. Aber ich kann es auch nicht testen.Natürlich sollte der oben erwähnte Plan funktionieren, wenn es ein Ablaufverfolgungsflag gibt, das dazu führen kann, dass die Zugriffsverletzung nicht stapelweise abgebrochen wird ;-).
quelle
ROLLBACK
im Login-TriggerINSERT
in eine Protokolltabelle :-)Wie krank möchtest du sein? Der TDS-Stream ist nicht so schwer zu proxen, wir haben es für unsere SaaS-App gemacht. Das gesuchte Bit (im wahrsten Sinne des Wortes ein bisschen) ist in der login7-Nachricht enthalten. Sie könnten Ihre Benutzer über einen Proxy verbinden und das Bit dort protokollieren / erzwingen lassen. Zum Teufel, du könntest es sogar für sie einschalten. :)
quelle
Verwendet Ihre Anwendung ein Dienstkonto oder mehrere Dienstkonten? Verwenden Sie in diesem Fall Extended Event, um Ihren Anmeldeverkehr zu überwachen, schließen Sie jedoch Ihre Dienstkonten auf Ihrem primären Always-On-Server aus. Sie sollten jetzt in der Lage sein zu sehen, wer sich auf dem primären Always-On-Server anmeldet und nicht die schreibgeschützte sekundäre Verbindungszeichenfolge verwendet. Ich bereite mich auf die Installation von Always-On vor und werde dies tun, sofern Sie mir nicht mitteilen, dass dies nicht funktioniert.
quelle
Leider habe ich nicht die Umgebung, um Folgendes zu testen, und es gibt zweifellos mehrere Punkte, an denen es fehlschlagen kann, aber ich werde es für das, was es wert ist, da rausschmeißen.
Eine gespeicherte CLR-Prozedur hat über das
new SqlConnection("context connection=true")
Konstrukt Zugriff auf die aktuelle Verbindung (von hier aus ). Der SqlConnection-Typ macht eine ConnectionString- Eigenschaft verfügbar . Da ApplicationIntent in der anfänglichen Verbindungszeichenfolge enthalten ist, wird diese vermutlich in dieser Eigenschaft verfügbar sein und kann analysiert werden. Natürlich gibt es eine Menge Übergaben in dieser Kette, so viele Möglichkeiten, dass alles birnenförmig wird.Dies würde von einem Anmeldetrigger ausgeführt, und die erforderlichen Werte würden nach Bedarf beibehalten.
quelle