Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Używanie LogMiner do znajdowania bieżących zmian

Może się zdarzyć, że konieczne będzie zbadanie ostatnich zmian w bazie danych i zgłoszenie tego, co zostało zmienione, kiedy i przez kogo. Od lat do takich zadań dostępny jest pakiet DBMS_LOGMNR Oracle, ale jego wywołania nie zostały w pełni pokryte. Konwencjonalne metody wykorzystują procedurę ADD_LOGFILE() w celu przygotowania Log Minera do użycia z podstawowym wywołaniem procedury START_LOGMNR. Spowoduje to uruchomienie narzędzia z bieżącym SCN jako punktem początkowym. Istnieje inny sposób uruchomienia Log Minera, wybierając prawidłowy początkowy SCN i dostarczając go do wywołania START_LOGMNR(). W tym artykule zobaczysz, jak można to zrobić, i w trakcie tego procesu ujawnisz możliwy obszar zainteresowania alokacją PGA.

Patrząc na skrypt „plain vanilla”, aby uruchomić Log Miner, wykonywane są zwykłe wywołania procedur, które uruchamiają Log Miner z bieżącym SCN:

---- run_logmnr.sql---- Dodaj pliki dziennika i ustaw DBMS_LOGMNR na-- ciągłe kopanie dzienników archiwum--ustaw rozmiar linii 200 buforów przycinania na rozmiar strony 0---- Dodaj istniejące pliki dziennika---- Pomiń pliki dzienników w trybie gotowości- -wybierz 'exec dbms_logmnr.add_logfile('''||członek||''')'z v$logfilewhere wpisz <> 'STANDBY'i członka (wybierz min(członek) z grupy v$logfile według grupy#)spool /tmp/add_logfiles.sql/spool off@/tmp/add_logfiles---- Uruchom logmnr w trybie kopania ciągłego--exec dbms_logmnr.start_logmnr(opcje => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG_ + DBMS_NUMLY_LOGUS_NRM) . 

Pamiętaj, że wszystkie dostępne dzienniki ponawiania są dodawane przed uruchomieniem Log Minera. Istnieje inna metoda, która dostarcza początkowy SCN do wywołania start_logmnr, o ile baza danych działa w trybie ARCHIVELOG:

BEGIN DBMS_LOGMNR.START_LOGMNR( startScn => , endScn => , OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY + DBMS_LOGMNR.); 

Co ciekawe, końcowy SCN nie jest konieczny do rozpoczęcia sesji Log Miner. Baza danych musi być w trybie ARCHIVELOG, aby można było określić opcję CONTINUOUS_MINE, ponieważ Log Miner automatycznie doda każdy dostępny zarchiwizowany plik dziennika podczas działania. Użycie tej metody pozwala na użycie określonego SCN do rozpoczęcia dowolnego wyszukiwania; określenie końcowego wyszukiwania nawiasów SCN, tak aby tylko ograniczony podzbiór danych był zwracany do widoku V$LOGMNR_CONTENTS i stanowił punkt zatrzymania wyszukiwania, dzięki czemu zapytanie widoku może zostać zakończone.

Monitorowanie postępu Log Minera to proste zadanie, sprawdzając dziennik alertów bazy danych, ponieważ wpisy oznaczone jako „LOGMINER” są rejestrowane. Kompletny wpis będzie zawierał linię BEGIN i END, jak pokazano poniżej:

Mon Oct 07 12:48:22 2019LOGMINER:Zakończ plik dziennika eksploracji dla sesji -2147482111 sekwencja wątku 1 9776, /oracle/archive/awcis/awcis_0000009776_0001_1008544071.arcMon Oct 07 12:48:22 2019LOGMINER:Rozpocznij plik dziennika eksploracji dla sesji - 2147482111 wątek 1 sekwencja 9777, /oracle/archive/awcis/awcis_0000009777_0001_1008544071.arcMon Oct 07 12:48:36 2019LOGMINER:Zakończ eksplorację logu dla sesji -2147482111 wątek 1 sekwencja 9777, /oracle/archive/awcis/awcis_00000097440_0001_10085Mon :48:36 2019LOGMINER:Rozpocznij logowanie dla sesji -2147482111, sekwencja wątku 1 9778, /oracle/archive/awcis/awcis_0000009778_0001_1008544071.arcMon Oct 07 12:48:49 oracle/archive/awcis/awcis_0000009778_0001_1008544071.arcMon Oct 07 12:48:49 2019LOGMINER:Rozpocznij wydobywanie dziennika dla sesji -2147482111 wątku 1 sekwencja 9779, /oracle/archive/awcis/awcis_0000009779_0001_1008544071.arc

W przypadku lokalnych sesji Oracle liczby są dodatnimi liczbami całkowitymi; dla sesji zdalnych, inicjowanych przez narzędzia takie jak Perl, Python, C/C++ lub inne języki, widoczne będą ujemne liczby całkowite (wpisy pokazane powyżej zostały zainicjowane przez skrypt Pythona). Nazwy plików dziennika będą przechodzić zarówno przez dzienniki przeróbek online, jak i dostępne kopie archiwalne.

Uruchamianie Log Minera w ten sposób może również powodować błędy, takie jak „brakujący plik dziennika”, gdy wybrany początkowy zakres SCN lub SCN nie jest już dostępny w strumieniu ponawiania. Długo działające zapytania mogą napotkać takie błędy. Dodatkowo, jeśli SCN jest poza zasięgiem dostępnych plików dziennika, Log Miner nie uruchomi się, rzucając:

BŁĄD w wierszu 1:ORA-01292:nie określono pliku dziennika dla bieżącej sesji LogMinerORA-06512:w „SYS.DBMS_LOGMNR”, wiersz 58ORA-06512:w wierszu 2

Aby pomóc w wyeliminowaniu takich błędów, wybranie FIRST_CHANGE# z widoku V$LOG zapewni prawidłowe punkty początkowe dla sesji Log Miner; użycie podobnego zapytania względem V$ARCHIVED_LOG zwróci wszystkie dostępne początkowe SCN dla zarchiwizowanych kopii ponawianych.

To nie jedyna komplikacja korzystania z Log Minera w ten sposób. W zależności od tego, ile informacji ma zostać zwróconych, proces Logmminer może przydzielić duże ilości pamięci PGA, co może, jeśli pga_aggregate_limit jest mały, zgłosić następujący błąd:

ORA-04036:Pamięć PGA używana przez instancję przekracza PGA_AGGREGATE_LIMIT

na szczęście nie jest to błąd krytyczny. Ponieważ zasoby PGA nie są już potrzebne, pamięć może zostać zwolniona z powrotem do bazy danych do wykorzystania w innym miejscu. Jednak zwolnienie tej pamięci z powrotem do puli pamięci może zająć trochę więcej czasu niż jest to pożądane. Opcją jest ustawienie pga_aggregate_limit na wyższą niż suma sesji Log Miner, co może zapobiec wystąpieniu błędu. Skąd wiesz, jaka pamięć jest przydzielona do tych sesji? W bazie danych dostępny jest widok V$PROCESS_MEMORY_DETAIL. Ale próba przeszukania tego widoku bez pewnych przygotowań zwróci:

nie wybrano wierszy.

Jest to stosunkowo niewielki problem, ale wymaga użycia narzędzia oradebug. Poniższe kroki załadują dane do V$PROCESS_MEMORY_DETAIL:

---- Ustaw identyfikator bieżącej sesji-- oradebug setmypid---- Używając PID żądanego procesu-- zrzuć dane pamięci---- To wypełnia V$PROCESS_MEMORY_DETAIL--oradebug pga_detail_get - --- Zapytanie o widok, aby uzyskać żądane dane--wybierz * Od v$process_memory_detail;---- Aby ponownie wypełnić widok nowszymi danymi-- po prostu wykonaj oradebug pga_detail_get-- oświadczenie--oradebug pga_detail_get    

Skrypt do wykonania tych działań jest pokazany poniżej:

---- Skonfiguruj środowisko dla wywołań oradebug--oradebug setmypidset echo off trimspool początek weryfikuj offundefine p_1undefine p_2undefine s1undefine s2zmienna p1 liczba zmienna p2 kolumna sys_date new_value sysdt noprintselect to_sysdate(sysdate'; -- Pobierz identyfikator procesu sesji --kolumna pid nowa_wartość p_1select pid z v$process gdzie addr in (wybierz paddr z v$session gdzie username ='' i sid =(select max(sid) From v$session where username =''));begin :p1 :=&p_1;end;/---- Zrzuć szczegóły procesu do v$process_memory_detail--oradebug dump pga_detail_get &p_1spool &p_1._pga_stats_&sysdt..log--- - Uzyskaj informacje o sesji dla --COLUMN alme NAGŁÓWEK „Alokowane MB” FORMAT 99999D9COLUMN usme NAGŁÓWEK „Used MB” FORMAT 99999D9COLUMN frme NAGŁÓWEK „Freeable MB” FORMAT 99999D9COLUMN mame NAGŁÓWEK „Max MB” FORMAT 99999D9COLUMN nazwa użytkownika FORMAT a FORMAT a22COLUMN sid FORMAT a5COLUMN spid FORMAT a8column pid_remote format a12SET LINESIZE 300SELECT s.username, SUBSTR(s.sid,1,5) sid, p.spid, logon_time, SUBSTR(s.program,1,22) program, s.process pid_remote, s.status, ROUND(pga_used_mem/1024/1024) usme, ROUND(pga_alloc_mem/1024/1024) alme, ROUND(pga_freeable_mem/1024/1024) frme, ROUND(pga_max_mem/1024/1024) mameFROM v$sesja s, v$process pWHERE p.addr=s.paddrAND s.username =''ORDER BY pga_max_mem,logon_time;---- Sleep 30 sekund---- Pobierz ponownie informacje o sesji--exec dbms_lock.sleep(30) kolumna sid nowa_wartość s1 noprintSELECT s.nazwa użytkownika, SUBSTR(s.sid,1,5) sid, p.spid, czas_logowania, SUBSTR(s.program,1,22) program , s.process pid_remote, s.status, ROUND( pga_used_mem/1024/1024) usme, ROUND(pga_alloc_mem/1024/1024) alme, ROUND(pga_freeable_mem/1024/1024) frme, ROUND(pga_max_mem/1024/1024) mameFROM v$session s,v$process pWHERE p.addr=s.paddrAND s.username =''ORDER BY pga_max_mem,logon_time;exec dbms_lock.sleep(10)select max(sid) sid z v$session gdzie nazwa użytkownika ='';---- Pobierz informacje o pamięci procesu--COLUMN kategoria HEADING "Category"COLUMN przydzielone HEADING "Przydzielone bajty"COLUMN użyte HEADING "Użyte bajty"COLUMN max_allocated HEADING "Maksymalnie przydzielone bajty"SELECT pid, kategoria, przydzielony, używany, max_allocatedFROM v$process_memoryWHERE pid in (SELECT pid FROM v$process WHERE addr in (select paddr FROM v$session WHERE sid =&&s1));exec dbms_lock.sleep(10)SELECT pid, kategoria, przydzielony, używany, max_allocatedFROM v$process_memoryWHERE pid in (SELECT pid FROM v$process WHERE addr in (select paddr FROM v$session WHERE sid =&&s1));exec dbms_lock.sleep(10)wybierz pid z v$process gdzie re addr in (wybierz paddr z v$session, gdzie username ='' i sid =(wybierz max(sid) z v$session, gdzie username =''));---- Zapisz pierwsze przejście statystyki pga--CREATE TABLE tab1 ASSELECT pid, kategoria, nazwa, nazwa_sterty, bajty, liczba_przydziału, deskryptor_sterty, deskryptor_sterty_nadrzędnejFROM v$process_memory_detailWHERE pid =&p_1AND category ='Inne';---- Pobierz drugi przebieg statystyk pgatail_pgatail--oradebug &p_1exec dbms_lock.sleep(120)---- Zapisz drugi przebieg statystyk pga ---CREATE TABLE tab2 ASSELECT pid, kategoria, nazwa, nazwa_sterty, bajty, liczba_alokacji, deskryptor_sterty, deskryptor_sterty_nadrzędnej_proces_memory_detailWHERE kategoria' =&p_1; ---- Rozpocznij raporty końcowe---- Informacje o stosie PGA--Kategoria KOLUMNY NAGŁÓWEK "Kategoria"Nazwa KOLUMNY NAGŁÓWEK "Nazwa" Nazwa KOLUMNY NAGŁÓWEK "Nazwa stosu" KOLUMNA q1 NAGŁÓWEK "Pamięć pierwsza" Format 999 999 999 999 KOLUMNA q2 NAGŁÓWEK "Pamięć druga" " Format 999,999,999,9 99KOLUMNA diff NAGŁÓWEK "Różnica" Format S999,999,999,999 USTAW WIERSZE 150SELECT tab2.pid, tab2.category, tab2.nazwa, tab2.heap_name, tab1.bajty q1, tab2.bajty q2, tab2.bajty-tab1.bajty diffFROM tab1, tab2GDZIE tab1.category =tab2.categoryAND tab1.name =tab2.nameAND tab1.heap_name =tab2.heap_nameand tab1.pid =tab2.pidAND tab1.bytes <> tab2.bytesORDER BY 1, 7 DESC;---- Logminer PGA info- -COLUMN nazwa_sterty HEADING "nazwa sterty" Nazwa KOLUMNY HEADING "Typ"COLUMN liczba_alokacji HEADING "Liczba"COLUMN bajty HEADING "Suma"COLUMN śred. jak 'Logminer%';tabela odrzucania buforów tab1 czyszczenie;tabela opuszczania tab2 czyszczenie;

Zapisz ten kod jako skrypt i edytuj tekst, aby zastąpić ciągi kontem użytkownika z uruchomionym programem Log Miner. Skrypt jest skierowany do pamięci Logminer, dzięki czemu można ją monitorować pod kątem wzrostu. Można go również zmodyfikować, aby wyszukać inne problematyczne obszary pamięci. Skomentuj polecenia „upuść tabelę”, aby zachować tab1 i tab2 do dalszych badań, jeśli chcesz, ponieważ inne obszary pamięci mogą być interesujące. Sprawdź również wsparcie Oracle pod kątem znanych problemów związanych z PGA. Takie raporty prawdopodobnie będą zawierały zapytania do zbadania określonych obszarów problemowych przy użyciu V$PROCESS_MEMORY_DETAIL. Dla ułatwienia te dodatkowe zapytania można dodać do kodu pokazanego powyżej, aby raportować wszystkie podejrzane obszary pamięci procesu. Dane te będą pomocne w udowodnieniu konieczności zastosowania określonych jednorazowych poprawek do bazy danych.

Log Miner może być bardzo przydatnym narzędziem do badania bieżących i stosunkowo niedawnych działań w bazie danych. Może być konieczne monitorowanie alokacji PGA, gdy sesje Log Miner są aktywne, aby można było wykonać działania zapobiegawcze, takie jak zwiększenie pga_aggregate_limit, a sesje nie zostaną nagle przerwane. „Ostrzegany jest uzbrojony”, jak mówi przysłowie, i chociaż administratorzy baz danych nie mają czterech ramion, wiedza o tym, co może się wydarzyć, jest zawsze warta posiadania.

Zobacz wszystkie artykuły Davida Fitzjarrella


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL ROWNUM jak zwrócić wiersze między określonym zakresem

  2. Podziel wartości oddzielone przecinkami w kolumnie w wierszu za pomocą zapytania Oracle SQL

  3. Błędy Addnode resolv.conf

  4. Czy można skorzystać ze zwrotu w procedurze składowanej?

  5. Jak przeliterować rok podczas formatowania daty w Oracle