Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle Wait Events, die jeder kennen sollte

Hier sind einige der Common Oracle-Warteereignisse, die jeder kennen sollte.

Warteereignisse
Sie können herausfinden, welche Ereignissitzung darauf wartet, indem Sie folgende Abfrage ausführen

select event from V$session_wait where sid=&1

Ich versuche, einige häufige Oracle-Warteereignisse, ihre Ursachen und Lösungen zu erklären

einreihen

Der Prozess wartet auf ein Orakel-Enqueue (eine Sperre, die Sie in v$lock sehen können). Dies tritt häufig auf, wenn ein Benutzer versucht, eine Zeile in einer Tabelle zu aktualisieren, die gerade von einem anderen Benutzer aktualisiert wird. Die Blocker können mit folgender Abfrage ermittelt werden

select * from dba_waiters

Bibliotheks-Cache-Pin
Der Prozess möchte ein Objekt im Speicher im Bibliothekscache zur Untersuchung anheften, um sicherzustellen, dass keine anderen Prozesse das Objekt gleichzeitig aktualisieren können. Dies geschieht, wenn Sie ein PL/SQL-Objekt oder eine Ansicht kompilieren oder parsen. Vermeiden Sie das Kompilieren von PL/SQL-Objekten oder Oracle-Ansichten zu Zeiten mit hoher Auslastung, um dieses Warteereignis zu vermeiden

Bibliotheks-Cache-Ladesperre
Der Prozess wartet auf die Gelegenheit, ein Objekt oder einen Teil eines Objekts in den Bibliothekscache zu laden. (Nur ein Prozess kann ein Objekt oder einen Teil eines Objekts gleichzeitig laden.)

entriegeln
Der Prozess wartet auf einen Latch, der von einem anderen Prozess gehalten wird. (Dieses Warteereignis gilt nicht für Prozesse, die sich drehen, während sie auf einen Latch warten; wenn sich ein Prozess dreht, wartet er nicht.). und Dateien.
Latches sind Sperren, die für extrem kurze Zeiträume gehalten werden sollen, z. B. die Zeit, die zum Ändern einer In-Memory-Datenstruktur benötigt wird. Sie werden verwendet, um bestimmte Speicherstrukturen zu schützen, wie z. B. den Datenbank-Blockpuffer-Cache oder den Bibliotheks-Cache im gemeinsam genutzten Pool.

Oracle Latches werden in der Regel intern in einem „Bereit zu warten“-Modus angefordert. Das bedeutet, dass, wenn der Latch nicht verfügbar ist, die anfordernde Sitzung für einen kurzen Zeitraum in den Ruhezustand versetzt wird und die Operation später erneut versucht wird. Andere Latches können in einem "sofortigen" Modus angefordert werden, der im Konzept ähnlich ist wie ein SELECT FOR UPDATE NO-WAIT, was bedeutet, dass der Prozess etwas anderes tun wird, z. anstatt herumzusitzen und darauf zu warten, dass dieser Riegel verfügbar wird. Da möglicherweise viele Anfragen gleichzeitig auf einen Latch warten, sehen Sie möglicherweise, dass einige Prozesse länger warten als andere.

Latches werden eher zufällig vergeben, wenn Sie so wollen, basierend auf dem Glück der Ziehung. Welche Sitzung direkt nach der Freigabe nach einem Latch fragt, wird es bekommen. Es gibt keine Schlange von Kellnern, nur eine Horde von Kellnern, die es ständig wiederholen.

Buffer-Busy-Wartezeiten
Der Prozess möchte auf einen Datenblock zugreifen, der sich derzeit nicht im Speicher befindet, aber ein anderer Prozess hat bereits eine E/A-Anforderung ausgegeben, um den Block in den Speicher zu lesen. (Der Prozess wartet darauf, dass der andere Prozess den Block in den Speicher bringt). Die heißen Blöcke können mit der Ansicht V$BH

gefunden werden

db-Datei verstreut gelesen
Der Prozess hat eine E/A-Anforderung ausgegeben, um eine Reihe zusammenhängender Blöcke aus einer Datendatei in den Puffercache zu lesen, und wartet auf den Abschluss des Vorgangs. Dies geschieht normalerweise während eines vollständigen Tabellenscans oder eines vollständigen Indexscans.

Wir sollten prüfen, ob die Abfrage einen vollständigen Tabellenscan verwenden sollte. Stellen Sie sicher, dass die Statistiken des Oracle-Optimierers auf dem neuesten Stand sind. Verwenden Sie Partitionsbereinigung, um die Anzahl der besuchten Blöcke zu reduzieren

Wenn eine Abfrage, die seit einiger Zeit einwandfrei läuft, plötzlich viel Zeit für das Ereignis "verstreutes Lesen" der db-Datei benötigt und keine Codeänderung stattgefunden hat, sollten Sie überprüfen, ob ein oder mehrere Indizes gelöscht wurden oder unbrauchbar werden.

sequenzielles Lesen der DB-Datei
Der Prozess hat eine E/A-Anforderung zum Lesen eines Blocks aus einer Datendatei in den Puffercache ausgegeben und wartet auf den Abschluss der Operation. Dies geschieht normalerweise während einer Indexsuche oder einem Abruf aus einer Oracle-Tabelle durch ROWID, wenn sich der erforderliche Datenblock nicht bereits im Speicher befindet. Lassen Sie sich nicht vom verwirrenden Namen dieses Warteereignisses täuschen!

Wir sollten überprüfen, ob die richtigen Indizes verwendet werden. Ein falscher Index kann dazu führen, dass die Abfrage schlecht abschneidet. Stellen Sie sicher, dass die Optimierer-Statistiken auf dem neuesten Stand sind.

db-Datei parallel lesen
Der Prozess hat mehrere E/A-Anforderungen parallel ausgegeben, um Blöcke aus Datendateien in den Speicher zu lesen, und wartet darauf, dass alle Anforderungen abgeschlossen sind. Die Dokumentation besagt, dass dieses Warteereignis nur während der Wiederherstellung auftritt, aber tatsächlich tritt es auch während der regulären Aktivität auf, wenn ein Prozess viele Einzelblock-I/O-Anforderungen zusammenfasst und sie parallel ausgibt. (Trotz des Namens werden Sie dieses Warteereignis während paralleler Abfragen oder paralleler DML nicht sehen. In diesen Fällen treten stattdessen Warteereignisse mit PX im Namen auf.)

Paralleles Schreiben der DB-Datei
Der Prozess, typischerweise DBWR, hat mehrere E/A-Anforderungen parallel ausgegeben, um fehlerhafte Blöcke aus dem Puffer-Cache auf die Festplatte zu schreiben, und wartet darauf, dass alle Anforderungen abgeschlossen sind.

direkter Pfad lesen, direkter Pfad schreiben
Der Prozess hat asynchrone E/A-Anforderungen ausgegeben, die den Puffer-Cache umgehen, und wartet darauf, dass sie abgeschlossen werden. Diese Warteereignisse beinhalten normalerweise Sortiersegmente.

SQL-Anweisungen mit Funktionen, die Sortierungen erfordern, wie ORDER BY, GROUP BY, UNION, DISTINCT und ROLLUP, schreiben Sortierläufe in den temporären Tablespace, wenn die Eingabegröße größer als der Arbeitsbereich in PGA

ist

Stellen Sie sicher, dass die Optimierungsstatistiken den Daten entsprechen und die Abfrage die richtige Fahrtabelle verwendet. Prüfen Sie, ob die Spalten des zusammengesetzten Indexes neu angeordnet werden können, damit sie mit der ORDER BY-Klausel übereinstimmen, um eine Sortierung vollständig zu vermeiden.

Stellen Sie sicher, dass der richtige Wert PGA_AGGREGATE_TARGET festgelegt ist. Verwenden Sie nach Möglichkeit UNION ALL anstelle von UNION.

Gemeinsamer Pool-Latch

Der gemeinsam genutzte Pool-Latch wird verwendet, um kritische Vorgänge beim Zuordnen und Freigeben von Speicher im gemeinsam genutzten Pool zu schützen. Konflikte um den gemeinsam genutzten Pool und die Cache-Latches der Bibliothek sind hauptsächlich auf intensives Hard-Parsing zurückzuführen. Eine harte Analyse gilt für neue Cursor und veraltete Cursor, die erneut ausgeführt werden müssen
Die Kosten für die Analyse einer neuen SQL-Anweisung sind hoch, sowohl im Hinblick auf die CPU-Anforderungen als auch auf die Anzahl der Bibliotheks-Cache und den gemeinsam genutzten Pool Sperren müssen möglicherweise erworben und freigegeben werden.

Das Eliminieren von Literal-SQL ist auch nützlich, um den gemeinsam genutzten Pool-Latch

zu vermeiden

sequenzielles Lesen von Dateien steuern
Der Prozess wartet darauf, dass Blöcke aus einer Steuerdatei gelesen werden. Dies geschieht im Allgemeinen

  • Erstellen einer Sicherungskopie der Kontrolldateien
  • Teilen von Informationen (zwischen Instanzen) aus der Steuerdatei
  • Lesen anderer Blöcke aus den Steuerdateien
  • Lesen des Header-Blocks

Wenn dies ein wichtiges Warteereignis ist, bedeutet dies, dass der Speicherort der Steuerdatei auf einen schnelleren Speicherort geändert werden muss

Paralleles Schreiben von Dateien steuern
Der Prozess hat mehrere E/A-Anforderungen parallel ausgegeben, um Blöcke in alle Steuerdateien zu schreiben, und wartet darauf, dass alle Schreibvorgänge abgeschlossen sind.

Protokollpufferspeicherplatz
Der Prozess wartet darauf, dass Speicherplatz im Protokollpuffer verfügbar wird (Speicherplatz wird erst verfügbar, nachdem LGWR den aktuellen Inhalt des Protokollpuffers auf die Festplatte geschrieben hat.) Dies geschieht normalerweise, wenn Anwendungen Redo schneller generieren, als LGWR ihn schreiben kann auf die Festplatte.

Dies kann auch passieren, wenn die Ein-/Ausgabe auf die Festplatte, auf der sich Redo-Protokolle befinden, langsam ist

Es sollte keine Wartezeiten im Protokollpuffer als solche in der Datenbank geben. Erwägen Sie, den Protokollpuffer zu vergrößern, wenn er klein ist, oder ziehen Sie in Betracht, Protokolldateien auf schnellere Festplatten wie Striped-Festplatten zu verschieben.

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');

Die pct_buff_alloc_retries sollten null oder kleiner als 0,01 (<1 %) sein. Wenn es größer ist, sollten Sie den Protokollpuffer vergrößern. Wenn es größer ist, ziehen Sie in Betracht, die Protokolldateien auf schnellere Laufwerke wie Stripeset-Laufwerke zu verschieben.

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';

Sequentielles Lesen der Protokolldatei
Der Prozess wartet darauf, dass Blöcke aus dem Online-Redo-Log in den Speicher gelesen werden. Dies tritt hauptsächlich beim Instanzstart auf und wenn die ARCH-Prozessarchive Online-Redo-Protokolle füllen.

Protokolldatei parallel schreiben
Der Prozess wartet darauf, dass Blöcke an alle Online-Redo-Log-Mitglieder in einer Gruppe geschrieben werden. LGWR ist normalerweise der einzige Prozess, der dieses Warteereignis sieht. Es wird warten, bis alle Blöcke an alle Mitglieder geschrieben wurden.

Synchronisierung der Protokolldatei
Der Prozess wartet darauf, dass LGWR das Leeren des Protokollpuffers auf die Festplatte beendet. Dies tritt auf, wenn ein Benutzer eine Transaktion festschreibt. (Eine Transaktion gilt erst dann als festgeschrieben, wenn alle Wiederholungen zur Wiederherstellung der Transaktion erfolgreich auf die Festplatte geschrieben wurden.)

Ein langsamer LGWR-Prozess kann zu Wartezeiten bei der Protokolldateisynchronisierung führen, wodurch der Benutzer beim Commit oder Rollback Wartezeiten erfährt. Die Ereignisse „Paralleles Schreiben in die Protokolldatei“ und „Protokolldateisynchronisierung warten“ sind miteinander verknüpft und müssen gleichzeitig behandelt werden.

Wir müssen versuchen, die Redo-Protokolle einer Hochleistungsfestplatte (Solid State Disk) zuzuordnen. Außerdem sollten wir versuchen, die Last auf LGWR zu reduzieren, indem wir die Commits in den Anwendungen reduzieren.

Das manuelle Hot-Backup kann auch Stress im System verursachen, indem es viele Wiederholungen erzeugt. Vermeiden Sie dies also während der Spitzenzeiten

Manchmal hungert LGWR nach CPU-Ressourcen. Wenn der Server sehr ausgelastet ist, kann LGWR auch an CPU hungern. Dies führt zu einer langsameren Reaktion von LGWR und zu längeren Wartezeiten für die Synchronisierung von Protokolldateien. Schließlich müssen diese Systemaufrufe und E/A-Aufrufe CPU verwenden. In diesem Fall ist die „Protokolldateisynchronisierung“ ein sekundäres Symptom, und die Behebung der Grundursache für eine hohe CPU-Auslastung wird die Wartezeiten für die „Protokolldateisynchronisierung“ reduzieren.

Aufgrund von Speicherproblemen kann LGWR auch ausgelagert werden. Dies kann auch zu einer langsameren Reaktion von LGWR führen.

Segmenterweiterung rückgängig machen

Die Sitzung wartet darauf, dass ein Undo-Segment erweitert oder verkleinert wird.

vollständige Wartezeiten schreiben

Die Sitzung wartet darauf, dass ein angeforderter Puffer auf die Platte geschrieben wird; der Puffer kann nicht verwendet werden, während er geschrieben wird.

Latch:Cache-Pufferketten

Die Zwischenspeicher der Cache-Pufferketten werden verwendet, um eine Pufferliste im Puffer-Cache zu schützen. Diese Latches werden beim Suchen, Hinzufügen oder Entfernen eines Puffers aus dem Puffer-Cache verwendet.

Blöcke im Puffer-Cache werden in verknüpfte Listen (Cache-Pufferketten) platziert, die an einer Hash-Tabelle hängen. Die Hash-Kette, auf der ein Block platziert wird, basiert auf dem DBA und der KLASSE des Blocks. Jede Hash-Kette wird durch ein einzelnes Kind-Latch geschützt. Prozesse müssen den relevanten Latch erhalten, damit sie eine Hash-Kette nach einem Puffer durchsuchen können, damit sich die verknüpfte Liste darunter nicht ändert.

Konkurrenz auf diesem Latch bedeutet normalerweise, dass es einen Block gibt, der stark umkämpft ist (bekannt als heißer Block).

Um die häufig aufgerufene Pufferkette und damit den umkämpften Block zu identifizieren, sehen Sie sich die Latch-Statistiken für die Latches der Cache-Pufferketten unter Verwendung der Ansicht V$LATCH_CHILDREN an. Wenn es einen bestimmten Kind-Latch von Cache-Pufferketten gibt, der im Vergleich zu den anderen Kind-Latches viel mehr GETS, MISSES und SEEPS hat, dann ist dies der umstrittene Kind-Latch.

Dieser Latch hat eine Speicheradresse, die durch die ADDR-Spalte identifiziert wird.

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
/

Verwenden Sie den Wert in der ADDR-Spalte verbunden mit der V$BH-Ansicht, um die Blöcke zu identifizieren, die durch diesen Latch geschützt sind. Wenn beispielsweise die Adresse (V$LATCH_CHILDREN.ADDR) eines stark umkämpften Latches gegeben ist, fragt dies die Datei- und Blocknummern ab:

SELECT file#, dbablk, class, state, TCH
FROM X$BH
WHERE HLADDR='address of latch';

X$BH.TCH ist ein Berührungszähler für den Puffer. Ein hoher Wert für X$BH.TCH weist auf einen Hot Block hin.

Viele Blöcke werden durch jeden Latch geschützt. Einer dieser Puffer wird wahrscheinlich der Hot Block sein. Jeder Block mit einem hohen TCH-Wert ist ein potenzieller heißer Block. Führen Sie diese Abfrage mehrmals durch und identifizieren Sie den Block, der ständig in der Ausgabe erscheint.

Nachdem Sie den heißen Block identifiziert haben, fragen Sie DBA_EXTENTS ab, indem Sie die Dateinummer und die Blocknummer verwenden, um das Segment zu identifizieren.

Wichtige Informationen zum Warteereignis

Die Ansicht v$session_wait zeigt Informationen zu Warteereignissen an, auf die derzeit aktive Sitzungen warten. Das Folgende ist die Beschreibung dieser Ansicht, und sie enthält einige sehr nützliche Spalten, insbesondere die P1- und P2-Referenzen zu den Objekten, die den Wait-Ereignissen zugeordnet sind.

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)

Mit v$session_wait ist es einfach, jeden Warteereignisparameter zu interpretieren, indem die entsprechenden beschreibenden Textspalten für diesen Parameter verwendet werden. Außerdem wurden Warteklassenspalten hinzugefügt, sodass verschiedene Warteereignisse in die zugehörigen Verarbeitungsbereiche wie Netzwerk, Anwendung, Leerlauf, Parallelität usw. gruppiert werden konnten.
Diese Spalte wurde ab 10g auch zur v$session-Tabelle hinzugefügt . Sie können also einfach v$session verwenden, um alle Details zu finden

Jedes Warteereignis enthält andere Parameter, die zusätzliche Informationen über das Ereignis bereitstellen.
So finden Sie die Informationen über das Warteereignis und seine 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';

Nehmen wir zum Beispiel an, wir haben

genommen

Die Eingabewerte für event_name:db-Datei verstreut gelesen
Ursprünglicher Wert von 3:WHERE NAME =‘&event_name A’
Der neue Wert 3:WHERE NAME =‘db-Datei verstreut gelesen’

Der Name P1 P2 P3

db-Datei verstreut gelesene Datei # Block # Blöcke

file #:Datendateinummer
Block #:Startblocknummer
blocks:zum Lesen der Nummer des Datenblocks

Lassen Sie uns nun sehen, wie uns die obigen Informationen dabei helfen können, verschiedene Dinge zu erfassen
Angenommen, eine bestimmte Sitzung wartet auf ein Buffer-Busy-Wait-Ereignis, das Datenbankobjekt, das dieses Warteereignis verursacht, kann leicht ermittelt werden:

select username, event, p1, p2 from  v$session_wait  where sid = 4563;

Die Ausgabe dieser Abfrage für eine bestimmte Sitzung mit SID 4563 könnte wie folgt aussehen:

USERNAME    EVENT            SID P1 P2
---------- ----------------- --- -- ---
APPS         buffer busy waits 4563  11  545

Die Spalten P1 und P2 ermöglichen es dem DBA, Datei- und Blocknummern zu ermitteln, die dieses Warteereignis verursacht haben. Die folgende Abfrage ruft den Objektnamen ab, der den Datenblock 155 besitzt, den Wert von P2 oben:

SQL> select segment_name,segment_type
from dba_extents
where file_id = 11
and 45 between block_id and block_id + blocks – 1;

Die Fähigkeit, Oracle Database-Warteereignisse zu analysieren und zu korrigieren, ist in jedem Optimierungsprojekt von entscheidender Bedeutung. Die meisten Aktivitäten in einer Datenbank beinhalten das Lesen von Daten, daher kann sich diese Art der Optimierung enorm positiv auf die Leistung auswirken.

Hinweis:Bei der Warteanalyse ist es wichtig, daran zu denken, dass bei allen Oracle-Datenbanken Warteereignisse auftreten und dass das Vorhandensein von Wartezeiten nicht immer auf ein Problem hinweist. Tatsächlich haben alle gut abgestimmten Datenbanken einige Engpässe.

Wir können das 10046-Ereignis auch verwenden, um das Warteereignis der Sitzung zu verfolgen

Liest auch
Oracle-Dokumentation
v$active_session_history
Plan in Oracle erläutern