Raport AWR to kopalnia wiedzy o wydajności Oracle Database, ale bez właściwej metodyki analizy łatwo utknąć w gąszczu liczb. Pokażę Ci, jak w kilka minut dotrzeć do sedna problemu.

Oracle AWR: jak czytać raport i nie zgubić się w tysiącach statystyk
Kluczowe punkty
  • AWR to historyczne repozytorium statystyk wydajnościowych zbieranych automatycznie co godzinę
  • Analiza powinna zaczynać się od DB Time i Top Wait Events, nie od przeglądania wszystkich sekcji
  • Stosunek DB Time do DB CPU natychmiast wskazuje kategorię problemu: CPU, I/O czy blokady
  • Ranking Top SQL według elapsed time jest ważniejszy niż ranking według liczby wykonań

Czym jest AWR i dlaczego ma znaczenie

Automatic Workload Repository to wbudowany mechanizm Oracle Database, który automatycznie zbiera i przechowuje statystyki wydajnościowe instancji. AWR działa w tle, wykonując co godzinę tzw. snapshoty, czyli migawki stanu bazy danych. Każdy snapshot zawiera tysiące metryk: od statystyk systemowych, przez informacje o sesjach, aż po szczegółowe dane o wykonywanych zapytaniach SQL.

Architektura AWR opiera się na tabelach przechowywanych w schemacie SYS, w tablespace SYSAUX. Domyślnie Oracle przechowuje snapshoty przez 8 dni, choć wartość tę można modyfikować za pomocą procedury DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS. W środowiskach produkcyjnych często zwiększam retencję do 30 dni, co pozwala analizować trendy miesięczne i porównywać wydajność w różnych okresach.

Kluczowa zaleta AWR polega na tym, że dane zbierane są niezależnie od tego, czy administrator aktualnie monitoruje system. Gdy użytkownicy zgłaszają problem wydajnościowy, który wystąpił wczoraj o 15:00, mamy pełen dostęp do statystyk z tego okresu. To fundamentalna różnica w porównaniu z monitorowaniem w czasie rzeczywistym.

Generowanie raportu: tutaj zaczynają się błędy

Raport AWR generujemy najczęściej za pomocą skryptu awrrpt.sql znajdującego się w katalogu $ORACLE_HOME/rdbms/admin. Po uruchomieniu skrypt pyta o format wyjściowy (HTML lub tekst), a następnie o zakres czasowy określony przez dwa snapshoty: początkowy i końcowy.

Pierwszy poważny błąd, który widzę regularnie, to generowanie raportu z całego dnia. Raport obejmujący 24 godziny uśrednia wszystkie statystyki i może całkowicie ukryć problem trwający godzinę. Jeśli użytkownik zgłasza spowolnienie między 14:00 a 15:00, raport powinien obejmować właśnie ten okres, maksymalnie z niewielkim marginesem.

Drugi błąd to porównywanie snapshotów z różnych dni bez uwzględnienia specyfiki obciążenia. Snapshot z niedzieli o 3:00 w nocy i snapshot z poniedziałku o 10:00 rano pochodzą z zupełnie innych światów wydajnościowych. Do analizy porównawczej służy oddzielny raport: AWR Diff Report generowany skryptem awrddrpt.sql.

Metodyka szybkiej analizy: nie czytaj wszystkiego

Raport AWR w formacie HTML może mieć kilkadziesiąt stron. Próba przeczytania go od początku do końca to strata czasu i gwarancja pominięcia istotnych informacji. Przez lata wypracowałem metodykę, która pozwala w ciągu 5 minut określić kategorię problemu.

Zawsze zaczynam od sekcji Report Summary, konkretnie od wartości DB Time. Jeśli DB Time wynosi 3600 sekund przy raporcie godzinnym dla systemu z 4 rdzeniami, to oznacza średnio jeden aktywny wątek. Jeśli wynosi 14400 sekund, mamy cztery w pełni obciążone rdzenie. Ta jedna liczba natychmiast mówi mi o skali problemu.

Następnie przechodzę do sekcji Top 10 Foreground Events by Total Wait Time. To właśnie Wait Events stanowią fundament diagnostyki Oracle i wskazują, na co baza danych rzeczywiście czeka. Dopiero po zrozumieniu kategorii problemu zagłębiam się w szczegółowe sekcje.

Wait Events: fundament diagnostyki Oracle

Oracle rejestruje każde zdarzenie, podczas którego sesja musiała czekać na zasób. Wait Events dzielą się na klasy: User I/O, System I/O, Concurrency, Application, Network i inne. Sama nazwa zdarzenia często wskazuje bezpośrednio na przyczynę problemu.

Najczęściej spotykane zdarzenia oczekiwania to db file sequential read (odczyty pojedynczych bloków, typowe dla dostępu indeksowego), db file scattered read (odczyty wieloblokowe, typowe dla full scanów), log file sync (oczekiwanie na zapis do redo logów przy COMMIT) oraz enq: TX row lock contention (blokady wierszy między sesjami).

Interpretacja Wait Events wymaga kontekstu. Zdarzenie db file sequential read na pierwszym miejscu nie oznacza automatycznie problemu z I/O. Jeśli średni czas oczekiwania wynosi 1 ms, a łączny czas to 500 sekund przy 500 000 odczytów, to dyski działają prawidłowo. Problem leży w liczbie odczytów, czyli prawdopodobnie w nieefektywnych zapytaniach lub brakujących indeksach.

DB Time kontra DB CPU: klucz do kategoryzacji

DB Time to łączny czas spędzony przez wszystkie sesje foreground na pracy lub oczekiwaniu. DB CPU to część DB Time spędzona wyłącznie na wykorzystaniu procesora. Różnica między tymi wartościami to czas oczekiwania na zasoby.

Przykład praktyczny: DB Time = 7200 sekund, DB CPU = 1800 sekund. Oznacza to, że 25% czasu baza pracowała na CPU, a 75% czekała na coś innego. Sekcja Top Wait Events powie nam, na co dokładnie. Gdyby proporcje były odwrotne (DB CPU stanowi 90% DB Time), problem leżałby po stronie procesora lub nieefektywnych zapytań wykonujących zbyt wiele operacji.

Ta prosta analiza natychmiast kieruje dalsze poszukiwania. Wysoki udział I/O wait prowadzi do analizy storage i planów wykonania. Wysoki udział Concurrency wait sugeruje problemy z blokowaniem. Wysoki DB CPU przy stosunkowo niskim throughput wskazuje na nieefektywne zapytania.

Top SQL: znajdź winowajców

Sekcja SQL Statistics zawiera kilka rankingów tego samego zbioru zapytań, posortowanych według różnych kryteriów. Każdy ranking odpowiada na inne pytanie diagnostyczne.

SQL ordered by Elapsed Time pokazuje zapytania konsumujące najwięcej łącznego czasu. To najważniejszy ranking, bo czas to zasób, który użytkownicy bezpośrednio odczuwają. SQL ordered by CPU Time identyfikuje zapytania obciążające procesor. SQL ordered by Gets pokazuje zapytania wykonujące najwięcej odczytów logicznych z buffer cache, co często koreluje z nieefektywnymi planami wykonania.

Szczególnie wartościowy jest stosunek elapsed time do executions. Zapytanie wykonane 1 000 000 razy po 0.001 sekundy to zupełnie inna sytuacja niż zapytanie wykonane 100 razy po 10 sekund, mimo że łączny czas jest podobny. Pierwsze wymaga optymalizacji przez redukcję wywołań (może batching?), drugie przez poprawę planu wykonania.

Pułapki interpretacyjne: czego nie robić

Najczęstszy błąd to wyciąganie wniosków z pojedynczej statystyki bez kontekstu. Widziałem administratorów panikujących z powodu wysokiego buffer busy waits, podczas gdy stanowiło to 2% DB Time przy systemie działającym bez zarzutu. Każda statystyka ma znaczenie tylko w relacji do innych.

Drugi częsty błąd to przypisywanie winy zapytaniu na szczycie rankingu bez analizy, czy to zapytanie jest rzeczywiście nieefektywne. Zapytanie przetwarzające miliony wierszy z hurtowni danych będzie zawsze wysoko w rankingach. Pytanie brzmi: czy robi to optymalnie?

Trzeci błąd to ignorowanie sekcji Instance Activity Stats i Operating System Statistics. Jeśli system operacyjny raportuje wysokie wykorzystanie CPU przez procesy inne niż Oracle, problem może leżeć całkowicie poza bazą danych.

Przypadek z praktyki: analiza krok po kroku

Użytkownicy zgłosili spowolnienie systemu ERP między 10:00 a 11:00. Wygenerowałem raport AWR dla tego okresu. DB Time wyniósł 28 000 sekund przy systemie z 8 rdzeniami (maksymalnie 3600 sekund na rdzeń, czyli 28 800 sekund). System był praktycznie wysycony.

Top Wait Events pokazał: enq: TX row lock contention (45% DB Time), db file sequential read (30% DB Time), DB CPU (20% DB Time). Dominujące blokowanie wierszy wymagało dalszej analizy.

Przeszedłem do sekcji SQL ordered by Elapsed Time. Na pierwszym miejscu znajdowało się zapytanie UPDATE z elapsed time 12 000 sekund. Sprawdziłem jego plan wykonania w sekcji SQL Execution Plans: full table scan na tabeli z 50 milionami wierszy, brak wykorzystania indeksu na kolumnie WHERE.

Rozwiązanie okazało się proste: dodanie brakującego indeksu złożonego. Po zmianie czas wykonania UPDATE spadł z minut do milisekund, blokady zniknęły, a kolejny raport AWR pokazał DB Time na poziomie 4000 sekund.

Co dalej: narzędzia uzupełniające

AWR daje obraz historyczny zagregowany do poziomu snapshotów. Dla analizy w rozdzielczości sekundowej służy Active Session History (ASH), dostępne przez raport ashrpt.sql. ASH przechowuje próbki aktywnych sesji co sekundę.

ADDM (Automatic Database Diagnostic Monitor) to mechanizm automatycznie analizujący dane AWR i generujący rekomendacje. Warto traktować go jako punkt wyjścia, nie jako wyrocznię. SQL Monitor dostarcza szczegółowych informacji o aktualnie wykonywanych lub niedawno zakończonych zapytaniach, włącznie z rzeczywistymi statystykami wykonania.

Raport AWR przestaje być przytłaczający, gdy zastosujesz systematyczną metodykę analizy. Zacznij od DB Time i Top Wait Events, ustal kategorię problemu, a dopiero potem zagłębiaj się w szczegóły. Pamiętaj, że każda statystyka ma znaczenie tylko w kontekście innych metryk i charakterystyki twojego systemu.