Auswahl  

 

Oracle
DBA
12.1, 12.2
25.06.18 (MP)
25.06.18 (MP)
DBA, Oracle Tuning

Body

STATSPACK ist ein, mit jeder Oracle Datenbank mitgeliefertes, kostenloses Tool zur Auswertung der Performance. Die meisten Datenbank-Administratoren, die schon einmal mit einem Performance-Problem konfrontiert wurden, haben mit Sicherheit einen STATSPACK-Report erzeugt und diesen analysiert.

Dieser Tipp setzt Grundwissen in der Benutzung von STATSPACK und SQL vorraus. Falls Sie Hilfe zu STATSPACK benötigen, sollten Sie zuerst diesen Tipp lesen.

Reports über größere Zeiträume und mehere Snap-IDs hinweg sind sehr ungenau und nicht für eine präzise Analyse geeignet. Wenn man einen einzelnen Wert über den Tag analysieren will und das möglichst detailliert, kann es dazu kommen, dass Sie sehr viele Reports erzeugen und analysieren müssen. Um die Übersicht zu behalten, wird man in der Regel einen Kompromiss eingehen und zum Beispiel nur für jede Stunde einen Report erzeugen.

An sich ist es aber relativ einfach, die benötigten Informationen auf eine übersichtliche Anzahl an Zeilen zu reduzieren.

Der Lösungsansatz dafür ist einfach, jedoch erfordert die Umsetzung mehr Einarbeitung. Alle Daten, die für einen Report verwendet werden, sind in den Tabellen des STATSPACK-Users gespeichert. Das heißt, die Informationen sollten sich ohne Probleme in einem "eigenen" Report anhand von SQL ermitteln lassen.

Mit den zahlreichen Varianten und Möglichkeiten, könnte man wahrscheinlich ein ganzes Buch füllen. Deswegen werden wir uns in diesem Tipp nur mit den Grundlagen, einem einfachen und einem komplexeren Beispiel beschäftigen.

Dieser Tipp soll somit mehr als ein Denkanstoß zur Entwicklung individueller Lösungen, als eine komplette Anleitung aufgefasst werden.

GRUNDLAGEN

Der Perfstat-User hat um die 70 Tabellen. Die meisten Tabellen haben einen sprechenden Namen, der durchaus Rückschlüsse auf die Inhalte ermöglicht:

SQL> select TABLE_NAME from dba_tables where owner='PERFSTAT';
TABLE_NAME
-------------------------
STATS$LATCH_PARENT
STATS$SNAPSHOT
...
STATS$DATABASE_INSTANCE
...
STATS$SYSSTAT
.....
STATS$TEMP_SQLSTATS

Die wichtiges Tabelle ist STATS$SNAPSHOT. Sie ist Dreh- und Angelpunkt jedes Selects, da sie SNAP_IDund SNAP_TIME enthält.

Generell ist auch noch zu beachten: Sollte zwischen zwei Snapshots ein Neustart liegen, sind die Daten meist nicht verwendbar.

Am Anfang kann es sich als mühsam erweisen, ein Vorgehen zu entwickeln, wie man grundlegend an die gewünschten Daten gelangt. Hier hilft ein Blick in das Report-Script (befindet sich in der Regel im Oracle Home unter rdbms/admin/spreport.sql). Dort muss man sich dann bis zur entsprechenden Stelle, an der die benötigten Daten abgefragt werden, "durchhangeln" und kann sich dort dann "inspirieren" lassen, wie es diese Daten abzufragen gilt.

Hierzu nun zwei Beispiele:

 

EINFACHES BEISPIEL

Mit folgendem Select können Sie einfach ermitteln, wie viele angemeldete User es zum Snapshot-Zeitpunkt auf der Datenbank gab:

SELECT
   s.snap_time as "Uhrzeit",
   st.value as "Current Logons"
FROM
   perfstat.stats$snapshot s,
   perfstat.stats$sysstat st
WHERE
   s.snap_id=st.snap_id and
   st.name='logons current'
ORDER BY
   s.snap_time;

Die Tabellen STATS$SNAPSHOT und STATS$SYSSTAT werden gejoint und es wird aus der STATS$SYSSTAT Tabelle auf die Werte für 'logons current' eingeschränkt.

Der Output könnte wie folgt aussehen:

Uhrzeit             Current Logons
------------------- --------------
16.06.2016 11:10:57             56
16.06.2016 11:26:20             39
16.06.2016 11:41:25             37
16.06.2016 11:56:30             37
16.06.2016 12:11:35             37
16.06.2016 12:26:41             37
16.06.2016 12:41:46             37
16.06.2016 12:56:51             37
16.06.2016 13:11:56             37
.....
17.06.2016 09:03:49             36
17.06.2016 09:18:54             47
17.06.2016 09:33:59             36
17.06.2016 09:49:04             35
17.06.2016 10:04:10             36
17.06.2016 10:19:15             52
17.06.2016 10:34:20             36
17.06.2016 10:49:25             36
17.06.2016 11:04:30             36
17.06.2016 11:19:35             99

Aus der Ausgabe könnten Sie zum Beispiel die Peak-Zeiten der Datenbank auslesen, insofern Sie nicht einen App-Server haben, der die Verbindungen poolt. (Connection-Pooling)

 

KOMPLEXES BEISPIEL

Folgender Select ist komplexer und berücksichtigt mehrere Extras, die das einfache Beispiel nicht benötigt:

set linesize 1000
set pagesize 1000
alter session set nls_date_format = 'DD.MM.YYYY HH24:MI:SS';
col Begintime for a21 heading 'Von'
col endtime for a21 heading 'Bis'
col fh for 9999999999999 heading 'Failed Parses'
col th for 9999999999999 heading 'Total Parses'
select * from (
select
   s.snap_time as begintime,
   lead(s.snap_time,1, s.snap_time) over (order by snap_time) as endtime,
   f.fh,
   t.th
from
   perfstat.stats$snapshot s,
   (
      select
         snap_id,
         lead(value, 1, 0) over (order by snap_id)-value as fh
      from
         perfstat.stats$sysstat
      where
         lower(name)='parse count (failures)'
    ) f,
    (
      select
         snap_id,
         lead(value, 1, 0) over (order by snap_id)-value as th
      from
         perfstat.stats$sysstat
      where
         lower(name)='parse count (total)'
    ) t
where
   t.snap_id=s.snap_id and
   s.snap_id=f.snap_id and
   t.snap_id=f.snap_id
order by
   s.snap_time)
where
   begintime<>endtime and
   (fh>=0 or th>=0);

Die Ausgabe könnte wie folgt aussehen:

Von                   Bis                    Failed Parses   Total Parses
--------------------- --------------------- -------------- --------------
16.06.2016 11:10:57   16.06.2016 11:26:20                6           9030
16.06.2016 11:26:20   16.06.2016 11:41:25                1           4866
16.06.2016 11:41:25   16.06.2016 11:56:30                2            966
16.06.2016 11:56:30   16.06.2016 12:11:35                0           3948
16.06.2016 12:11:35   16.06.2016 12:26:41                0            897
16.06.2016 12:26:41   16.06.2016 12:41:46                0            922
16.06.2016 12:41:46   16.06.2016 12:56:51                0            901
16.06.2016 12:56:51   16.06.2016 13:11:56                0           3362
16.06.2016 13:11:56   16.06.2016 13:27:01                0            894
...
17.06.2016 09:03:49   17.06.2016 09:18:54                0            921
17.06.2016 09:18:54   17.06.2016 09:33:59                0            893
17.06.2016 09:33:59   17.06.2016 09:49:04                0            944
17.06.2016 09:49:04   17.06.2016 10:04:10                5           4030
17.06.2016 10:04:10   17.06.2016 10:19:15                0            958
17.06.2016 10:19:15   17.06.2016 10:34:20                0            885
17.06.2016 10:34:20   17.06.2016 10:49:25                0            938
17.06.2016 10:49:25   17.06.2016 11:04:30                0           3927
17.06.2016 11:04:30   17.06.2016 11:19:35                0           1015
17.06.2016 11:19:35   17.06.2016 11:34:40                0          11814

Da "Total Parses" und "Failed Parses" kumulativ seit Instanzstart gespeichert werden, muss man hier mit lead oder lag arbeiten, damit man nur die Werte pro Zeitabschnitt erhält. Sollen beide Werte in einer Zeile stehen, werden die entsprechenden Selects in Subselects verpackt.

Failed Parses sind vor allem interessant, um Applikationen zu finden, die zum Beispiel nicht vorhandene Tabellen abfragen (Eine Abfrage auf eine nicht vorhandene Tabelle gibt einen Failed Parse.).

Falls Sie Hilfe bei der Erstellung oder Interpretation benötigen, können Sie sich gerne an uns wenden, wir helfen Ihnen gerne.

Besuchen Sie uns doch bei einer unsere über 40 Oracle Schulungen in München - Unterhaching.