sql >> Database >  >> RDS >> Oracle

Oracle Wait-gebeurtenissen die iedereen zou moeten weten

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


  1. Hoe XML-bestand importeren in Oracle SQL Developer?

  2. OASIS-SVN en git gebruiken voor toegang tot broncodecontrole

  3. Werken met hulpmiddelen op het scherm in Access 2019

  4. Easysoft Release ODBC-ODBC Bridge voor Windows 10