Hier zijn enkele van de gemeenschappelijke Oracle-wachtgebeurtenissen die iedereen zou moeten kennen.
Wacht evenementen
Je kunt zien welke evenementsessie erop wacht door de volgende vraag te volgen
select event from V$session_wait where sid=&1
Ik probeer enkele veelvoorkomende Oracle-wachtgebeurtenissen uit te leggen, er zijn oorzaken en oplossingen
in de wachtrij plaatsen
Het proces wacht op een orakelwachtrij (een slot dat je kunt zien in v$lock). Dit komt vaak voor wanneer een gebruiker een rij probeert bij te werken in een tabel die momenteel door een andere gebruiker wordt bijgewerkt. De blokkers kunnen worden gevonden door de volgende zoekopdracht te gebruiken
select * from dba_waiters
bibliotheekcachespeld
Het proces wil een object in het geheugen vastzetten in de bibliotheekcache voor onderzoek, zodat geen enkel ander proces het object tegelijkertijd kan bijwerken. Dit gebeurt wanneer u een PL/SQL-object of een view compileert of parseert. Vermijd het compileren van PL/SQL-objecten of orakelweergaven bij hoge gebruikstijd om deze wachtgebeurtenis te voorkomen
laadvergrendeling bibliotheekcache
Het proces wacht op de mogelijkheid om een object of een stuk van een object in de bibliotheekcache te laden. (Slechts één proces kan een object of een stuk van een object tegelijk laden.)
vrij vergrendelen
Het proces wacht op een vergrendeling die door een ander proces wordt vastgehouden. (Deze wait-gebeurtenis is niet van toepassing op processen die draaien terwijl ze wachten op een vergrendeling; wanneer een proces draait, wacht het niet.). Vergrendelingen zijn lichtgewicht serialisatie-apparaten die worden gebruikt om de toegang van meerdere gebruikers tot gedeelde gegevensstructuren, objecten, en bestanden.
Latches zijn sloten die ontworpen zijn om voor extreem korte tijd vastgehouden te worden, bijvoorbeeld de tijd die nodig is om een in-memory datastructuur aan te passen. Ze worden gebruikt om bepaalde geheugenstructuren te beschermen, zoals de buffercache van het databaseblok of de bibliotheekcache in de gedeelde pool.
Oracle Latches worden doorgaans intern aangevraagd in een 'willing to wait'-modus. Dit betekent dat als de vergrendeling niet beschikbaar is, de verzoekende sessie voor een korte tijd in slaap valt en de bewerking later opnieuw probeert. Andere vergrendelingen kunnen worden aangevraagd in een 'onmiddellijke' modus, wat qua concept vergelijkbaar is met een SELECT FOR UPDATE NO-WAIT, wat betekent dat het proces iets anders zal doen, zoals proberen een gelijkwaardige broer of zus-vergrendeling te pakken die mogelijk vrij is, in plaats van te gaan zitten wachten tot deze vergrendeling beschikbaar komt. Aangezien veel verzoeken tegelijkertijd op een vergrendeling kunnen wachten, ziet u mogelijk dat sommige processen langer wachten dan andere.
Vergrendelingen worden nogal willekeurig toegewezen, op basis van het geluk van de trekking, als je wilt. Elke sessie die om een vergrendeling vraagt, direct nadat deze is vrijgegeven, krijgt deze. Er is geen rij klinkkelners, maar een menigte kelners die het constant opnieuw probeert.
buffer bezig wacht
Het proces wil toegang krijgen tot een datablok dat zich momenteel niet in het geheugen bevindt, maar een ander proces heeft al een I/O-verzoek gedaan om het blok in het geheugen te lezen. (Het proces wacht tot het andere proces klaar is met het in het geheugen plaatsen van het blok.). De hot-blocks zijn te vinden via view V$BH
db-bestand verspreid gelezen
Het proces heeft een I/O-verzoek verzonden om een reeks aaneengesloten blokken uit een gegevensbestand in de buffercache te lezen en wacht tot de bewerking is voltooid. Dit gebeurt meestal tijdens een scan van een volledige tabel of een volledige index.
We moeten controleren of de query volledige tabelscan moet gebruiken. Zorg ervoor dat de Oracle Optimizer-statistieken up-to-date zijn. Gebruik Partition snoeien om het aantal bezochte blokken te verminderen
Als een query die al een tijdje goed loopt, plotseling veel tijd klokt op de db file scatter read-gebeurtenis en er geen codewijziging is geweest, wilt u misschien controleren of een of meer indexen zijn verwijderd of onbruikbaar worden.
db-bestand opeenvolgend gelezen
Het proces heeft een I/O-verzoek verzonden om één blok uit een gegevensbestand in de buffercache te lezen en wacht tot de bewerking is voltooid. Dit gebeurt meestal tijdens het opzoeken van een index of het ophalen van een orakeltabel door ROWID wanneer het vereiste gegevensblok zich nog niet in het geheugen bevindt. Laat je niet misleiden door de verwarrende naam van dit wachtevenement!
We moeten controleren of de juiste indexen worden gebruikt. Een verkeerde index kan ervoor zorgen dat de zoekopdracht slecht presteert. Zorg ervoor dat de optimalisatiestatistieken up-to-date zijn.
db-bestand parallel gelezen
Het proces heeft meerdere parallelle I/O-verzoeken verzonden om blokken uit gegevensbestanden in het geheugen te lezen en wacht tot alle verzoeken zijn voltooid. De documentatie zegt dat deze wait-gebeurtenis alleen optreedt tijdens herstel, maar in feite ook tijdens reguliere activiteiten wanneer een proces veel single-block I/O-verzoeken samenvoegt en deze parallel afgeeft. (Ondanks de naam zul je deze wait-gebeurtenis niet zien tijdens parallelle query's of parallelle DML. In die gevallen vinden in plaats daarvan wait-events met PX in hun naam plaats.)
db-bestand parallel schrijven
Het proces, typisch DBWR, heeft meerdere parallelle I/O-verzoeken uitgegeven om vuile blokken van de buffercache naar schijf te schrijven en wacht tot alle verzoeken zijn voltooid.
direct pad lezen, direct pad schrijven
Het proces heeft asynchrone I/O-verzoeken uitgegeven die de buffercache omzeilen, en wacht tot ze zijn voltooid. Deze wachtgebeurtenissen omvatten meestal sorteersegmenten.
SQL-instructies met functies die sortering vereisen, zoals ORDER BY, GROUP BY, UNION, DISTINCT en ROLLUP, schrijven sorteerbewerkingen naar de tijdelijke tabelruimte wanneer de invoergrootte groter is dan het werkgebied in PGA
Zorg ervoor dat de optimalisatiestatistieken up-to-date zijn en dat de zoekopdracht de juiste rijtabel gebruikt. Controleer of de kolommen van de samengestelde index kunnen worden herschikt zodat ze overeenkomen met de ORDER BY-component om het sorteren helemaal te voorkomen.
Zorg ervoor dat de juiste waarde PGA_AGGREGATE_TARGET is ingesteld. Gebruik indien mogelijk UNION ALL in plaats van UNION.
Gedeelde poolvergrendeling
De vergrendeling van de gedeelde pool wordt gebruikt om kritieke bewerkingen te beschermen bij het toewijzen en vrijmaken van geheugen in de gedeelde pool. Betwistingen voor de cache-vergrendelingen van de gedeelde pool en bibliotheek zijn voornamelijk te wijten aan intensieve harde parsering. Er is een harde ontleding van toepassing op nieuwe cursors en cursors die verouderd zijn en opnieuw moeten worden uitgevoerd
De kosten van het ontleden van een nieuwe SQL-instructie zijn duur, zowel wat betreft de CPU-vereisten als het aantal keren dat de bibliotheekcache en de gedeelde pool worden gebruikt vergrendelingen moeten mogelijk worden aangeschaft en vrijgegeven.
Het elimineren van letterlijke SQL is ook handig om de vergrendeling van de gedeelde pool te vermijden
controlebestand opeenvolgend lezen
Het proces wacht op het lezen van blokken uit een controlebestand. Dit gebeurt over het algemeen
- een back-up maken van de controlebestanden
- informatie delen (tussen instanties) uit het controlebestand
- andere blokken uit de controlebestanden lezen
- het kopblok lezen
Als dit een grote wachtgebeurtenis is, betekent dit dat de locatie van het besturingsbestand moet worden gewijzigd in een snellere schijflocatie
controlebestand parallel schrijven
Het proces heeft meerdere parallelle I/O-verzoeken verzonden om blokken naar alle besturingsbestanden te schrijven en wacht tot alle schrijfbewerkingen zijn voltooid.
bufferruimte loggen
Het proces wacht op het vrijkomen van ruimte in de logbuffer (ruimte komt pas beschikbaar nadat LGWR de huidige inhoud van de logbuffer naar schijf heeft geschreven.) Dit gebeurt meestal wanneer toepassingen sneller opnieuw uitvoeren dan LGWR kan schrijven naar schijf.
Dit kan ook gebeuren als de I/O naar de schijf waar de redo-logs zich bevinden traag is
Er zou als zodanig geen logbufferruimte in de database moeten zijn. Overweeg om de logbuffer groter te maken als deze klein is of overweeg logbestanden te verplaatsen naar snellere schijven zoals striped disks.
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');
De pct_buff_alloc_retries moet nul of kleiner zijn dan 0,01 (<1%). Als het groter is, overweeg dan om de logbuffer groter te maken. Als het groter is, overweeg dan om de logbestanden naar snellere schijven te verplaatsen, zoals gestreepte schijven.
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';
logbestand opeenvolgend gelezen
Het proces wacht op het lezen van blokken van het online opnieuw inloggen in het geheugen. Dit gebeurt voornamelijk bij het opstarten van de instantie en wanneer de ARCH-procesarchieven de online logs opnieuw vullen.
logbestand parallel schrijven
Het proces wacht op het schrijven van blokken naar alle online log-leden in één groep. LGWR is doorgaans het enige proces dat deze wachtgebeurtenis ziet. Het wacht totdat alle blokken naar alle leden zijn geschreven.
synchronisatie van logbestanden
Het proces wacht tot LGWR klaar is met het leegmaken van de logbuffer naar schijf. Dit gebeurt wanneer een gebruiker een transactie uitvoert. (Een transactie wordt pas als vastgelegd beschouwd als alle herhalingen om de transactie te herstellen met succes naar de schijf zijn geschreven.)
Een langzaam LGWR-proces kan synchronisatiewachten voor logbestanden introduceren, waardoor de gebruiker wachttijden ervaart tijdens het vastleggen of terugdraaien. De parallelle schrijf- en logbestandsynchronisatiewachtgebeurtenissen van het logbestand zijn met elkaar verbonden en moeten gelijktijdig worden afgehandeld.
We moeten proberen de redo-logboeken toe te wijzen aan een high-performance schijf (Solid state disk). We moeten ook proberen de belasting van LGWR te verminderen door vastleggingen in de applicaties te verminderen.
Het handmatige hot-back-upstuk kan ook stress in het systeem veroorzaken door veel dingen opnieuw te doen, dus vermijd dat tijdens piekuren
Soms heeft LGWR honger naar CPU-bronnen. Als de server erg druk is, kan LGWR ook verhongeren voor CPU. Dit zal leiden tot een langzamere reactie van LGWR, waardoor de wachttijden voor 'logbestandsynchronisatie' toenemen. Deze systeemaanroepen en I/O-aanroepen moeten immers CPU gebruiken. In dit geval is 'synchronisatie van logbestanden' een secundair symptoom en het oplossen van de hoofdoorzaak voor hoog CPU-gebruik zal de wachttijden voor 'logbestandsynchronisatie' verminderen.
Vanwege geheugengebrek kan LGWR ook worden uitgewisseld. Dit kan ook leiden tot een tragere reactie van LGWR.
segmentextensie ongedaan maken
De sessie wacht op een ongedaan maken van een segment dat wordt verlengd of verkleind.
schrijf volledige wachttijden
De sessie wacht op het schrijven van een aangevraagde buffer naar schijf; de buffer kan niet worden gebruikt terwijl deze wordt geschreven.
Latch:cachebufferketens
De cachebufferketens worden gebruikt om een bufferlijst in de buffercache te beschermen. Deze vergrendelingen worden gebruikt bij het zoeken naar, toevoegen of verwijderen van een buffer uit de buffercache.
Blokken in de buffercache worden op gekoppelde lijsten (cachebufferketens) geplaatst die aan een hashtabel hangen. De hashketen waarop een blok wordt geplaatst, is gebaseerd op de DBA en KLASSE van het blok. Elke hash-keten wordt beschermd door een enkele kindervergrendeling. Processen moeten de relevante vergrendeling krijgen zodat ze een hash-keten voor een buffer kunnen scannen, zodat de gekoppelde lijst eronder niet verandert.
Onenigheid over deze vergrendeling betekent meestal dat er een blok is dat in grote strijd is (bekend als een hot block).
Om de zwaar bezochte bufferketen te identificeren, en dus het bevochten blok, kijk naar de vergrendelingsstatistieken voor de cachebufferketens vergrendelingen met behulp van de V$LATCH_CHILDREN-weergave. Als er een specifieke cachebuffer is voor kindvergrendeling die veel meer GETS, MISSES en SLEEPS heeft in vergelijking met de andere kindvergrendelingen, dan is dit de betwiste kindervergrendeling.
Deze vergrendeling heeft een geheugenadres, geïdentificeerd door de ADDR-kolom.
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 /
Gebruik de waarde in de ADDR-kolom samen met de V$BH-weergave om de blokken te identificeren die door deze vergrendeling worden beschermd. Bijvoorbeeld, gegeven het adres (V$LATCH_CHILDREN.ADDR) van een zwaar bevochten grendel, vraagt dit de bestands- en bloknummers op:
SELECT file#, dbablk, class, state, TCH FROM X$BH WHERE HLADDR='address of latch';
X$BH.TCH is het aantal aanrakingen voor de buffer. Een hoge waarde voor X$BH.TCH duidt op een hot block.
Veel blokken worden beschermd door elke vergrendeling. Een van deze buffers zal waarschijnlijk het hot block zijn. Elk blok met een hoge TCH-waarde is een potentieel hot block. Voer deze query een aantal keren uit en identificeer het blok dat consequent in de uitvoer verschijnt.
Nadat u het hot block hebt geïdentificeerd, zoekt u DBA_EXTENTS op met behulp van het bestandsnummer en bloknummer om het segment te identificeren.
Belangrijke informatie over wachtgebeurtenis
De v$session_wait-weergave toont informatie over wachtgebeurtenissen waarop momenteel actieve sessies wachten. Hieronder volgt de beschrijving van deze weergave en bevat enkele zeer nuttige kolommen, met name de verwijzingen naar P1 en P2 naar de objecten die zijn gekoppeld aan de wachtgebeurtenissen.
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)
Met v$session_wait is het gemakkelijk om elke wait-gebeurtenisparameter te interpreteren met behulp van de corresponderende beschrijvende tekstkolommen voor die parameter. Er zijn ook wachtklasse-kolommen toegevoegd zodat verschillende wachtgebeurtenissen konden worden gegroepeerd in de gerelateerde verwerkingsgebieden zoals netwerk, applicatie, inactief, gelijktijdigheid, enz.
Deze kolom is ook toegevoegd aan de v$session-tabel vanaf 10g . Je kunt dus gewoon v$session gebruiken om alle details te vinden
Elke wachtgebeurtenis bevat andere parameters die aanvullende informatie over de gebeurtenis geven.
De informatie over de wachtgebeurtenis en de bijbehorende parameter vinden
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';
Laten we zeggen dat we bijvoorbeeld
De event_name invoerwaarden:db file scatter read
Oorspronkelijke waarde van 3:WHERE NAME =‘&event_name A’
De nieuwe waarde 3:WHERE NAME =‘db file scatter read’
De naam P1 P2 P3
db-bestand verspreid leesbestand # blok # blokken
file #:gegevensbestandsnummer
Blok #:startbloknummer
blokken:om het nummer van het gegevensblok te lezen
Laten we nu eens kijken hoe de bovenstaande informatie ons kan helpen verschillende dingen vast te leggen
Stel dat een bepaalde sessie wacht op een buffer busy waits-gebeurtenis, het databaseobject dat deze wait-gebeurtenis veroorzaakt, kan eenvoudig worden bepaald:
select username, event, p1, p2 from v$session_wait where sid = 4563;
De uitvoer van deze query voor een bepaalde sessie met SID 4563 kan er als volgt uitzien:
USERNAME EVENT SID P1 P2 ---------- ----------------- --- -- --- APPS buffer busy waits 4563 11 545
Met kolommen P1 en P2 kan de DBA de bestands- en bloknummers bepalen die deze wachtgebeurtenis hebben veroorzaakt. De onderstaande query haalt de objectnaam op die eigenaar is van gegevensblok 155, de waarde van P2 hierboven:
SQL> select segment_name,segment_type from dba_extents where file_id = 11 and 45 between block_id and block_id + blocks – 1;
De mogelijkheid om wachtgebeurtenissen van Oracle Database te analyseren en corrigeren is van cruciaal belang in elk afstemmingsproject. De meeste activiteit in een database omvat het lezen van gegevens, dus dit soort afstemming kan een enorme, positieve invloed hebben op de prestaties.
Opmerking:wanneer u wachtanalyses uitvoert, is het van cruciaal belang om te onthouden dat alle Oracle-databases wachtgebeurtenissen ervaren en dat de aanwezigheid van wachttijden niet altijd op een probleem wijst. In feite hebben alle goed afgestemde databases een knelpunt.
we kunnen de 10046-gebeurtenis ook gebruiken om de wachtgebeurtenis van de sessie te traceren
Leest ook
Oracle-documentatie
v$active_session_history
Plan uitleggen in Oracle