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-02068
wurde (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_CALL
usw.) und sqlnet.ora
Parameter 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 xyz
oder 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.
Antworten:
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.
quelle
max_run_duration
um das Ereignis zu erhöhen, so dass ich eine neue Frage gegabelt hierIch 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:
Sie können den Remote-Server natürlich vorher abfragen mit:
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.
quelle