Her er nogle af de fælles Oracle-ventebegivenheder, som alle bør kende.
Vent-begivenheder
Du kan finde, hvilken begivenhedssession der venter på den, ved at følge forespørgslen
select event from V$session_wait where sid=&1
Jeg forsøger at forklare nogle almindelige Oracle-ventehændelser, der er årsager og løsninger
kø
Processen venter på en orakelkø (en lås, du kan se i v$lock). Dette sker ofte, når en bruger forsøger at opdatere en række i en tabel, der i øjeblikket opdateres af en anden bruger. Blokererne kan finde ud af ved at bruge følgende forespørgsel
select * from dba_waiters
biblioteks cache-pin
Processen ønsker at fastgøre et objekt i hukommelsen i bibliotekets cache til undersøgelse, hvilket sikrer, at ingen andre processer kan opdatere objektet på samme tid. Dette sker, når du kompilerer eller analyserer et PL/SQL-objekt eller en visning. Undgå at kompilere PL/SQL-objekt eller orakelvisning ved høj brugstid for at undgå denne ventehændelse
lås til indlæsning af bibliotekscache
Processen venter på muligheden for at indlæse et objekt eller en del af et objekt i bibliotekets cache. (Kun én proces kan indlæse et objekt eller et stykke af et objekt ad gangen.)
låsefri
Processen venter på en lås, der holdes af en anden proces. (Denne ventehændelse gælder ikke for processer, der roterer, mens de venter på en låsning; når en proces drejer, venter den ikke). Latches er letvægts-serialiseringsenheder, der bruges til at koordinere flerbrugeradgang til delte datastrukturer, objekter, og filer.
Låse er låse designet til at blive holdt i ekstremt korte perioder, f.eks. den tid det tager at ændre en datastruktur i hukommelsen. De bruges til at beskytte visse hukommelsesstrukturer, såsom databaseblokbuffercachen eller bibliotekscachen i den delte pulje.
Oracle Latches anmodes typisk internt i en 'villig til at vente'-tilstand. Dette betyder, at hvis låsen ikke er tilgængelig, vil den anmodende session dvale i en kort periode og prøve handlingen igen senere. Andre låse kan blive anmodet om i en 'øjeblikkelig' tilstand, som i koncept ligner en VÆLG TIL OPDATERING NO-WAIT, hvilket betyder, at processen vil gå til noget andet, såsom at prøve at få fat i en tilsvarende søskendelås, der kan være gratis, i stedet for at sidde og vente på, at denne lås bliver tilgængelig. Da mange anmodninger muligvis venter på en låsning på samme tid, kan du se nogle processer, der venter længere end andre.
Låse tildeles ret tilfældigt, baseret på lodtrækningens held, om du vil. Uanset hvilken session, der beder om en lås, lige efter den blev frigivet, vil den få den. Der er ingen række af tjenere, bare en flok tjenere, der konstant prøver igen.
buffer optaget venter
Processen ønsker at få adgang til en datablok, der i øjeblikket ikke er i hukommelsen, men en anden proces har allerede udstedt en I/O-anmodning om at læse blokken ind i hukommelsen. (Processen venter på, at den anden proces er færdig med at bringe blokken i hukommelsen.). De varme blokke kan findes ved at bruge view V$BH
db-fil spredt læst
Processen har udstedt en I/O-anmodning om at læse en række sammenhængende blokke fra en datafil ind i buffercachen og venter på, at handlingen er fuldført. Dette sker typisk under en fuld tabelscanning eller fuld indeksscanning.
Vi bør tjekke, om forespørgslen skal bruge fuld tabelscanning. Sørg for, at Oracle Optimizer-statistik er opdateret. Brug partitionsbeskæring for at reducere antallet af besøgte blokke
Hvis en forespørgsel, der har kørt fint i et stykke tid, pludselig klokke meget tid på db-filens spredte læsehændelse, og der ikke er sket en kodeændring, kan du måske tjekke, om et eller flere indekser er blevet slettet eller blive ubrugelig.
db-fil sekventiel læsning
Processen har udstedt en I/O-anmodning om at læse en blok fra en datafil ind i buffercachen og venter på, at handlingen er fuldført. Dette sker typisk under et indeksopslag eller en hentning fra en oracle-tabel af ROWID, når den påkrævede datablok ikke allerede er i hukommelsen. Lad dig ikke vildlede af det forvirrende navn på denne ventebegivenhed!
Vi bør tjekke, om de rigtige indekser bliver brugt. Et forkert indeks kan få forespørgslen til at fungere dårligt. Sørg for, at optimeringsstatistikken er opdateret.
db-fil parallel læsning
Processen har udstedt flere I/O-anmodninger parallelt for at læse blokke fra datafiler ind i hukommelsen og venter på, at alle anmodninger er fuldført. Dokumentationen siger, at denne ventehændelse kun opstår under gendannelse, men faktisk forekommer den også under almindelig aktivitet, når en proces batcher mange enkelt blok I/O-anmodninger sammen og udsteder dem parallelt. (På trods af navnet vil du ikke se denne ventehændelse under parallel forespørgsel eller parallel DML. I de tilfælde opstår der i stedet ventehændelser med PX i deres navne.)
db fil parallel skrivning
Processen, typisk DBWR, har udstedt flere I/O-anmodninger parallelt for at skrive beskidte blokke fra buffercachen til disken og venter på, at alle anmodninger er fuldført.
direkte sti læs, direkte sti skriv
Processen har udstedt asynkrone I/O-anmodninger, der omgår buffercachen, og venter på, at de er færdige. Disse ventehændelser involverer typisk sorteringssegmenter.
SQL-sætninger med funktioner, der kræver sorteringer, såsom ORDER BY, GROUP BY, UNION, DISTINCT og ROLLUP, skrivesorteringskørsler til det midlertidige tablespace, når inputstørrelsen er større end arbejdsområdet i PGA
Sørg for, at optimeringsstatistikken er op til data, og forespørgslen bruger den rigtige køretabel. Tjek for at se, om det sammensatte indekss kolonner kan omarrangeres, så de matcher ORDER BY-sætningen for at undgå helt at sortere.
Sørg for, at den passende værdi PGA_AGGREGATE_TARGET er angivet. Hvis det er muligt, brug UNION ALL i stedet for UNION.
Delt poollås
Den delte pool-lås bruges til at beskytte kritiske operationer, når der tildeles og frigøres hukommelse i den delte pool. Indsigelser om den delte pulje og bibliotekets cachelåse skyldes primært intens hård parsing. En hård parse gælder for nye markører og markører, der er forældede og skal udføres igen
Omkostningerne ved at parse en ny SQL-sætning er dyr både i forhold til CPU-krav og antallet af gange bibliotekets cache og delte pool låse skal muligvis anskaffes og frigøres.
Eliminering af bogstavelig SQL er også nyttig for at undgå den delte pool-lås
kontrolfil sekventiel læsning
Processen venter på, at blokke bliver læst fra en kontrolfil. Dette sker generelt
- laver en sikkerhedskopi af kontrolfilerne
- deling af information (mellem forekomster) fra kontrolfilen
- læse andre blokke fra kontrolfilerne
- læser overskriftsblokken
Hvis dette er en større ventende begivenhed, betyder det, at kontrolfilens placering skal ændres til en hurtigere diskplacering
kontrolfil parallel skrivning
Processen har udstedt flere I/O-anmodninger parallelt om at skrive blokke til alle kontrolfiler og venter på, at alle skrivningerne er fuldført.
logbufferplads
Processen venter på, at plads bliver tilgængelig i logbufferen (plads bliver først tilgængelig, efter LGWR har skrevet det aktuelle indhold af logbufferen til disken). Dette sker typisk, når applikationer genererer gentag hurtigere, end LGWR kan skrive det. til disk.
Dette kan også ske, hvis I/O'en til disken, hvor gentag-logfiler er placeret, er langsom
Der bør ikke være nogen logbufferplads som sådan i databasen. Overvej at gøre logbufferen større, hvis den er lille, eller overvej at flytte logfiler til hurtigere diske, såsom striped diske.
Select event, total_waits, total_timeouts, time_waited, average_wait from v$system_event where event = 'log buffer space'; Select sid, event, seconds_in_wait, state from v$session_wait where event = 'log buffer space'; Select name, value from v$sysstat where name in ('redo log space requests');
pct_buff_alloc_retries skal være nul eller mindre end 0,01 (<1%). Hvis den er større, overvej at gøre logbufferen større. Hvis det er større, skal du overveje at flytte logfilerne til hurtigere diske, såsom stribede diske.
Select v1.value as redo_buff_alloc_retries, v2.value as redo_entries, trunc(v1.value/v2.value,4) as pct_buff_alloc_retries from v$sysstat v1, v$sysstat v2 where v1.name = 'redo buffer allocation retries' and v2.name = 'redo entries';
logfil sekventiel læsning
Processen venter på, at blokke bliver læst fra online-redo-log til hukommelsen. Dette sker primært ved opstart af instanser, og når ARCH-procesarkiverne udfyldte online-redo-logfiler.
logfil parallel skrivning
Processen venter på, at blokke bliver skrevet til alle online-redo-logmedlemmer i én gruppe. LGWR er typisk den eneste proces til at se denne ventebegivenhed. Det vil vente, indtil alle blokke er blevet skrevet til alle medlemmer.
synkronisering af logfiler
Processen venter på, at LGWR er færdig med at tømme logbufferen til disken. Dette sker, når en bruger foretager en transaktion. (En transaktion anses ikke for at være begået, før alle gentag for at gendanne transaktionen er blevet skrevet til disken.)
En langsom LGWR-proces kan introducere ventetider til logfilsynkronisering, som får brugeren til at opleve ventetider under commit eller rollback. Logfilens parallelle skrive- og logfilsynkroniseringsventehændelser er indbyrdes forbundne og skal behandles samtidigt.
Vi skal forsøge at allokere redo-logfilerne til højtydende disk (solid state disk). Vi bør også forsøge at reducere belastningen på LGWR ved at reducere commits i applikationerne.
Den manuelle hot-backup kan også introducere stress i systemet ved at generere en masse gentag-ting, så undgå det i spidsbelastningsperioder
Nogle gange sulter LGWR efter CPU-ressourcer. Hvis serveren er meget optaget, kan LGWR også sulte efter CPU. Dette vil føre til langsommere respons fra LGWR, hvilket øger ventetiden på 'logfilsynkronisering'. Disse systemopkald og I/O-opkald skal jo bruge CPU. I dette tilfælde er "logfilsynkronisering" et sekundært symptom, og løsning af hovedårsagen til højt CPU-brug vil reducere ventetiden for "logfilsynkronisering".
På grund af problemer med hukommelsessultning kan LGWR også søges ud. Dette kan også føre til langsommere respons fra LGWR.
fortryd segmentudvidelse
Sessionen venter på, at et fortryd-segment bliver forlænget eller formindsket.
skriv komplette ventetider
Sessionen venter på, at en anmodet buffer bliver skrevet til disken; bufferen kan ikke bruges, mens den skrives.
Lås:cachebufferkæder
Cachebufferkædernes låse bruges til at beskytte en bufferliste i buffercachen. Disse låse bruges, når du søger efter, tilføjer eller fjerner en buffer fra buffercachen.
Blokke i buffer-cachen placeres på linkede lister (cache-bufferkæder), som hænger fra en hash-tabel. Den hash-kæde, som en blok er placeret på, er baseret på blokkens DBA og CLASS. Hver hashkæde er beskyttet af en enkelt barnelås. Processer skal have den relevante lås for at tillade dem at scanne en hash-kæde for en buffer, så den sammenkædede liste ikke ændres under dem.
Strid om denne lås betyder normalt, at der er en blok, der er i stor strid (kendt som en varm blok).
For at identificere den stærkt tilgåede bufferkæde og dermed den påståede blokering, se på låsestatistikker for cachebufferkædens låse ved hjælp af V$LATCH_CHILDREN-visningen. Hvis der er en specifik cachebufferkæder børnelås, der har mange flere GETS, MISSES og SLEEPS sammenlignet med de andre underordnede låse, så er dette den påståede børnelås.
Denne lås har en hukommelsesadresse, identificeret af ADDR-kolonnen.
SELECT addr, sleeps FROM v$latch_children c, v$latchname n WHERE n.name='cache buffers chains' and c.latch#=n.latch# and sleeps > 100 ORDER BY sleeps /
Brug værdien i ADDR-kolonnen sammen med V$BH-visningen til at identificere de blokke, der er beskyttet af denne lås. Givet f.eks. adressen (V$LATCH_CHILDREN.ADDR) på en hårdt belastet lås, spørger dette fil- og bloknumrene:
SELECT file#, dbablk, class, state, TCH FROM X$BH WHERE HLADDR='address of latch';
X$BH.TCH er en berøringstælling for bufferen. En høj værdi for X$BH.TCH indikerer en varm blok.
Mange blokke er beskyttet af hver lås. En af disse buffere vil sandsynligvis være den varme blok. Enhver blok med en høj TCH-værdi er en potentiel hot-blok. Udfør denne forespørgsel et antal gange, og identificer den blok, der konsekvent vises i outputtet.
Når du har identificeret den varme blok, skal du forespørge DBA_EXTENTS ved hjælp af filnummeret og bloknummeret for at identificere segmentet.
Vigtige oplysninger om ventehændelse
Visningen v$session_wait viser information om ventehændelser, som aktive sessioner venter på i øjeblikket. Det følgende er beskrivelsen af denne visning, og den indeholder nogle meget nyttige kolonner, især P1- og P2-referencerne til de objekter, der er forbundet med ventehændelser.
desc v$session_wait Name Null? Type --------------------------- -------- ------------ SID NUMBER SEQ# NUMBER EVENT VARCHAR2(64) P1TEXT VARCHAR2(64) P1 NUMBER P1RAW RAW(4) P2TEXT VARCHAR2(64) P2 NUMBER P2RAW RAW(4) P3TEXT VARCHAR2(64) P3 NUMBER P3RAW RAW(4) WAIT_CLASS_ID NUMBER WAIT_CLASS# NUMBER WAIT_CLASS VARCHAR2(64) WAIT_TIME NUMBER SECONDS_IN_WAIT NUMBER STATE VARCHAR2(19)
Ved at bruge v$session_wait er det let at fortolke hver wait-hændelsesparameter ved hjælp af de tilsvarende beskrivende tekstkolonner for den parameter. Vent klassekolonner blev også tilføjet, så forskellige ventehændelser kunne grupperes i de relaterede behandlingsområder såsom netværk, applikation, inaktiv, samtidighed osv.
Denne kolonne blev også tilføjet til v$sessionstabellen fra 10g og fremefter . Så du kan bare bruge v$session til at finde alle detaljerne
Hver ventehændelse indeholder andre parametre, der giver yderligere oplysninger om hændelsen.
Sådan finder du oplysningerne om venthændelsen og dens parameter
The meaning of each wait event corresponds know by querying the V$EVENT_NAME p1, p2, p3 of col name format a25; col p1 format a10; col p2 format a10; col p3 format a10; SELECT NAME, PARAMETER1 P1, PARAMETER2 P2, PARAMETER3 P3 FROM V$EVENT_NAME WHERE NAME = '&event_name';
Lad os sige, at vi for eksempel tog
Hændelsesnavn-inputværdierne:db-fil spredt læst
Original værdi på 3:WHERE NAME ='&hændelsesnavn A'
Den nye værdi 3:WHERE NAME ='db-fil spredt læst'
Navnet P1 P2 P3
db-fil spredt læst fil # blok # blokke
fil nr.:datafilnummer
Blok nr.:startbloknummer
blokke:for at læse nummeret på datablokken
Lad os nu se, hvordan ovenstående oplysninger kan hjælpe os med at fange forskellige ting
Antag at en bestemt session venter på en buffer busy waits-hændelse, kan databaseobjektet, der forårsager denne wait-hændelse, nemt bestemmes:
select username, event, p1, p2 from v$session_wait where sid = 4563;
Outputtet af denne forespørgsel for en bestemt session med SID 4563 kan se sådan ud:
USERNAME EVENT SID P1 P2 ---------- ----------------- --- -- --- APPS buffer busy waits 4563 11 545
Kolonne P1 og P2 giver DBA'en mulighed for at bestemme fil- og bloknumre, der forårsagede denne ventehændelse. Forespørgslen nedenfor henter objektnavnet, der ejer datablok 155, værdien af P2 ovenfor:
SQL> select segment_name,segment_type from dba_extents where file_id = 11 and 45 between block_id and block_id + blocks – 1;
Evnen til at analysere og korrigere ventehændelser i Oracle Database er afgørende i ethvert tuning-projekt. Størstedelen af aktiviteten i en database involverer læsning af data, så denne type tuning kan have en enorm, positiv indvirkning på ydeevnen.
Bemærk:Når du laver venteanalyse, er det vigtigt at huske, at alle Oracle-databaser oplever ventehændelser, og at tilstedeværelsen af ventetider ikke altid indikerer et problem. Faktisk har alle veltunede databaser en flaskehals.
vi kan også bruge 10046-hændelsen til at spore sessionens ventehændelse
Læser også
Oracle-dokumentation
v$active_session_history
Forklar plan i Oracle