Gibt es eine Zeitüberschreitung für eine Abfrage über eine Datenbankverbindung?


11

Bearbeiten / Vorwort: Diese Frage wurde von SO migriert, da mich die Frage zu Zeitüberschreitungen bei DB-Link-Abfragen besonders interessiert. Die von SO bereitgestellte Problemumgehung ist in Ordnung, aber die Frage selbst interessiert mich sehr.

Motivation:
Ich hatte eine Abfrage "für immer" (mehr als 2 Tage, bis ich die Sitzung beendet habe), die einen Datenbanklink verwendete. Das Problem schien zu sein, dass die entfernte Datenbank nicht mehr verfügbar war und aus einem noch unbekannten Grund nein ausgelöst ORA-02068wurde (hier nicht zu diskutieren) und die Abfrage nur wartete und wartete.

(Die Abfrage wird von einem dbms_scheduler-Job ausgegeben, der eine Prozedur in einem PL / SQL-Paket ausführt. Infolgedessen blieb der Job ebenfalls hängen. Dies ist jedoch für den Kern dieser Frage nicht von besonderem Interesse.)

Ich habe diese Situation simuliert, indem ich eine meiner Test-DBs in den Ruhemodus versetzt und über eine Datenbankverbindung abgefragt habe. Wie erwartet wartete die Abfrage, bis sie entweder manuell abgebrochen oder die Remote-Datenbank nicht mehr stillgelegt wurde.

Frage:
Ich habe keine Kontrolle über das Verhalten und die Verfügbarkeit der entfernten Datenbank. Daher suche ich nach einer Möglichkeit, ein Zeitlimit für eine Abfrage festzulegen, die eine Datenbankverbindung verwendet.

Ich habe bereits Profile ( CPU_PER_CALLusw.) und sqlnet.oraParameter untersucht, lokale Benennungsparameter direkt in die Verbindungszeichenfolge eingefügt (z. B. das Hinzufügen (connect_timeout=10)zur Datenbankverbindungsdefinition) und einen Befehl mit ausgeführt ... for update wait 1, aber sie funktionieren entweder für ausgelastete oder inaktive Sitzungen, jedoch nicht für wartende Sitzungen.

Ich bin also auf der Suche nach einer Option auf der "lokalen" Seite der Datenbankverknüpfung, die eine Zeitüberschreitung für Abfragen über Datenbankverknüpfungen festlegt.
Einige Lösungen mögen alter session set xyzoder select ... from a@b "wait 100" --(yes, I know this syntax doesn't exist)wären willkommen, da ich keine DBA-Rechte für diese bestimmten DBs habe.

Ich bin derzeit auf 10gR2, aber ein Upgrade auf 11gR2 in ein paar Wochen, daher sind Ideen für jede dieser Versionen hilfreich.


Wie wird die Abfrage verwendet? Teil einer größeren Prozedur / eines größeren Pakets, zugrunde liegendes SQL für eine Mattenansicht, wird von einer externen App ausgeführt, ...? Ich kenne keine einfache "wait xxx" -Syntax. Ihre Lösung muss möglicherweise Teil eines größeren Programms sein. Dies hängt von Ihrer Verwendung ab.

Die Abfrage wird von einem dbms_scheduler-Job ausgegeben, der eine Prozedur in einem PL / SQL-Paket ausführt. (aktualisierte Frage damit)
GWu

Antworten:


4

Da Sie dbms_scheduler verwenden, können Sie das Attribut max_run_duration des Jobs auf ein bestimmtes Limit festlegen und sich dann vom Scheduler eine E-Mail senden lassen, wenn dieses Ereignis ausgelöst wird . Hinter den Kulissen Oracle verwendet Warteschlangentabellen (mit denen Sie Jobs erstellen können, die beim Auslösen eines Ereignisses ausgelöst werden , wenn Sie die zusätzlichen Schritte zur Automatisierung Ihrer Antwort ausführen möchten). Grundsätzlich löst jedoch jeder Job, der über die von Ihnen eingerichtete max_run_duration ausgeführt wird, den Ereignistyp JOB_OVER_MAX_DUR aus

Das E-Mail-Stück ist in 11gr2 gebaut, siehe hier für eine gute Beschreibung.

Ich hoffe, das hilft.


tolle Idee, danke! Es ist nicht gerade eine Antwort auf die spezifische Frage zum Timeout bei DB-Links, aber ich denke, es löst mein anfängliches Problem trotzdem, also +1 :-). Ich wusste nichts von max_run_duration und von da an habe ich gerade herausgefunden, wie man den hängen gebliebenen Job stoppt
löscht

Aus irgendeinem Grund kann ich nicht bekommen , max_run_durationum das Ereignis zu erhöhen, so dass ich eine neue Frage gegabelt hier
GWu

0

Ich sage nicht, dass ich eine Lösung habe, aber ich möchte auch mehr darüber diskutieren, wie ein Dblink-Timeout gesteuert werden kann. Ich nehme an, es könnte denkbar sein, Code zu schreiben, der ein Ereignis auslöst oder auf ein TNS-Timeout-Ereignis wartet und dann Folgendes ausführt:

ALTER SESSION CLOSE DATABASE LINK dblink;

Sie können den Remote-Server natürlich vorher abfragen mit:

select * from dual@dblink

um zu überprüfen, ob es verfügbar ist, aber das behebt nicht das Problem, dass Code auf der Fernbedienung zu lange ausgeführt wird. Der fehlerhafte Remote-Code sollte Warteereignisse auslösen, daher könnten diese möglicherweise abgefangen werden (sogar auf Klassenebene in 12c). Das gibt uns immer noch keine elegante Lösung, um eine Dblink-Sitzung zum Timeout zu zwingen.

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.