In historisch gewachsenen Datenbank-Landschaften mit vielen Datenbanken kommt es häufig vor, dass die einzelnen Datenbanken über Datenbank-Links verbunden sind. Das kann in Umgebungen mit vielen Benutzern und Datenbanken schnell sehr komplexe Züge annehmen, da auch oft die Verlinkungen mehrfach vorhanden sind, denn ein Public-Datenbank-Link ist sicherheitstechnisch nicht erlaubt. Nun kann das Ermitteln bei allgemeinen und Performance-Problemen in diesem Fall sehr mühsam und verzweigt sein. Vor allem wenn es sich um eine stark frequentierte Datenbank handelt und Sie nicht über ein Ausschlussverfahren die nötige Gewissheit erreichen können.
An dieser Stelle vorerst ein kleiner Hinweis:
Wenn Sie in diesen Umgebungen Daten selektieren, vor allem wenn es sich um aneinandergereihte Datenbank-Links handelt, wie z. B. SELECT auf eine View über Datenbank-Link die wiederrum einen oder mehrere SELECTs auf andere Datenbank-Links usw. beinhaltet:
Überprüfen Sie immer aufs Genauste woher die Daten, die Sie selektieren, stammen! Im ungünstigsten Fall stammen diese von Ihrer eigenen Datenbank und Ihr SELECT ist unnötigerweise durch mehrere Datenbanken und mehrmals durch das Netzwerk geschleust worden.
Wissenswert an dieser Stelle zu Datenbank-Links ist des Weiteren, dass selbst ein SELECT über einen Datenbank-Link sowohl in der Quelle wie auch im Ziel eine Transaktion generiert.
Es gibt zwei grobe Varianten wenn man in diesen Umgebungen mit Szenarien über Datenbank-Links ein Problem hat:
Variante 1: Man kennt die Quelle und möchte das Ziel genauer analysieren, z. B. ein SELECT mit einem Datenbank-Link.
Variante 2: Man kennt das Ziel und möchte wissen was der Auslöser ist, z. B. eine Session in der Ziel-Datenbank, die durch ihren Ressourcen-Hunger andere Sessions ausbremst oder sogar ganz blockiert.
Variante 1 ist natürlich einfach zu bewerkstelligen, kann in größeren Umgebungen aber ein verwirrendes Ausmaß annehmen. Dazu muss man jeden Datenbank-Link folgen (bei Szenarien mit mehr als zwei Datenbanken, meist im Viewtext enthalten) bis schlussendlich nur noch eine normale lokale Tabelle dahinter steht.
Wie Sie in der zweiten Variante den "Übeltäter" finden wird nun folgend beschrieben. Wenn Sie den "Übeltäter" gefunden haben, startet die normale Performance- oder Fehler-Analyse. Für diese Demonstration wird folgende Umgebung verwendet:
Drei 12c Datenbanken (SIDs: PERSONENDB, FIRMENDB, STANDORTDB) mit drei Usern (Namen: PERSONENUSER, FIRMENUSER, STANDORTUSER) auf drei Servern (Hostnamen: PERSONENHOST, FIRMENHOST, STANDORTHOST)
Folgender SELECT ist das wichtigste Werkzeug für das Verfolgen des Datenbank-Links. Dieser wird folgend nur als "Global Transaction Select" bezeichnet:
SET LINESIZE 200
COL SID FOR 99999
COL User FOR a20
COL Host FOR a20
COL "Global TX ID" FOR a30
COL "Wait Event" FOR a50
SELECT
S.SID "SID",
S.USERNAME "User",
U.KSUSEMNM "Host",
G.K2GTITID_ORA "Global TX ID",
W.EVENT "Wait Event"
FROM
X$K2GTE G,
X$KSUSE U,
V$SESSION_WAIT W,
V$SESSION S
WHERE
U.ADDR=G.K2GTDSES AND
S.SID=U.INDX AND
W.SID=S.SID
ORDER BY
2,3
/
Wenn Sie die Ausgabe des Selects verstanden haben kann dieser Ihnen auch bei der Analyse der Variante 1 nützliche Informationen liefern. Vorallem wenn es zu Abzweigungen der Datenbanken-Links kommt.
GLOBAL TRANSACTION SELECT AUSGABE
Als erstes ein simples Beispiel, um die Ausgabe des oben erwähnten SELECTs zu erklären.
Erstes Szenario: Der User FIRMENUSER selektiert die Tabelle PERSONENTABLE über den Datenbank-Link PERSONENLINK und beendet diese Session vorerst nicht.
FIRMENUSER@FIRMENDB - SQL> select * from personentable@personenlink;
ID
----------
1
2
3
4
5
5 rows selected.
Wenn Sie nun ein zweite Session als SYS-Benutzer aufmachen und den Global Transaction Select ausführen erhalten wir folgendes Ergebnis:
Quelle:
SID User Host Global TX ID Wait Event
------ -------------------- -------------------- ------------------------------ --------------------------------------------------
67 FIRMENUSER FIRMENHOST FIRMENDB.fe9da486.5.29.6585 SQL*Net message from client
Nun sollten Sie auf der Ziel-Datenbank ebenfalls diesen Select als SYS-Benutzer ausführen:
Ziel:
SID User Host Global TX ID Wait Event
------ -------------------- -------------------- ------------------------------ --------------------------------------------------
35 PERSONENUSER FIRMENHOST FIRMENDB.fe9da486.5.29.6585 SQL*Net message from client
So eindeutige Ergebnisse gibt es natürlich nur in einer relativ leeren Testumgebung. Wenn Sie beim Global Transaction Select viele Ergebnisse zurück bekommen, sollten Sie diese über die SID einschränken. Die SID müssen Sie allerdings vorher ermitteln.
Erklärung der Spalten:
SID - Dieser Spalte enthält die auf der jeweiligen Instanz zugehörige SID der lokalen Session.
User - Enthält den Benutzer mit dem diese Session gestartet wurde.
Host - Enthält den Remote Host von dem diese Session aus gestartet wurde (bei längeren Ketten von Datenbank-Links ist das nicht zwangsläufig die ursprüngliche Quell.).
Global TX ID - Zeigt die Gobale Transaktions Identifikations Nummer. Diese ist über alle Instanzen gleich und das eindeutigste Kriterium, um den Weg des Datenbank-Links zu verfolgen. Sie beginnt immer mit der SID der Datenbank, auf der die erste Transaktion gestartet wurde.
Wait Event - Hier ist das derzeit aktuelle Wait Event der Session zu sehen.
Durch die SELECTs in diesem Beispiel wissen Sie nun, dass die Session mit der SID 67 in der Quell-Datenbank und die Session mit der SID 35 in der Ziel-Datenbank zusammen gehören und Sie könnten ihre Fehler- oder Performance Analyse starten.
KOMPLEXERES BEISPIEL
Szenario: Sie haben eine Session die andere Sessions massiv ausbremst. Von dieser Session wissen Sie die SID (417) und wollen nun in Erfahrung bringen woher diese Session stammt. Die erste Analyse hat ergeben, dass es sich um keine direkte Verbindung zur Datenbank handelt, sondern durch einen Datenbank-Link entstand.
In diesem Fall befinden Sie sich auf der Ziel-Datenbank und führen als SYS-Benutzer nun den Global Transaction Select durch.
In unserem Testfall erhalten wir folgendes Ergebnis:
SID User Host Global TX ID Wait Event
------ -------------------- -------------------- ------------------------------ --------------------------------------------------
417 STANDORTUSER FIRMENHOST PERSONENDB.fa233449.1.22.18169 SQL*Net message from client
Wie wir schon wissen, hat die Problem-Session die SID 417, die Session wurde mit dem User STANDORTUSER vom FIRMENHOST und einer Datenbank mit der SID PERSONENDB erstellt.
Nach kurzer Recherche steht fest, dass es auf dem FIRMENHOST keine Datenbank mit der SID PERSONENDB gibt! Auf den Host FIRMENHOST laufen mehrere Datenbanken. Ohne weiteres Wissen hilft erstmal nur raten und den Global Transaction Select auf jeder Datenbank dort auszuführen welche einen Datenbank-Link auf das schlussendliche Ziel hat, um einen Eintrag mit der gleichen Transaktions-Nummer zu finden.
Dank Murphy's Law werden wir erst auf der letzten Datenbank, die wir prüfen fündig und erhalten folgenden Ausgabe des Global Transaction Selects:
SID User Host Global TX ID Wait Event
------ -------------------- -------------------- ------------------------------ --------------------------------------------------
71 FIRMENUSER PERSONENHOST PERSONENDB.fa233449.1.22.18169 SQL*Net message from client
Die Global TX ID ist identisch, und somit handelt es sich um die gleiche globale Transaktion. In der Ausgabe sehen wir nun wieder einen neuen Host und einen neuen User. In diesem Fall sind wir scheinbar auch schon am Ende der Suche angekommen, denn es gibt auf dem Host PERSONENHOST eine Instanz mit der SID PERSONENDB.
In ihr setzten wir nun wiederrum als SYS-Benutzer den Global Transaction Select ab und erhalten das folgende Ergebnis:
SID User Host Global TX ID Wait Event
------ -------------------- -------------------- ------------------------------ --------------------------------------------------
266 PERSONENUSER PERSONENHOST PERSONENDB.fa233449.1.22.18169 SQL*Net message from client
Da die Datenbank-SID in der Global TX ID der Datenbank-SID der Instanz entspricht, auf der wir uns befinden und dies für den Host ebenfalls zutrifft, kann man davon ausgehen, dass wir die ursprüngliche Quelle gefunden haben. Jetzt können Sie über v$session weitere Informationen ermitteln und eine Problem- bzw. Performance Analyse starten.
Hier handelt es sich natürlich um sehr geradlinige Beispiele, die einfach zu ermitteln sind, da diese Test-Datenbanken kaum Sessions über Datenbank-Links aufweisen. Das Vorgehen zum Nachverfolgen von Transaktionen über Datenbank-Links bleibt in groben Zügen aber immer das selbe.