9. September 2010

Information ist alles! DBMS_APPLICATION_INFO

Zum diesem Thema hatte ich vor langer Zeit zwar schonmal ein Blog-Posting, aber ich denke, dass es ein erneutes Posting durchaus wert ist.
Regarding today's topic I already had a blog posting long time ago. But this is IMHO so important that another posting is worth the effort.
Es geht darum, wie Ihr dem Datenbank-Administrator - schon während der Anwendungsentwicklung helfen könnt. Mit dem PL/SQL-Paket DBMS_APPLICATION_INFO. Das ist meiner Meinung nach eins der wichtigsten PL/SQL-Pakete für jeden Entwickler - egal ob man PL/SQL, Java, .NET, PHP oder andere Programmiersprachen verwendet.
I'll talk about DBMS_APPLICATION_INFO. With this package you can today - while developing your application - help the database administrator when it is about future debugging and tracing. This is one of the most important PL/SQL packages for application developers - for all developers regardless the programming language they use.
Mit DBMS_APPLICATION_INFO könnt Ihr eure Datenbanksitzung mit drei "Etiketten" versehen. Die Etikette heißen CLIENT_INFO, MODULE und ACTION. Was Ihr dort hineinschreibt, ist der Datenbank völlig egal. Die Informationen werden aber in allen Datenbank-Views, die der DBA zur Überwachung verwendet (also V$SQL, V$SESSION und andere) mit angezeigt. Dazu ein PL/SQL-Beispiel:
DBMS_APPLICATION_INFO allows you to set "markers" in the database session. Oracle provides three markers: CLIENT_INFO, MODULE and ACTION. You are allowed to set whatever value you want. The values you set are being recorded in all dynamic performance views the DBA uses (V$SQL, V$SQLAREA, V$SESSION and others. A PL/SQL example illustrates this.
begin
  dbms_application_info.set_client_info(
    client_info => 'MEINE_PLSQL_PROZEDUR'
  );
  dbms_application_info.set_module(
    module_name => 'MODUL 1',
    action_name => 'SCHLAFEN'
  );

  dbms_lock.sleep(100);

  dbms_application_info.set_client_info(
    client_info => ''
  );
  dbms_application_info.set_module(
    module_name => '',
    action_name => ''
  );
end;
/
sho err
Wenn der DBA nun (während diese Prozedur läuft), in die V$SESSION-View hineinsieht, werden diese Informationen mit angezeigt - in den Spalten CLIENT_INFO, ACTION und MODULE.
If the DBA (while this PL/SQL block is running) queries the V$SESSION view, he gets this information - it is contained in the columns CLIENT_INFO, ACTION and MODULE.
SQL> select sid, serial#, client_info, module, action
  2  from v$session where username='SCOTT'

       SID    SERIAL# CLIENT_INFO          MODULE     ACTION
---------- ---------- -------------------- ---------- ----------
        39       9780 MEINE_PLSQL_PROZEDUR MODUL 1    SCHLAFEN

1 Zeile wurde ausgewählt.
Man kann also sofort sehen, was eine Datenbanksitzung gerade tut. Das ist besonders wichtig, wenn Middleware im Einsatz ist, denn diese arbeitet normalerweise mit einem Connection-Pool, in dem alle Datenbanksitzungen mit dem gleichen Nutzerkonto arbeiten ... Und mit Java lässt sich DBMS_APPLICATION_INFO ebenfalls nutzen ...
The DBA can directly see what's going on in this very database session. This is particularly important when you have a three-tier-architecture with middleware involved. In those cases you have a connection pool where multiple database sessions are being opened with the same database user. Without DBMS_APPLICATION_USER the DBA cannot see which database session is doing which operation. DBMS_APPLICATION_INFO makes it transparent - and Java developers can (and should) also use it.
:
  Connection con = theDatasource.getConnection DBMS_APPLICATION_INFO();
  CallableStatement cstmt_ci = con.prepareCall("{call dbms_application_info.set_client_info(?)}");
  cstmt.setString(1, "JAVA_ANWENDUNG_1");
  ctsmt.execute();
  CallableStatement cstmt_mo = con.prepareCall("{call dbms_application_info.set_module(?,?)}");
  cstmt.setString(1, "MODUL 2");
  cstmt.setString(2, "JAVA BERECHNUNG");
  ctsmt.execute();
  :
Und mit allen anderen Programmiersprachen geht das analog. Die Nutzung dieser Informationen zieht sich übrigens durch alle Oracle-Werkzeuge - das folgende ist ein Screenshot aus dem Oracle Enterprise Manager. Dieses Werkzeug wird typischerweise vom DBA verwendet, um Informationen über die abgelaufenen SQL-Anweisungen zu erhalten. Und auch hier kann anhand MODULE und ACTION gesucht werden.
The same applies to all other programming languages. All Oracle tools use the Information provided with DBMS_APPLICATION_INFO. The following is a screenshot of Oracle's Enterprise Manager - the tool which many DBAs use the maintain the database. If they search for particular SQL statements Enterprise Manager allows to filter for ACTION or MODULE or both.

Ich kann nur wärmstens empfehlen, DBMS_APPLICATION_INFO immer und überall einzusetzen; wenn es mal später ans Tuning oder an den Betrieb der Applikation geht, wird der Aufwand doppelt und dreifach wieder zurückgezahlt - eben dadurch, dass sich Probleme schneller zuordnen und damit auch einfacher diagnostizieren lassen. Wenn Ihr das Package bislang also noch nicht genutzt habt: Fangt noch heute damit an.
If you're not using DBMS_APPLICATION_INFO - start using it today! You get additional efforts (if any) paid back doubled and tripled when it's about debugging, tracing or tuning the application.

Kommentare:

Anonym hat gesagt…

Man lernt nie aus, interessante Sache - vielen Dank!

Muss man die Parameter vor dem Ende der Ausführung wieder auf "leer" setzen? (siehe Codebeispiel)

Carsten Czarski hat gesagt…

Hallo,

mann muss nicht; kann aber sinnvoll sein; denn die Datenbank macht von sich aus nichts. Deine Einträge bleiben solange stehen, wie die Session existiert und solange sie nicht anderweitig überschrieben werden.

Um ein Beispiel zu nennen: APEX nutzt das Package auch intensiv und setzt nach Abschluß seiner Arbeit alles wieder auf SQL NULL.

Beste Grüße

-Carsten

Anonym hat gesagt…

Alles klar, vielen Dank. Sowas dachte ich mir schon, war mir aber nicht sicher, ob sich das nach Beendigung der Prozedur nicht direkt "erledigt" hat.

oraculix hat gesagt…

Hallo Carsten,

Wer seine Anwendungen in Java schreibt, muß nicht unbedingt die DBMS-Packages aufrufen. Oracles JDBC-Erweiterungen stellen die Methode oracle.jdbc.OracleConnection.setEndToEndMetrics() bereit, die die besprochenen Funktionen von DBMS_APPLICATION_INFO und DBMS_SESSION vereint.

Da erlaube ich mir mal etwas Werbung in eigener Sache :-), da ich mich von Deinem nunmehr zweiten Artikel zum Thema habe anspornen lassen, meinen alten Entwurf zu DBMS_SESSION auch endlich fertig zu stellen.

Ansonsten kann ich nur beipflichten: Diese einfache Methode, seine Anwendung fürs Troubleshooting zu instrumentieren, sollte jeder Entwickler beherzigen!

Viele Grüße,
Uwe

Ralf Flatau hat gesagt…

Hallo,

für die Identifizierung von z.B. Nutzern kann auch die Funktion DBMS_SESSION.SET_IDENTIFIER(varchar2); genutzt werden. Dabei wird er Wert in V$Session.client_identifier angezeigt und man kann ein Trace nur dafür einschalten.


Ralf Flatau

Beliebte Postings