sql >> Databasteknik >  >> RDS >> Oracle

Använda LogMiner för att hitta aktuella ändringar

Det kan finnas tillfällen då det är nödvändigt att undersöka de senaste ändringarna i databasen och rapportera vad som ändrades, när och av vem. I flera år har Oracles DBMS_LOGMNR-paket varit tillgängligt för sådana uppgifter men dess anrop har inte täckts helt. Konventionella metoder använder proceduren ADD_LOGFILE() för att förbereda Log Miner för användning med ett grundläggande anrop till START_LOGMNR-proceduren. Detta startar verktyget med nuvarande SCN som utgångspunkt. Det finns ett annat sätt att starta Log Miner, genom att välja ett giltigt startande SCN och ge det till START_LOGMNR()-anropet. I den här artikeln kommer du att se hur detta kan göras och, i processen, avslöja ett möjligt problemområde med PGA-tilldelningar.

När man tittar på ett "vanligt vanilj"-skript för att starta Log Miner görs de vanliga proceduranrop som startar Log Miner med den aktuella SCN:

---- run_logmnr.sql---- Lägg till loggfiler och ställ in DBMS_LOGMNR för att-- kontinuerligt gruva arkivloggar--ställa in radstorlek 200 trimpool på sidstorlek 0---- Lägg till befintliga loggfiler---- Utelämna standbyloggfiler- -välj 'exec dbms_logmnr.add_logfile('''||medlem||''')'från v$logfilewhere skriv <> 'STANDBY'och medlem i (välj min(medlem) från v$logfilgruppen efter grupp#)spool /tmp/add_logfiles.sql/spool off@/tmp/add_logfiles---- Starta logmnr i kontinuerligt gruvläge--exec dbms_logmnr.start_logmnr(optioner => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG_CATALOG_CONLINE_CATALOG_CONTINU_LOGMNR.Press 

Observera att alla tillgängliga redo-loggar läggs till innan du startar Log Miner. Det finns en annan metod som tillhandahåller ett startande SCN till start_logmnr-anropet, så länge databasen körs i ARCHIVELOG-läge:

BÖRJA DBMS_LOGMNR.START_LOGMNR( startScn => , endScn => , OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY + DBMS_LOGMNR.CONTINU>ENDOUMNR;END_MTI>); 

Intressant nog är slutet SCN inte nödvändigt för att få igång en Log Miner-session. Databasen måste vara i ARCHIVELOG-läge så att alternativet CONTINUOUS_MINE kan anges eftersom Log Miner automatiskt lägger till alla tillgängliga arkiverade loggfiler när den körs. Genom att använda denna metod kan en specifik SCN användas för att starta en sökning; ange slut-SCN-parentessökningen så att endast en begränsad delmängd av data returneras till vyn V$LOGMNR_CONTENTS och tillhandahåller en stopppunkt för sökningen, så att en förfrågan i vyn kan avslutas.

Det är en enkel uppgift att övervaka Log Miners framsteg genom att kontrollera databasens varningslogg när poster markerade med "LOGMINER" registreras. En komplett post kommer att innehålla en BEGIN och en END-rad, som visas nedan:

Mån 07 okt 12:48:22 2019LOGMINER:Avsluta mining-loggfilen för session -2147482111 tråd 1 sekvens 9776, /oracle/archive/awcis/awcis_0000009776_0001_1008544401_1008544401_1008544401:0001_1008544401:Börja 1008544401 session:1008544401 min 2147482111 thread 1 sequence 9777, /oracle/archive/awcis/awcis_0000009777_0001_1008544071.arcMon Oct 07 12:48:36 2019LOGMINER:End mining logfile for session -2147482111 thread 1 sequence 9777, /oracle/archive/awcis/awcis_0000009777_0001_1008544071.arcMon Oct 07 12 :48:36 2019LOGMINER:Börja mining loggfil för session -2147482111 tråd 1 sekvens 9778, /oracle/archive/awcis/awcis_0000009778_0001_1008544071.arc Mån 2 okt:407 min 12:12 12:48 min sekvens:7 1 2 2 2 2 4 1 4 1 1 1 2 1 1 2 1 1 2 1 1 1 1 2 4 8 1 1 1 2 oracle/archive/awcis/awcis_0000009778_0001_1008544071.arcMon Oct 07 12:48:49 2019LOGMINER:Börja bryta loggfil för session -2147482111 tråd 1 sekvens 977482111 tråd 1 sekvens 977482111 sekvens 977482111 sekvens 977482111 sekvens 977482111 sekvens 97/4800901901090190190190190190190190190190190190100901010010100100100100100100001001 

För lokala Oracle-sessioner är talen positiva heltal; för fjärrsessioner, initierade av verktyg som Perl, Python, C/C++ eller andra språk kommer negativa heltal att ses (posterna som visas ovan initierades av ett Python-skript). Loggfilnamnen kommer att gå igenom både redo-loggarna online och tillgängliga arkiverade kopior.

Att starta Log Miner på det här sättet kan också orsaka fel som "saknad loggfil" när det valda start-SCN- eller SCN-intervallet inte längre är tillgängligt i redo-strömmen. Långvariga frågor kan stöta på sådana fel. Dessutom, om SCN är utanför räckvidden med avseende på de tillgängliga loggfilerna kommer inte Log Miner att starta, kastar:

FEL på rad 1:ORA-01292:ingen loggfil har specificerats för den aktuella LogMiner-sessionenORA-06512:vid "SYS.DBMS_LOGMNR", rad 58ORA-06512:på rad 2

För att hjälpa till att eliminera sådana fel kommer att välja FIRST_CHANGE# från V$LOG-vyn att ge giltiga startpunkter för en Log Miner-session; att använda en liknande fråga mot V$ARCHIVED_LOG kommer att returnera alla tillgängliga start-SCN för de arkiverade redo-kopiorna.

Detta är inte den enda komplikationen med att använda Log Miner på detta sätt. Beroende på hur mycket information som ska returneras kan Logmminer-processen allokera stora mängder PGA-minne som kan, om pga_aggregate_limit är liten, ge följande fel:

ORA-04036:PGA-minne som används av instansen överstiger PGA_AGGREGATE_LIMIT

lyckligtvis är detta inte ett fatalt misstag. Eftersom PGA-resurser inte längre behövs kan minne släppas tillbaka till databasen för användning på annat håll. Det kan dock ta lite längre tid än önskat att få det minnet frigjort tillbaka till minnespoolen. Ett alternativ är att sätta pga_aggregate_limit högre än summan av Log Miner-sessionerna, vilket kan förhindra att felet uppstår. Hur vet du vilket minne som är tilldelat till dessa sessioner? En vy, V$PROCESS_MEMORY_DETAIL, är tillgänglig i databasen. Men ett försök att fråga den här vyn utan några förberedelser kommer att returnera:

inga rader markerade.

Detta är ett relativt litet problem, men det kräver användning av verktyget oradebug. Följande steg kommer att ladda data till V$PROCESS_MEMORY_DETAIL:

---- Ställ in den aktuella sessionsidentifieraren-- oradebug setmypid---- Använd PID för den önskade processen-- dumpa minnesdata---- Detta fyller i V$PROCESS_MEMORY_DETAIL--oradebug pga_detail_get - --- Fråga vyn för att få önskad data--välj * Från v$process_memory_detail;---- För att fylla på vyn med nyare data-- kör helt enkelt oradebugen pga_detail_get-- statement--oradebug pga_detail_get    

Ett skript för att utföra dessa åtgärder visas nedan:

---- Ställ in miljön för oradebug-anrop--oradebug setmypidset echo off trimspool onset verifiera offundefine p_1undefine p_2undefine s1undefine s2variable p1 numbervariable p2 numbercolumn sys_date new_value sysdt noprintselect to_char-MISSH; -- Hämta process-id för -sessionen--kolumn pid new_value p_1välj pid från v$process där addr in (välj paddr från v$session där användarnamn ='' och sid =(välj max(sid) Från v$session där användarnamn =''));begin :p1 :=&p_1;end;/---- Dumpa processdetalj till v$process_memory_detail--oradebug dump pga_detail_get &p_1spool &p_1._pga_stats_&sysdt..log--- - Hämta sessionsinformation för --KOLUMN alme RUBRIK "Allokerad MB" FORMAT 99999D9COLUMN usme RUBRIK "Använd MB" FORMAT 99999D9KOLUMN frme RUBRIK "Fribar MB" FORMAT 99999D9COLUMN MATCH FORMAT "Max2C 9 MBOLN9" program 99999D9COLUMN 99999D9COLUMN 99999D9COLUMN användarnamn99 MBOLN9 FORMAT a22COLUMN sid FORMAT a5COLUMN spid FORMAT a8column pid_remote format a12SET LINESIZE 300SELECT s.användarnamn, SUBSTR(s.sid,1,5) sid, p.spid, logon_time, SUBSTR(s.program,1,22) programs, s.s.s.s.s. 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_mem/1020 mamsession/pga_max ROM(/10_max ROM) v$process pWHERE p.addr=s.paddrAND s.username =''BESTÄLL AV pga_max_mem,logon_time;---- Sov 30 sekunder---- Få sessionsinformation igen--exec dbms_lock.sleep(30) kolumn sid nytt_värde s1 noprintSELECT s.användarnamn, 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) mame v$session s,v$process pWHERE p.addr=s.paddrAND s.username =''ORDER AV pga_max_mem,logon_time;exec dbms_lock.sleep(10)välj max(sid) sid från v$session där användarnamn ='';---- Hämta processminnesinformation--COLUMN category HEADING "Kategori"COLUMN allocated HEADING "Allokerade bytes"COLUMN used HEADING "Använda bytes"COLUMN max_allocated HEADING "Max allocated bytes"SELECT pid, category, allocated, used, max_allocatedFROM v$process_memoryWHERE pid in (SELECT pid FROM v$process WHERE addr in (välj paddr FROM v$session WHERE sid =&&s1));exec dbms_lock.sleep(10)SELECT pid, kategori, allokerad, använd, max_allocatedFROM v$process_memoryWHERE pid in (VÄLJ pid FRÅN v$process WHERE addr in (välj paddr FROM v$session WHERE sid =&&s1));exec dbms_lock.sleep(10)välj pid från v$process whe re addr in (välj paddr från v$session där användarnamn ='' och sid =(välj max(sid) från v$session där användarnamn =''));---- Spara första pass av pga stats--CREATE TABLE tab1 ASSELECT pid, kategori, namn, heap_name, bytes, allocation_count, heap_descriptor, parent_heap_descriptorFROM v$process_memory_detailWHERE pid =&p_1AND category ='Annan';---- Få andra pass av pga_dump_dump_descriptor &p_1exec dbms_lock.sleep(120)---- Spara andra genomgången av pga statistik--SKAPA TABELL tab2 ASSELECT pid, kategori, namn, heap_name, bytes, allocation_count, heap_descriptor, parent_heap_descriptorFROM v$process_memory_detail_detailWHERE pid ='&p_1WHERE'; ---- Starta slutrapporter---- PGA heap info--COLUMN category HEADING "Kategori"COLUMN name HEADING "Name"COLUMN heap_name HEADING "Heap name"COLUMN q1 HEADING "Memory 1st" Format 999,999,999,99q nd y nd ynd ynd " Format 999,999,999,9 99COLUMN diff HEADING "Difference" Format S999,999,999,999SET LINES 150SELECT tab2.pid, tab2.category, tab2.name, tab2.heap_name, tab1.bytes q1, tab2.bytes q2, tab2.bytes tab2. 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 heap_name HEADING "heap name"COLUMN name HEADING "Type"COLUMN allocation_count HEADING "Count"COLUMN bytes HEADING "Summa"COLUMN avg HEADING "Average" FORMAT 99999D99SELECT pid, heap_count_WEREap, bytes_count_2WEREap som 'Logminer%';spool offdrop table tab1 purge;drop table tab2 purge;

Spara den här koden som ett skript och redigera texten för att ersätta -strängarna med användarkontot som kör Log Miner. Skriptet riktar sig specifikt till Logminer-minnet så att det kan övervakas för ökningar. Det kan också modifieras för att leta efter andra problemminnesområden. Kommentera "släpp tabell"-kommandona för att bevara tab1 och tab2 för vidare forskning, om så önskas eftersom andra minnesområden kan vara av intresse. Kontrollera även Oracle-stödet för kända PGA-relaterade problem. Sådana rapporter kommer sannolikt att ha frågor att använda för att undersöka specifika problemområden med hjälp av V$PROCESS_MEMORY_DETAIL. För enkelhets skull kan dessa ytterligare frågor läggas till i koden som visas ovan för att rapportera om alla misstänkta områden i processminnet. Dessa data kommer att vara avgörande för att bevisa nödvändigheten av att tillämpa specifika engångskorrigeringar på databasen.

Log Miner kan vara ett mycket användbart verktyg för att undersöka aktuella och relativt nya tidigare åtgärder till databasen. Det kan vara nödvändigt att övervaka PGA-tilldelningar medan Log Miner-sessioner är aktiva så att förebyggande åtgärder som att öka pga_aggregate_limit kan utföras och sessioner inte abrupt avslutas. "Forewarned is forearmed", som ordspråket säger, och även om DBA:er inte har fyra armar är det alltid kunskap värt att veta vad som kan ligga framför sig.

Se alla artiklar av David Fitzjarrell


  1. Ställ in värde i beroende av rordiagrammet

  2. Kul med Djangos nya Postgres-funktioner

  3. Hanterar ExecuteScalar() när inga resultat returneras

  4. Upptäck dubbletter av objekt i rekursiv CTE