Der kan være tilfælde, hvor det er nødvendigt at undersøge de seneste ændringer af databasen og rapportere, hvad der blev ændret, hvornår og af hvem. I årevis har Oracles DBMS_LOGMNR-pakke været tilgængelig for sådanne opgaver, men dens påkald er ikke blevet dækket fuldt ud. Konventionelle metoder bruger ADD_LOGFILE()-proceduren til at forberede Log Miner til brug med et grundlæggende kald til START_LOGMNR-proceduren. Dette starter hjælpeprogrammet med det aktuelle SCN som udgangspunkt. Der er en anden måde at starte Log Miner på, ved at vælge et gyldigt start-SCN og give det til START_LOGMNR()-kaldet. I denne artikel vil du se, hvordan dette kan gøres, og i processen afsløre et muligt problemområde med PGA-allokeringer.
Ser man på et 'plain vanilla'-script til at starte Log Miner, foretages de sædvanlige procedurekald, der starter Log Miner med den aktuelle SCN:
---- run_logmnr.sql---- Tilføj logfiler og indstil DBMS_LOGMNR til-- kontinuerligt at mine arkivlogfiler--sæt linjestørrelse 200 trimspool på sidestørrelse 0---- Tilføj de eksisterende logfiler---- Udelad standby-logfiler- -vælg 'exec dbms_logmnr.add_logfile('''||medlem||''')'fra v$logfilewhere skriv <> 'STANDBY'og medlem i (vælg min(medlem) fra v$logfilgruppe efter gruppe#)spool /tmp/add_logfiles.sql/spool off@/tmp/add_logfiles---- Start logmnr i kontinuert minetilstand--exec dbms_logmnr.start_logmnr(options => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG_CATALOG_CONLINE_CATALOG_CONTINU_LOGMNR.CONTIN.Bemærk, at alle tilgængelige redo-logfiler tilføjes, før du starter Log Miner. Der findes en anden metode, der leverer et start-SCN til start_logmnr-kaldet, så længe databasen kører i ARCHIVELOG-tilstand:
BEGIN DBMS_LOGMNR.START_LOGMNR( startScn =>, endScn => , OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY + DBMS_LOGMNR/_MTI>); Interessant nok er slutningen af SCN ikke nødvendig for at få startet en Log Miner-session. Databasen skal være i ARCHIVELOG-tilstand, så indstillingen CONTINUOUS_MINE kan angives, fordi Log Miner automatisk tilføjer alle tilgængelige arkiverede logfiler, mens den kører. Ved at bruge denne metode kan en specifik SCN bruges til at starte enhver søgning; angivelse af slut-SCN-parentessøgningen, så kun en begrænset delmængde af data returneres til V$LOGMNR_CONTENTS-visningen og giver et stoppunkt for søgningen, så en forespørgsel i visningen kan afsluttes.
Det er en simpel opgave at overvåge Log Miner's fremskridt ved at kontrollere databasens advarselslog, da poster markeret med 'LOGMINER' bliver registreret. En komplet indtastning vil indeholde en BEGIN og en SLUT linje, som vist nedenfor:
Man 07. okt. 12:48:22 2019LOGMINER:Slut mining-logfil for session -2147482111 tråd 1 sekvens 9776, /oracle/archive/awcis/awcis_0000009776_0001_100854407:Begynd oc. 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:Begynd mining-logfil for session -2147482111 tråd 1-sekvens 9778, /oracle/archive/awcis/awcis_0000009778_0001_1008544071.arcMon 2. okt. 407. 1. 1. 1. 2. 4. 12. Oracle/Archive/AWCIS/AWCIS_0000009778_0001_1008544071.Arcmon 07. oktober 12:48:49 2019LogMiner:Begynd Mining Logfile til session -2147482111 Thread 1 Sequence 9779, /oracle/archive/awcis/AWCIS_00000097979_0001_1100400440440440404040404040404040440440440444444404444444444044444444444444444444444444444444444444444474For lokale Oracle-sessioner er tallene positive heltal; til fjernsessioner, initieret af hjælpeprogrammer som Perl, Python, C/C++ eller andre sprog, vil negative heltal blive set (indgangene vist ovenfor blev initieret af et Python-script). Logfilnavne vil cykle gennem både online-redo-logfilerne og de tilgængelige arkiverede kopier.
At starte Log Miner på denne måde kan også give fejl som "manglende logfil", når det valgte start-SCN eller SCN-område ikke længere er tilgængeligt i gen-strømmen. Langvarige forespørgsler kan støde på sådanne fejl. Derudover, hvis SCN'en er uden for rækkevidde i forhold til de tilgængelige logfiler, starter Log Miner ikke, og kaster:
FEJL på linje 1:ORA-01292:ingen logfil er angivet for den aktuelle LogMiner-sessionORA-06512:på "SYS.DBMS_LOGMNR", linje 58ORA-06512:på linje 2For at hjælpe med at eliminere sådanne fejl vil valg af FIRST_CHANGE# fra V$LOG-visningen give gyldige startpunkter for en Log Miner-session; brug af en lignende forespørgsel mod V$ARCHIVED_LOG vil returnere alle tilgængelige start-SCN'er for de arkiverede gentage-kopier.
Dette er ikke den eneste komplikation ved at bruge Log Miner på denne måde. Afhængigt af hvor meget information der skal returneres, kan Logmminer-processen allokere store mængder PGA-hukommelse, som kan, hvis pga_aggregate_limit er lille, give følgende fejl:
ORA-04036:PGA-hukommelse, der bruges af forekomsten, overstiger PGA_AGGREGATE_LIMITHeldigvis er dette ikke en fatal fejl. Da PGA-ressourcer ikke længere er nødvendige, kan hukommelse frigives tilbage til databasen til brug andetsteds. Det kan dog tage lidt længere tid end ønsket at få den hukommelse frigivet tilbage til hukommelsespuljen. En mulighed er at sætte pga_aggregate_limit højere end summen af Log Miner-sessionerne, hvilket kan forhindre fejlen i at opstå. Hvordan ved du, hvilken hukommelse der er allokeret til disse sessioner? En visning, V$PROCESS_MEMORY_DETAIL, er tilgængelig i databasen. Men forsøg på at forespørge på denne visning uden nogen forberedelse vil returnere:
ingen rækker valgt.Dette er et relativt mindre problem, men det kræver brug af oradebug-værktøjet. Følgende trin indlæser data i V$PROCESS_MEMORY_DETAIL:
---- Indstil den aktuelle sessionsidentifikator-- oradebug setmypid---- Brug af PID for den ønskede proces-- dump hukommelsesdataene---- Dette udfylder V$PROCESS_MEMORY_DETAIL--oradebug pga_detail_get- --- Forespørg visningen for at få de ønskede data--vælg * Fra v$process_memory_detail;---- For at genudfylde visningen med nyere data-- skal du blot udføre oradebug pga_detail_get-- statement--oradebug pga_detail_get Et script til at udføre disse handlinger er vist nedenfor:
---- Opsæt miljøet for oradebug-kald--oradebug setmypidset ekko fra trimspool onset verify offundefine p_1undefine p_2undefine s1undefine s2variable p1 numbervariable p2 numbercolumn sys_date new_value sysdt noprintselect to_char-MISSH; -- Hent proces-id for-sessionen--kolonne pid new_value p_1vælg pid fra v$process hvor addr in (vælg paddr fra v$session hvor brugernavn =' ' og sid =(vælg max(sid) Fra v$session hvor brugernavn =' '));begin :p1 :=&p_1;end;/---- Dump procesdetaljer til v$process_memory_detail--oradebug dump pga_detail_get &p_1spool &p_1._pga_stats_&sysdt..log--- - Hent sessionsinformation for --KOLUMNE alme OVERSKRIFT "Tildelt MB" FORMAT 99999D9KOLUMN usme OVERSKRIFT "Brugt MB" FORMAT 99999D9KOLUMN frme OVERSKRIFT "Fribar MB" FORMAT 99999D9KOLUMN MATCH FORMAT "Max2C 9COLUMN bruger FORMAT9 MBOLN9" program 99999 MBOLN999999D9KOLUMN 99999D9KOLUMN 99999D9KOLUMN 5 FORMAT a22COLUMN sid FORMAT a5COLUMN spid FORMAT a8column pid_remote format a12SET LINESIZE 300SELECT s.brugernavn, SUBSTR(s.sid,1,5) sid, p.spid, logon_time, SUBSTR(s.program,1,22) program, 1,22. 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_maks. ROM/1020 mamsession) v$process pWHERE p.addr=s.paddrAND s.username =' 'BESTILLING AF pga_max_mem,logon_time;---- Sove 30 sekunder---- Få sessionsoplysninger igen--exec dbms_lock.sleep(30) kolonne sid ny_værdi s1 noprintSELECT s.brugernavn, 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$session s,v$process pWHERE p.addr=s.paddrAND s.username =' 'ORDER BY pga_max_mem,logon_time;exec dbms_lock.sleep(10)vælg max(sid) side fra v$session, hvor brugernavn =' ';---- Få proceshukommelsesoplysninger--COLUMN category HEADING "Kategori"COLUMN allocated HEADING "Allokerede bytes"COLUMN used HEADING "Brugte bytes"COLUMN max_allocated HEADING "Max allocated bytes"SELECT pid, category, allocated, used, max_allocatedFROM v$process_memoryWHERE pid in (SELECT pid FROM v$proces WHERE addr in (vælg paddr FROM v$session WHERE sid =&&s1));exec dbms_lock.sleep(10)SELECT pid, kategori, allokeret, brugt, max_allocatedFROM v$process_memoryWHERE pid in (SELECT pid FROM v$process WHERE addr in (vælg paddr FROM v$session WHERE sid =&&s1));exec dbms_lock.sleep(10)vælg pid fra v$process whe re addr in (vælg paddr fra v$session hvor brugernavn =' ' og sid =(vælg max(sid) fra v$session hvor brugernavn =' '));---- Gem første pass af pga stats--CREATE TABLE tab1 ASSELECT pid, kategori, navn, heap_name, bytes, allocation_count, heap_descriptor, parent_heap_descriptorFROM v$process_memory_detailWHERE pid =&p_1AND category ='Andet';---- Få anden gennemgang af pga statsget pga_oradebug &p_1exec dbms_lock.sleep(120)---- Gem anden gennemgang af pga stats--CREATE TABLE tab2 ASSELECT pid, kategori, navn, heap_name, bytes, allocation_count, heap_descriptor, parent_heap_descriptorFROM v$process_memory_detail_detailWHERE pid ='&p_1HER'; ---- Start endelige rapporter---- PGA heap info--COLUMN category HEADING "Kategori"COLUMN name HEADING "Navn"COLUMN heap_name HEADING "Heap name"COLUMN q1 HEADING "Hukommelse 1st" Format 999,999,999,99 yd. " Format 999,999,999,9 99COLUMN diff OVERSKRIFT "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.FROM. 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 "Sum"COLUMN gns. OVERSKRIFT "Gennemsnit" FORMAT 99999D99SELECT pid, heap_count_tæller, faneblade_tæller, faneblade_tæller, faneblade_navn, aftal_navn, faneblade, som 'Logminer%';spool offdrop table tab1 purge; drop table tab2 purge; Gem denne kode som et script, og rediger teksten for at erstatte
-strengene med den brugerkonto, der kører Log Miner. Scriptet retter sig specifikt mod Logminer-hukommelsen, så den kan overvåges for stigninger. Den kan også ændres til at lede efter andre problemhukommelsesområder. Kommenter 'slip tabel'-kommandoerne for at bevare tab1 og tab2 til yderligere forskning, hvis det ønskes, da andre hukommelsesområder kan være af interesse. Tjek også Oracle-understøttelse for kendte PGA-relaterede problemer. Sådanne rapporter vil sandsynligvis have forespørgsler til at bruge til at undersøge specifikke problemområder ved hjælp af V$PROCESS_MEMORY_DETAIL. For nemheds skyld kan disse yderligere forespørgsler føjes til koden vist ovenfor for at rapportere om alle mistænkelige områder af proceshukommelsen. Disse data vil være medvirkende til at bevise nødvendigheden af at anvende specifikke engangsrettelser til databasen. Log Miner kan være et meget nyttigt værktøj til at undersøge aktuelle og relativt nylige tidligere handlinger til databasen. Det kan være nødvendigt at overvåge PGA-allokeringer, mens Log Miner-sessioner er aktive, så forebyggende handlinger såsom at øge pga_aggregate_limit kan udføres, og sessioner vil ikke blive brat afsluttet. "Forewarned is forearmed", som man siger, og selvom DBA'er ikke har fire arme, er det altid viden værd at have ved, hvad der kan ligge forude.
Se alle artikler af David Fitzjarrell