

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Optimierung mit Warteereignissen für RDS für PostgreSQL
<a name="PostgreSQL.Tuning"></a>

Warteereignisse sind ein wichtiges Optimierungs-Tool für RDS für PostgreSQL. Wenn Sie herausfinden können, warum Sitzungen auf Ressourcen warten und was sie tun, können Sie Engpässe besser reduzieren. Anhand der Informationen in diesem Abschnitt können Sie mögliche Ursachen und Abhilfemaßnahmen ermitteln. In diesem Abschnitt werden außerdem grundlegende PostgreSQL-Optimierungskonzepte erörtert.

Die Warteereignisse in diesem Abschnitt gelten speziell für RDS für PostgreSQL.

**Topics**
+ [Grundlegende Konzepte für die Optimierung von RDS für PostgreSQL](PostgreSQL.Tuning.concepts.md)
+ [Warteereignisse von RDS für PostgreSQL](PostgreSQL.Tuning.concepts.summary.md)
+ [Kunde: ClientRead](wait-event.clientread.md)
+ [Kunde: ClientWrite](wait-event.clientwrite.md)
+ [CPU](wait-event.cpu.md)
+ [IO: BufFileRead und IO: BufFileWrite](wait-event.iobuffile.md)
+ [IO: DataFileRead](wait-event.iodatafileread.md)
+ [IO:WALWrite](wait-event.iowalwrite.md)
+ [IPC:parallel-Warteereignisse](rpg-ipc-parallel.md)
+ [IPC: ProcArrayGroupUpdate](apg-rpg-ipcprocarraygroup.md)
+ [Lock:advisory](wait-event.lockadvisory.md)
+ [Lock:extend](wait-event.lockextend.md)
+ [Lock:Relation](wait-event.lockrelation.md)
+ [Lock:transactionid](wait-event.locktransactionid.md)
+ [Lock:tuple](wait-event.locktuple.md)
+ [LWLock: BufferMapping (:buffer\$1mapping) LWLock](wait-event.lwl-buffer-mapping.md)
+ [LWLock:BufferIO (IPC:BufferIO)](wait-event.lwlockbufferio.md)
+ [LWLock:buffer\$1content (BufferContent)](wait-event.lwlockbuffercontent.md)
+ [LWLock:lock\$1manager (:lockmanager) LWLock](wait-event.lw-lock-manager.md)
+ [LWLock:pg\$1stat\$1statements](apg-rpg-lwlockpgstat.md)
+ [LWLock:subtransSLRU (:) LWLock SubtransControlLock](wait-event.lwlocksubtransslru.md)
+ [Timeout:PgSleep](wait-event.timeoutpgsleep.md)
+ [Timeout:VacuumDelay](wait-event.timeoutvacuumdelay.md)

# Grundlegende Konzepte für die Optimierung von RDS für PostgreSQL
<a name="PostgreSQL.Tuning.concepts"></a>

Bevor Sie Ihre Datenbank von RDS für PostgreSQL optimieren, sollten Sie wissen, was Warteereignisse sind und warum sie auftreten. Sehen Sie sich auch die grundlegende Speicher- und Festplattenarchitektur von RDS für PostgreSQL an. Ein hilfreiches Architekturdiagramm finden Sie im [PostgreSQL](https://en.wikibooks.org/wiki/PostgreSQL/Architecture)-Wikibook.

**Topics**
+ [Warteereignisse von RDS für PostgreSQL](PostgreSQL.Tuning.concepts.waits.md)
+ [Speicher von RDS für PostgreSQL](PostgreSQL.Tuning.concepts.memory.md)
+ [Prozesse von RDS für PostgreSQL](PostgreSQL.Tuning.concepts.processes.md)

# Warteereignisse von RDS für PostgreSQL
<a name="PostgreSQL.Tuning.concepts.waits"></a>

Ein *Warteereignis* ist ein Hinweis darauf, dass die Sitzung auf eine Ressource wartet. Das Warteereignis `Client:ClientRead` tritt beispielsweise auf, wenn RDS für PostgreSQL darauf wartet, Daten vom Client zu empfangen. Sitzungen warten in der Regel auf Ressourcen wie die folgenden.
+ Singlethread-Zugriff auf einen Puffer, beispielsweise wenn eine Sitzung versucht, einen Puffer zu ändern
+ Eine Zeile, die derzeit von einer anderen Sitzung gesperrt ist
+ Eine gelesene Datendatei
+ Eine geschriebene Protokolldatei

Um beispielsweise eine Abfrage zu erfüllen, kann die Sitzung einen vollständigen Tabellenscan durchführen. Wenn sich die Daten noch nicht im Arbeitsspeicher befinden, wartet die Sitzung, bis die Datenträger-I/O abgeschlossen ist. Wenn die Puffer in den Speicher gelesen werden, muss die Sitzung möglicherweise warten, da andere Sitzungen auf dieselben Puffer zugreifen. Die Datenbank zeichnet die Wartezeiten unter Verwendung eines vordefinierten Warteereignisses auf. Diese Ereignisse sind in Kategorien eingeteilt.

Ein einzelnes Warteereignis ist kein Anzeichen für ein Leistungsproblem. Wenn sich beispielsweise die angeforderten Daten nicht im Speicher befinden, müssen die Daten von der Festplatte gelesen werden. Wenn eine Sitzung eine Zeile für eine Aktualisierung sperrt, wartet eine andere Sitzung darauf, dass die Zeile entsperrt wird, damit sie sie aktualisieren kann. Bei einem Commit muss gewartet werden, bis der Schreibvorgang in eine Protokolldatei abgeschlossen ist. Wartezeiten sind ein wesentlicher Bestandteil des normalen Funktionierens einer Datenbank. 

Eine große Anzahl von Warteereignissen hingegen weist normalerweise auf ein Leistungsproblem hin. In solchen Fällen können Sie Warteereignisdaten verwenden, um zu bestimmen, wo die Sitzungen Zeit verbringen. Wenn beispielsweise ein Bericht, der normalerweise in Minuten ausgeführt wird, jetzt Stunden dauert, können Sie die Warteereignisse identifizieren, die am meisten zur Gesamtwartezeit beitragen. Wenn Sie die Ursachen für die häufigsten Warteereignisse ermitteln können, können Sie manchmal Änderungen vornehmen, die die Leistung verbessern. Wenn Ihre Sitzung beispielsweise auf eine Zeile wartet, die von einer anderen Sitzung gesperrt wurde, können Sie die Sperrsitzung beenden. 

# Speicher von RDS für PostgreSQL
<a name="PostgreSQL.Tuning.concepts.memory"></a>

Der Arbeitsspeicher von RDS für PostgreSQL ist in gemeinsam genutztem und lokalem Speicher unterteilt.

**Topics**
+ [Gemeinsam genutzter Arbeitsspeicher von RDS für PostgreSQL](#PostgreSQL.Tuning.concepts.shared)
+ [Lokaler Arbeitsspeicher in RDS für PostgreSQL](#PostgreSQL.Tuning.concepts.local)

## Gemeinsam genutzter Arbeitsspeicher von RDS für PostgreSQL
<a name="PostgreSQL.Tuning.concepts.shared"></a>

RDS für PostgreSQL weist beim Start der Instance gemeinsam genutzten Speicher zu. Shared Memory ist in mehrere Teilbereiche unterteilt. Die folgenden Abschnitte enthalten Beschreibungen der wichtigsten Teilbereiche.

**Topics**
+ [Freigegebene Puffer](#PostgreSQL.Tuning.concepts.buffer-pool)
+ [Write-Ahead-Protokoll (WAL)-Puffer](#PostgreSQL.Tuning.concepts.WAL)

### Freigegebene Puffer
<a name="PostgreSQL.Tuning.concepts.buffer-pool"></a>

Der *freigegebene Pufferpool* ist ein Speicherbereich von RDS für PostgreSQL, der alle Seiten enthält, die von Anwendungsverbindungen verwendet werden oder wurden. Eine *Seite* ist die Speicherversion eines Plattenblocks. Der gemeinsam genutzte Pufferpool zwischenspeichert die von der Platte gelesenen Datenblöcke. Der Pool reduziert die Notwendigkeit, Daten erneut von der Festplatte zu lesen, wodurch die Datenbank effizienter arbeitet.

Jede Tabelle und jeder Index wird als Array von Seiten einer festen Größe gespeichert. Jeder Block enthält mehrere Tupel, die Zeilen entsprechen. Ein Tupel kann auf jeglicher Seite gespeichert werden.

Der gemeinsam genutzte Pufferpool hat endlichen Speicher. Wenn eine neue Anforderung eine Seite erfordert, die sich nicht im Speicher befindet und kein Speicher mehr vorhanden ist, entfernt RDS für PostgreSQL eine weniger häufig verwendete Seite, um die Anforderung zu erfüllen. Die Räumungsrichtlinie wird durch einen Takt-Sweep-Algorithmus implementiert.

Der Parameter `shared_buffers` bestimmt, wie viel Speicher der Server für das Caching von Daten bereitstellt. Der Standardwert ist auf `{DBInstanceClassMemory/32768}` Byte festgelegt, basierend auf dem verfügbaren Speicher für die DB-Instance.

### Write-Ahead-Protokoll (WAL)-Puffer
<a name="PostgreSQL.Tuning.concepts.WAL"></a>

Ein *Write-Ahead-Protokoll-Puffer (WAL)* enthält Transaktionsdaten, die RDS für PostgreSQL später in den persistenten Speicher schreibt. Mithilfe des WAL-Mechanismus kann RDS für PostgreSQL folgende Vorgänge ausführen:
+ Daten nach einem Fehler wiederherstellen
+ Reduzieren Sie die I/O Festplattenkapazität, indem Sie häufige Schreibvorgänge auf die Festplatte vermeiden

Wenn ein Client Daten ändert, schreibt RDS für PostgreSQL die Änderungen in den WAL-Puffer. Wenn der Client einen `COMMIT` ausgibt, schreibt der WAL-Writerprozess Transaktionsdaten in die WAL-Datei.

Der Parameter `wal_level` bestimmt, wie viele Informationen in das WAL geschrieben werden. Mögliche Werte sind zum Beispiel `minimal`, `replica` und `logical`.

## Lokaler Arbeitsspeicher in RDS für PostgreSQL
<a name="PostgreSQL.Tuning.concepts.local"></a>

Jeder Backend-Prozess weist lokalen Speicher für die Abfrageverarbeitung zu.

**Topics**
+ [Arbeitsspeicherbereich](#PostgreSQL.Tuning.concepts.local.work_mem)
+ [Wartungs-Arbeitsspeicherbereich](#PostgreSQL.Tuning.concepts.local.maintenance_work_mem)
+ [Temporärer Pufferbereich](#PostgreSQL.Tuning.concepts.temp)

### Arbeitsspeicherbereich
<a name="PostgreSQL.Tuning.concepts.local.work_mem"></a>

Der *Arbeitsspeicherbereich* enthält temporäre Daten für Abfragen, die Sortierungen und Hashes durchführen. Beispielsweise führt eine Abfrage mit einer `ORDER BY`-Klausel eine Sortierung durch. Abfragen verwenden Hash-Tabellen in Hash-Joins und Aggregationen.

Der Parameter `work_mem` für die Speichergröße, die von internen Sortiervorgängen und Hash-Tabellen belegt werden soll, bevor in temporäre Festplattendateien geschrieben wird, gemessen in Megabyte. Der Standardwert lautet 4 MB. Mehrere Sitzungen können gleichzeitig ausgeführt werden, und jede Sitzung kann Wartungsvorgänge parallel ausführen. Aus diesem Grund kann der gesamte verwendete Arbeitsspeicher ein Vielfaches der Einstellung `work_mem` betragen. 

### Wartungs-Arbeitsspeicherbereich
<a name="PostgreSQL.Tuning.concepts.local.maintenance_work_mem"></a>

Der *Wartungsarbeitsspeicherbereich* speichert Daten für Wartungsvorgänge zwischen. Zu diesen Vorgängen gehören das Vakuumieren, das Erstellen eines Index und das Hinzufügen von Fremdschlüsseln.

Der Parameter `maintenance_work_mem` gibt die maximale Speichergröße an, die von Wartungsvorgängen verwendet werden soll, gemessen in Megabyte. Der Standardwert lautet 64 MB. In einer Datenbanksitzung kann jeweils nur ein Wartungsvorgang ausgeführt werden.

### Temporärer Pufferbereich
<a name="PostgreSQL.Tuning.concepts.temp"></a>

Der *temporäre Pufferbereich* speichert temporäre Tabellen für jede Datenbanksitzung zwischen.

Jede Sitzung weist temporäre Puffer nach Bedarf bis zu dem von Ihnen angegebenen Limit zu. Wenn die Sitzung endet, löscht der Server die Puffer.

Der Parameter `temp_buffers` legt die maximale Anzahl temporärer Puffer fest, die von der jeweiligen Sitzung verwendet werden, gemessen in Megabyte. Der Standardwert ist 8 MB. Vor der ersten Verwendung temporärer Tabellen innerhalb einer Sitzung können Sie den `temp_buffers`-Wert ändern.

# Prozesse von RDS für PostgreSQL
<a name="PostgreSQL.Tuning.concepts.processes"></a>

RDS für PostgreSQL verwendet mehrere Prozesse.

**Topics**
+ [Postmaster-Prozess](#PostgreSQL.Tuning.concepts.postmaster)
+ [Backend-Prozesse](#PostgreSQL.Tuning.concepts.backend)
+ [Hintergrundprozesse](#PostgreSQL.Tuning.concepts.vacuum)

## Postmaster-Prozess
<a name="PostgreSQL.Tuning.concepts.postmaster"></a>

Der *Postmaster-Prozess* ist der erste Prozess, der beim Öffnen von RDS für PostgreSQL gestartet wird. Der Postmaster-Prozess hat die folgenden Hauptaufgaben:
+ Hintergrundprozesse teilen und überwachen
+ Empfangen Sie Authentifizierungsanfragen von Clientprozessen und authentifizieren Sie sie, bevor Sie der Datenbank erlauben, Anfragen zu bearbeiten

## Backend-Prozesse
<a name="PostgreSQL.Tuning.concepts.backend"></a>

Wenn der Postmaster eine Client-Anfrage authentifiziert, forkisiert der Postmaster einen neuen Backend-Prozess, auch Postgres-Prozess genannt. Ein Client-Prozess verbindet sich mit genau einem Backend-Prozess. Der Client-Prozess und der Backend-Prozess kommunizieren direkt ohne Eingriff des Postmaster-Prozesses.

## Hintergrundprozesse
<a name="PostgreSQL.Tuning.concepts.vacuum"></a>

Der Postmaster-Prozess teilt mehrere Prozesse, die unterschiedliche Backend-Aufgaben ausführen. Einige der wichtigeren sind die folgenden:
+ WAL-Writer

  Aurora PostgreSQL schreibt Daten im WAL-Puffer (Write Ahead Logging) in die Protokolldateien. Das Prinzip der Write-Ahead-Protokollierung besteht darin, dass die Datenbank keine Änderungen in die Datendateien schreiben kann, bis die Datenbank Protokolldatensätze geschrieben hat, die diese Änderungen auf die Festplatte beschreiben. Der WAL-Mechanismus reduziert Festplatten-I/O und ermöglicht RDS für PostgreSQL, die Protokolle zu verwenden, um die Datenbank nach einem Fehler wiederherzustellen.
+ Hintergrund-Autor

  Dieser Prozess schreibt regelmäßig schmutzige (modifizierte) Seiten aus den Speicherpuffern in die Datendateien. Eine Seite wird schmutzig, wenn ein Backend-Prozess sie im Speicher ändert.
+ Autovacuum-Daemon

  Der Daemon besteht aus Folgendem:
  + Der Autovacuum-Launcher
  + Die Autovacuum-Worker-Prozesse

  Wenn Autovacuum aktiviert ist, sucht es nach Tabellen mit einer großen Anzahl eingefügter, aktualisierter oder gelöschter Tupel. Der Daemon hat folgende Aufgaben:
  + Wiederherstellen oder Wiederverwenden von Speicherplatz, der von aktualisierten oder gelöschten Zeilen belegt ist
  + Vom Planer verwendete Statistiken aktualisieren
  + Schutz vor Verlust alter Daten durch Transaktions-ID-Wraparound

  Die Autovacuum-Funktion automatisiert die Ausführung von `VACUUM`- und `ANALYZE`-Befehlen. `VACUUM` hat folgende Varianten: Standard und Voll. Standardvakuum läuft parallel zu anderen Datenbankvorgängen. `VACUUM FULL` erfordert eine exklusive Sperre für die Tabelle, an der es arbeitet. Daher kann es nicht parallel zu Vorgängen ausgeführt werden, die auf dieselbe Tabelle zugreifen. `VACUUM`erzeugt eine beträchtliche Menge an I/O Datenverkehr, was zu Leistungseinbußen bei anderen aktiven Sitzungen führen kann.

# Warteereignisse von RDS für PostgreSQL
<a name="PostgreSQL.Tuning.concepts.summary"></a>

Die folgende Tabelle listet die Warteereignisse für RDS für PostgreSQL auf, die am häufigsten auf Leistungsprobleme hinweisen, und fasst die häufigsten Ursachen und Korrekturmaßnahmen zusammen.


| Warteereignis | Definition | 
| --- | --- | 
|  [Kunde: ClientRead](wait-event.clientread.md)  |  Dieses Ereignis tritt auf, wenn RDS für PostgreSQL darauf wartet, Daten vom Client zu empfangen.  | 
|  [Kunde: ClientWrite](wait-event.clientwrite.md)  |  Dieses Ereignis tritt auf, wenn RDS für PostgreSQL darauf wartet, Daten an den Client zu schreiben.  | 
|  [CPU](wait-event.cpu.md)  | Dieses Ereignis tritt auf, wenn ein Thread in der CPU aktiv ist oder auf die CPU wartet.  | 
|  [IO: BufFileRead und IO: BufFileWrite](wait-event.iobuffile.md)  |  Diese Ereignisse treten auf, wenn RDS für PostgreSQL temporäre Dateien erstellt.  | 
|  [IO: DataFileRead](wait-event.iodatafileread.md)  |  Dieses Ereignis tritt auf, wenn eine Verbindung darauf wartet, dass ein Backend-Prozess eine erforderliche Seite aus dem Speicher liest, da die Seite nicht im gemeinsam genutzten Speicher verfügbar ist.   | 
| [IO:WALWrite](wait-event.iowalwrite.md)  | Dieses Ereignis tritt auf, wenn RDS für PostgreSQL darauf wartet, dass die Write-Ahead-Protokoll-Puffer (WAL) in eine WAL-Datei geschrieben werden.  | 
|  [Lock:advisory](wait-event.lockadvisory.md)  |  Dieses Ereignis tritt auf, wenn eine PostgreSQL-Anwendung eine Sperre verwendet, um Aktivitäten über mehrere Sitzungen hinweg zu koordinieren.  | 
|  [Lock:extend](wait-event.lockextend.md) |  Dieses Ereignis tritt ein, wenn ein Backend-Prozess darauf wartet, eine Beziehung zu sperren, um sie zu erweitern, während ein anderer Prozess diese Beziehung für denselben Zweck gesperrt hat.  | 
|  [Lock:Relation](wait-event.lockrelation.md)  |  Dieses Ereignis tritt ein, wenn eine Abfrage darauf wartet, eine Sperre für eine Tabelle oder Ansicht zu erhalten, die derzeit von einer anderen Transaktion gesperrt ist.  | 
|  [Lock:transactionid](wait-event.locktransactionid.md)  | Dieses Ereignis tritt ein, wenn eine Transaktion auf eine Sperre auf Zeilenebene wartet. | 
|  [Lock:tuple](wait-event.locktuple.md)  |  Dieses Ereignis tritt ein, wenn ein Backend-Prozess darauf wartet, eine Sperre für ein Tupel zu erlangen.  | 
|  [LWLock: BufferMapping (:buffer\$1mapping) LWLock](wait-event.lwl-buffer-mapping.md)  |  Dieses Ereignis tritt ein, wenn eine Sitzung darauf wartet, einen Datenblock einem Puffer im gemeinsam genutzten Pufferpool zuzuordnen.  | 
|  [LWLock:BufferIO (IPC:BufferIO)](wait-event.lwlockbufferio.md)  |  Dieses Ereignis tritt auf, wenn RDS for PostgreSQL darauf wartet, dass andere Prozesse ihre input/output (I/O-) Operationen beenden, wenn gleichzeitig versucht wird, auf eine Seite zuzugreifen.  | 
|  [LWLock:buffer\$1content (BufferContent)](wait-event.lwlockbuffercontent.md)  |  Dieses Ereignis tritt ein, wenn eine Sitzung darauf wartet, eine Datenseite im Speicher zu lesen oder zu schreiben, während eine andere Sitzung diese Seite zum Schreiben gesperrt hat.  | 
|  [LWLock:lock\$1manager (:lockmanager) LWLock](wait-event.lw-lock-manager.md)  | Dieses Ereignis tritt auf, wenn die Engine von RDS für PostgreSQL den Speicherbereich der gemeinsam genutzten Sperre verwaltet, um eine Sperre zuzuweisen, zu überprüfen und aufzuheben, wenn eine Fast-Path-Sperre nicht möglich ist. | 
|  [LWLock:subtransSLRU (:) LWLock SubtransControlLock](wait-event.lwlocksubtransslru.md)  |  Dieses Ereignis tritt auf, wenn ein Prozess darauf wartet, auf den SLRU-Cache (Simple Least-Recently Used) für eine Subtransaktion zuzugreifen.  | 
|  [Timeout:PgSleep](wait-event.timeoutpgsleep.md)  |  Dieses Ereignis tritt ein, wenn ein Serverprozess die Funktion `pg_sleep` aufgerufen hat und darauf wartet, dass das Sleep-Timeout abläuft.   | 
|  [Timeout:VacuumDelay](wait-event.timeoutvacuumdelay.md)  | Dieses Ereignis weist darauf hin, dass der Bereinigungsprozess inaktiv ist, da die geschätzte Kostengrenze erreicht wurde.  | 

# Kunde: ClientRead
<a name="wait-event.clientread"></a>

Das `Client:ClientRead`-Ereignis tritt auf, wenn RDS für PostgreSQL darauf wartet, Daten vom Client zu empfangen.

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.clientread.context.supported)
+ [Kontext](#wait-event.clientread.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.clientread.causes)
+ [Aktionen](#wait-event.clientread.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.clientread.context.supported"></a>

Diese Warteereignisinformationen werden für RDS für PostgreSQL Version 10 und höher unterstützt.

## Kontext
<a name="wait-event.clientread.context"></a>

Eine DB-Instance von RDS für PostgreSQL wartet darauf, Daten vom Client zu empfangen. Die DB-Instance von RDS für PostgreSQL muss die Daten vom Client empfangen, bevor sie weitere Daten an den Client senden kann. Die Zeit, die die Instance wartet, bevor sie Daten vom Client empfängt, ist ein `Client:ClientRead`-Ereignis.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.clientread.causes"></a>

Häufige Gründe dafür, dass das `Client:ClientRead`-Ereignis in den Top-Wartezeiten angezeigt wird, sind die folgenden: 

**Erhöhte Netzwerklatenz**  
Es kann zu einer erhöhten Netzwerklatenz zwischen dem DB-Cluster von RDS für PostgreSQL und dem Client kommen. Eine höhere Netzwerklatenz erhöht die Zeit, die die DB-Instance benötigt, um Daten vom Client zu empfangen.

**Erhöhte Belastung des Clients**  
Auf dem Client kann es zu CPU-Druck oder Netzwerksättigung kommen. Eine Zunahme der Last auf dem Client kann die Übertragung von Daten vom Client zur DB-Instance von RDS für PostgreSQL verzögern.

**Übermäßige Netzwerkrundfahrten**  
Eine große Anzahl von Netzwerk-Roundtrips zwischen der DB-Instance von RDS für PostgreSQL und dem Client kann die Datenübertragung vom Client zur DB-Instance von RDS für PostgreSQL verzögern.

**Großer Kopiervorgang**  
Während eines Kopiervorgangs werden die Daten vom Dateisystem des Clients an die DB-Instance von RDS für PostgreSQL übertragen. Das Senden einer großen Datenmenge an die DB-Instance kann die Übertragung von Daten vom Client zur DB-Instance verzögern.

**Verbindung von Clients im Leerlauf**  
Wenn sich ein Client in einem `idle in transaction`-Zustand mit der DB-Instance von RDS für PostgreSQL verbindet, wartet die DB-Instance möglicherweise darauf, dass der Client weitere Daten sendet oder einen Befehl ausgibt. Eine Verbindung in diesem Zustand kann zu einer Zunahme von `Client:ClientRead`-Ereignissen führen.

**PgBouncer wird für das Verbindungspooling verwendet**  
PgBouncer hat eine Netzwerkkonfigurationseinstellung auf niedriger Ebene aufgerufen`pkt_buf`, die standardmäßig auf 4.096 gesetzt ist. Wenn der Workload Abfragepakete mit mehr als 4.096 Byte durchsendet, empfehlen wir PgBouncer, die Einstellung auf 8.192 zu erhöhen. `pkt_buf` Wenn die neue Einstellung die Anzahl der `Client:ClientRead`-Ereignisse nicht verringert, empfehlen wir, die `pkt_buf`-Einstellung auf höhere Werte zu erhöhen, z. B. 16.384 oder 32.768. Wenn der Abfragetext groß ist, kann die größere Einstellung besonders hilfreich sein.

## Aktionen
<a name="wait-event.clientread.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen.

**Topics**
+ [Platzieren Sie die Clients in derselben Availability Zone und im gleichen VPC-Subnetz wie die Instance](#wait-event.clientread.actions.az-vpc-subnet)
+ [Skalieren Sie Ihren -C](#wait-event.clientread.actions.scale-client)
+ [Instances der aktuellen Generation verwenden](#wait-event.clientread.actions.db-instance-class)
+ [Erhöhung der Netzwerkbandbreite](#wait-event.clientread.actions.increase-network-bandwidth)
+ [Überwachen Sie Maximen für die Netzwerkleistung](#wait-event.clientread.actions.monitor-network-performance)
+ [Überwachen Sie auf Transaktionen im Status „Leerlauf in Transaktion“](#wait-event.clientread.actions.check-idle-in-transaction)

### Platzieren Sie die Clients in derselben Availability Zone und im gleichen VPC-Subnetz wie die Instance
<a name="wait-event.clientread.actions.az-vpc-subnet"></a>

Um die Netzwerklatenz zu reduzieren und den Netzwerkdurchsatz zu erhöhen, platzieren Sie Clients in dieselbe Availability Zone und das gleiche Virtual Private Cloud (VPC)-Subnetz wie die DB-Instance von RDS für PostgreSQL. Stellen Sie sicher, dass sich die Clients geografisch so nah wie möglich an der DB-Instance befinden.

### Skalieren Sie Ihren -C
<a name="wait-event.clientread.actions.scale-client"></a>

Ermitteln Sie anhand von Amazon CloudWatch oder anderen Host-Metriken, ob Ihr Client derzeit durch CPU- oder Netzwerkbandbreite oder beides eingeschränkt ist. Wenn der Kunde eingeschränkt ist, skalieren Sie Ihren Kunden entsprechend.

### Instances der aktuellen Generation verwenden
<a name="wait-event.clientread.actions.db-instance-class"></a>

In einigen Fällen verwenden Sie möglicherweise keine DB-Instance-Klasse, die Jumbo-Frames unterstützt. Wenn Sie Ihre Anwendung auf Amazon EC2 ausführen, sollten Sie eine Instance der aktuellen Generation für den Client verwenden. Konfigurieren Sie außerdem die maximale Übertragungseinheit (MTU) im Kundenvorgangssystem Diese Technik könnte die Anzahl der Netzläufe reduzieren und den Netzwerkdurchsatz erhöhen. Weitere Informationen finden Sie unter [Jumbo-Frames (9.001 MTU)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) im *Amazon-EC2-Benutzerhandbuch*.

Weitere Informationen zu DB-Instance-Klassen finden Sie unter [](Concepts.DBInstanceClass.md). Um die DB-Instance-Klasse zu bestimmen, die einem Amazon EC2-Instance-Typ entspricht, platzieren Sie `db.` vor dem Namen des Amazon EC2-Instance-Typs. Beispielsweise entspricht die `r5.8xlarge`-Amazon EC2-Instance der `db.r5.8xlarge`-DB-Instance-Klasse.

### Erhöhung der Netzwerkbandbreite
<a name="wait-event.clientread.actions.increase-network-bandwidth"></a>

Verwenden Sie `NetworkReceiveThroughput` und `NetworkTransmitThroughput` CloudWatch Amazon-Metriken, um den eingehenden und ausgehenden Netzwerkverkehr auf der DB-Instance zu überwachen. Diese Metriken können Ihnen helfen festzustellen, ob die Netzwerkbandbreite für Ihre Workload ausreicht. 

Wenn Ihre Netzwerkbandbreite nicht ausreicht, erhöhen Sie sie. Wenn der AWS Client oder Ihre DB-Instance die Netzwerkbandbreitenlimits erreicht, besteht die einzige Möglichkeit, die Bandbreite zu erhöhen, darin, Ihre DB-Instance-Größe zu erhöhen. Weitere Informationen finden Sie unter [DB-Instance-Klassenarten](Concepts.DBInstanceClass.Types.md).

Weitere Informationen zu CloudWatch Metriken finden Sie unter[CloudWatch Amazon-Metriken für Amazon RDS](rds-metrics.md). 

### Überwachen Sie Maximen für die Netzwerkleistung
<a name="wait-event.clientread.actions.monitor-network-performance"></a>

Wenn Sie Amazon EC2-Clients verwenden, bietet Amazon EC2 Maximum für Netzwerkleistungsmetriken, einschließlich der aggregierten eingehenden und ausgehenden Netzwerkbandbreite. Es bietet auch Verbindungsverfolgung, um sicherzustellen, dass Pakete wie erwartet zurückgegeben werden, und Zugriff auf Link-lokale Dienste für Dienste wie das Domain Name System (DNS). Um diese Maximen zu überwachen, verwenden Sie einen aktuell erweiterten Netzwerktreiber und überwachen Sie die Netzwerkleistung für Ihren Client. 

Weitere Informationen finden Sie unter [Überwachen der Netzwerkleistung für Ihre Amazon-EC2-Instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html) im *Amazon-EC2-Benutzerhandbuch* und unter [Überwachen der Netzwerkleistung für Ihre Amazon-EC2-Instance](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/monitoring-network-performance-ena.html) im *Amazon-EC2-Benutzerhandbuch*.

### Überwachen Sie auf Transaktionen im Status „Leerlauf in Transaktion“
<a name="wait-event.clientread.actions.check-idle-in-transaction"></a>

Überprüfen Sie, ob Sie eine steigende Anzahl von `idle in transaction`-Verbindungen haben. Beobachten Sie dazu die `state`-Spalte in der `pg_stat_activity`-Tabelle. Möglicherweise können Sie die Verbindungsquelle identifizieren, indem Sie eine Abfrage ähnlich der folgenden ausführen.

```
select client_addr, state, count(1) from pg_stat_activity 
where state like 'idle in transaction%' 
group by 1,2 
order by 3 desc
```

# Kunde: ClientWrite
<a name="wait-event.clientwrite"></a>

Das `Client:ClientWrite`-Ereignis tritt auf, wenn RDS für PostgreSQL darauf wartet, Daten an den Client zu schreiben.

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.clientwrite.context.supported)
+ [Kontext](#wait-event.clientwrite.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.clientwrite.causes)
+ [Aktionen](#wait-event.clientwrite.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.clientwrite.context.supported"></a>

Diese Warteereignisinformationen werden für RDS für PostgreSQL Version 10 und höher unterstützt.

## Kontext
<a name="wait-event.clientwrite.context"></a>

Ein Clientprozess muss alle Daten lesen, die von einem DB-Cluster von RDS für PostgreSQL empfangen wurden, bevor der Cluster weitere Daten senden kann. Die Zeit, die der Cluster wartet, bevor weitere Daten an den Client gesendet werden, ist ein `Client:ClientWrite`-Ereignis.

Ein reduzierter Netzwerkdurchsatz zwischen dem DB-Cluster von RDS für PostgreSQL und dem Client kann dieses Ereignis verursachen. CPU-Druck und Netzwerksättigung auf dem Client können dieses Ereignis ebenfalls verursachen. *CPU-Druck* liegt vor, wenn die CPU voll ausgelastet ist und Aufgaben auf CPU-Zeit warten. *Eine Netzwerksättigung* liegt vor, wenn das Netzwerk zwischen Datenbank und Client mehr Daten überträgt, als es verarbeiten kann. 

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.clientwrite.causes"></a>

Häufige Gründe dafür, dass das `Client:ClientWrite`-Ereignis in den Top-Wartezeiten angezeigt wird, sind die folgenden: 

**Erhöhte Netzwerklatenz**  
Es kann zu einer erhöhten Netzwerklatenz zwischen dem DB-Cluster von RDS für PostgreSQL und dem Client kommen. Eine höhere Netzwerklatenz erhöht die Zeit, die der Client benötigt, um die Daten zu empfangen.

**Erhöhte Belastung des Clients**  
Auf dem Client kann es zu CPU-Druck oder Netzwerksättigung kommen. Eine Erhöhung der Last des Clients verzögert den Empfang von Daten aus der DB-Instance von RDS für PostgreSQL.

**Große Datenmenge, die an den Kunden gesendet werden**  
Die DB-Instance von RDS für PostgreSQL sendet möglicherweise eine große Datenmenge an den Client. Ein Client kann die Daten möglicherweise nicht so schnell empfangen, wie der Cluster sie sendet. Aktivitäten wie das Kopieren einer großen Tabelle können zu einer Zunahme von `Client:ClientWrite`-Ereignissen führen.

## Aktionen
<a name="wait-event.clientwrite.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen.

**Topics**
+ [Platzieren Sie die Clients im selben Availability Zone- und VPC-Subnetz wie der Cluster](#wait-event.clientwrite.actions.az-vpc-subnet)
+ [Instances der aktuellen Generation verwenden](#wait-event.clientwrite.actions.db-instance-class)
+ [Reduzieren Sie die an den Kunden gesendeten Daten](#wait-event.clientwrite.actions.reduce-data)
+ [Skalieren Sie Ihren -C](#wait-event.clientwrite.actions.scale-client)

### Platzieren Sie die Clients im selben Availability Zone- und VPC-Subnetz wie der Cluster
<a name="wait-event.clientwrite.actions.az-vpc-subnet"></a>

Um die Netzwerklatenz zu reduzieren und den Netzwerkdurchsatz zu erhöhen, platzieren Sie Clients in dieselbe Availability Zone und das gleiche Virtual Private Cloud (VPC)-Subnetz wie die DB-Instance von RDS für PostgreSQL.

### Instances der aktuellen Generation verwenden
<a name="wait-event.clientwrite.actions.db-instance-class"></a>

In einigen Fällen verwenden Sie möglicherweise keine DB-Instance-Klasse, die Jumbo-Frames unterstützt. Wenn Sie Ihre Anwendung auf Amazon EC2 ausführen, sollten Sie eine Instance der aktuellen Generation für den Client verwenden. Konfigurieren Sie außerdem die maximale Übertragungseinheit (MTU) im Kundenvorgangssystem Diese Technik könnte die Anzahl der Netzläufe reduzieren und den Netzwerkdurchsatz erhöhen. Weitere Informationen finden Sie unter [Jumbo-Frames (9.001 MTU)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) im *Amazon-EC2-Benutzerhandbuch*.

Weitere Informationen zu DB-Instance-Klassen finden Sie unter [](Concepts.DBInstanceClass.md). Um die DB-Instance-Klasse zu bestimmen, die einem Amazon EC2-Instance-Typ entspricht, platzieren Sie `db.` vor dem Namen des Amazon EC2-Instance-Typs. Beispielsweise entspricht die `r5.8xlarge`-Amazon EC2-Instance der `db.r5.8xlarge`-DB-Instance-Klasse.

### Reduzieren Sie die an den Kunden gesendeten Daten
<a name="wait-event.clientwrite.actions.reduce-data"></a>

Passen Sie Ihre Anwendung nach Möglichkeit an, um die Datenmenge zu reduzieren, die die DB-Instance von RDS für PostgreSQL Cluster an den Client sendet. Solche Anpassungen entlasten die CPU- und Netzwerkkonflikte auf dem Client.

### Skalieren Sie Ihren -C
<a name="wait-event.clientwrite.actions.scale-client"></a>

Ermitteln Sie anhand von Amazon CloudWatch oder anderen Host-Metriken, ob Ihr Client derzeit durch CPU- oder Netzwerkbandbreite oder beides eingeschränkt ist. Wenn der Client eingeschränkt ist, skalieren Sie Ihren Client entsprechend.

# CPU
<a name="wait-event.cpu"></a>

Dieses Ereignis tritt auf, wenn ein Thread in der CPU aktiv ist oder auf die CPU wartet.

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.cpu.context.supported)
+ [Kontext](#wait-event.cpu.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.cpu.causes)
+ [Aktionen](#wait-event.cpu.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.cpu.context.supported"></a>

Diese Warteereignisinformationen sind für alle Versionen von RDS für PostgreSQL relevant.

## Kontext
<a name="wait-event.cpu.context"></a>

Die *Zentrale Verarbeitungseinheit (CPU)* ist die Komponente eines Computers, die Anweisungen ausführt. Beispielsweise führen CPU-Anweisungen arithmetische Vorgänge aus und tauschen Daten im Speicher aus. Wenn eine Abfrage die Anzahl der Anweisungen erhöht, die sie über das Datenbank-Engine ausführt, erhöht sich der Zeitaufwand für die Ausführung der Abfrage. *CPU-Scheduling* gibt einem Prozess CPU-Zeit. Die Planung wird vom Kernel des Betriebssystems orchestriert.

**Topics**
+ [Wie kann man sagen, wann diese Wartezeit stattfindet](#wait-event.cpu.when-it-occurs)
+ [DBLoadCPU-Metrik](#wait-event.cpu.context.dbloadcpu)
+ [Metriken für Os.cPuUtilization](#wait-event.cpu.context.osmetrics)
+ [Wahrscheinliche Ursache für CPU-Planung](#wait-event.cpu.context.scheduling)

### Wie kann man sagen, wann diese Wartezeit stattfindet
<a name="wait-event.cpu.when-it-occurs"></a>

Dieses `CPU`-Warteereignis zeigt an, dass ein Backend-Prozess in der CPU aktiv ist oder auf die CPU wartet. Sie wissen, dass es passiert, wenn eine Abfrage die folgenden Informationen anzeigt:
+ Die Spalte `pg_stat_activity.state` hat den Wert `active`.
+ Die Spalten `wait_event_type` und `wait_event` in `pg_stat_activity` sind beide `null`.

Führen Sie die folgende Abfrage aus, um die Backend-Prozesse anzuzeigen, die auf der CPU verwenden oder auf dieser warten.

```
SELECT * 
FROM   pg_stat_activity
WHERE  state = 'active'
AND    wait_event_type IS NULL
AND    wait_event IS NULL;
```

### DBLoadCPU-Metrik
<a name="wait-event.cpu.context.dbloadcpu"></a>

Die Performance Insights-Metrik für CPU ist `DBLoadCPU`. Der Wert für `DBLoadCPU` kann vom Wert für die CloudWatch Amazon-Metrik abweichen`CPUUtilization`. Die letztere Metrik wird aus der HyperVisor für eine Datenbank-Instance erfasst.

### Metriken für Os.cPuUtilization
<a name="wait-event.cpu.context.osmetrics"></a>

Performance Insights Betriebssystem-Metriken liefern detaillierte Informationen zur CPU-Auslastung. Sie können beispielsweise die folgenden Metriken anzeigen:
+ `os.cpuUtilization.nice.avg`
+ `os.cpuUtilization.total.avg`
+ `os.cpuUtilization.wait.avg`
+ `os.cpuUtilization.idle.avg`

Performance Insights meldet die CPU-Auslastung durch die Datenbank-Engine als `os.cpuUtilization.nice.avg`.

### Wahrscheinliche Ursache für CPU-Planung
<a name="wait-event.cpu.context.scheduling"></a>

 Der Betriebssystem-Kernel übernimmt die Planung für die CPU. Wenn die CPU *aktiv* ist, muss ein Prozess möglicherweise warten, bis er geplant wird. Die CPU ist aktiv, während sie Berechnungen durchführt. Sie ist auch aktiv, wenn sie einen inaktiven Thread hat, der nicht läuft, d. h. ein inaktiver Thread, der auf Speicher wartet, I/O. This type of I/O dominiert die typische Datenbank-Arbeitslast. 

Wenn die folgenden Bedingungen erfüllt sind, werden Prozesse wahrscheinlich warten, bis die folgenden Bedingungen erfüllt sind:
+ Die CloudWatch `CPUUtilization` Metrik liegt bei fast 100 Prozent.
+ Die durchschnittliche Last ist größer als die Zahl von vCPUs, was auf eine hohe Last hindeutet. Sie finden die `loadAverageMinute`-Metrik im Abschnitt Betriebssystemmetriken in Performance Insights.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.cpu.causes"></a>

Wenn das CPU-Warteereignis mehr als normal auftritt und möglicherweise auf ein Leistungsproblem hinweist, sind typische Ursachen die folgenden.

**Topics**
+ [Wahrscheinliche Ursachen für plötzliche Stacheln](#wait-event.cpu.causes.spikes)
+ [Wahrscheinliche Ursachen für langfristige Hochfrequenz](#wait-event.cpu.causes.long-term)
+ [Corner Cases](#wait-event.cpu.causes.corner-cases)

### Wahrscheinliche Ursachen für plötzliche Stacheln
<a name="wait-event.cpu.causes.spikes"></a>

Die wahrscheinlichsten Ursachen für plötzliche Stacheln sind wie folgt:
+ Ihre Anwendung hat zu viele gleichzeitige Verbindungen zur Datenbank geöffnet. Dieses Szenario wird als „Verbindungssturm“ bezeichnet.
+ Ihre Anwendungs-Workload hat sich auf eine der folgenden Weisen geändert:
  + Neue Anfragen
  + Eine Zunahme der Größe Ihres Datensatzes
  + Indexpflege oder -erstellung
  + Neue Funktionen
  + Neue Betreiber
  + Eine Zunahme der parallelen Abfrageausführung
+ Ihre Abfrageausführungspläne haben sich geändert. In einigen Fällen kann eine Änderung zu einem Anstieg der Puffer führen. Beispielsweise verwendet die Abfrage jetzt einen sequentiellen Scan, als sie zuvor einen Index verwendet hat. In diesem Fall benötigen die Abfragen mehr CPU, um dasselbe Ziel zu erreichen.

### Wahrscheinliche Ursachen für langfristige Hochfrequenz
<a name="wait-event.cpu.causes.long-term"></a>

Die wahrscheinlichsten Ursachen für Ereignisse, die über einen langen Zeitraum auftreten:
+ Zu viele Backend-Prozesse laufen gleichzeitig auf der CPU. Diese Prozesse können parallele Arbeiter sein.
+ Abfragen funktionieren suboptimal, da sie eine große Anzahl von Puffern benötigen.

### Corner Cases
<a name="wait-event.cpu.causes.corner-cases"></a>

Wenn sich herausstellt, dass keine der wahrscheinlichen Ursachen tatsächliche Ursachen ist, können folgende Situationen auftreten:
+ Die CPU tauscht Prozesse ein- und aus.
+ Die CPU verwaltet möglicherweise Seitentabelleneinträge, wenn die Funktion *Huge Pages* deaktiviert wurde. Die Speicherverwaltungsfunktion ist standardmäßig für alle DB-Instance-Klassen aktiviert, außer Micro, Small und Medium. Weitere Informationen finden Sie unter [Huge Pages für RDS für PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.HugePages.md). 

## Aktionen
<a name="wait-event.cpu.actions"></a>

Wenn das `CPU`-Wait-Ereignis die Datenbankaktivität dominiert, weist dies nicht unbedingt auf ein Leistungsproblem hin. Reagieren Sie auf dieses Ereignis nur, wenn sich die Leistung verschlechtert.

**Topics**
+ [Untersuchen Sie, ob die Datenbank den CPU-Anstieg verursacht](#wait-event.cpu.actions.db-CPU)
+ [Bestimmen Sie, ob die Anzahl der Verbindungen gestiegen ist](#wait-event.cpu.actions.connections)
+ [Reagieren auf Workload-Änderungen](#wait-event.cpu.actions.workload)

### Untersuchen Sie, ob die Datenbank den CPU-Anstieg verursacht
<a name="wait-event.cpu.actions.db-CPU"></a>

Untersuchen Sie die `os.cpuUtilization.nice.avg`-Metrik in Performance Insights. Wenn dieser Wert weit unter der CPU-Auslastung liegt, tragen Nicht-Datenbankprozesse den Hauptbeitrag zur CPU bei.

### Bestimmen Sie, ob die Anzahl der Verbindungen gestiegen ist
<a name="wait-event.cpu.actions.connections"></a>

Untersuchen Sie die `DatabaseConnections` Metrik in Amazon CloudWatch. Ihre Aktion hängt davon ab, ob die Zahl während des Zeitraums erhöhter CPU-Warteereignisse erhöht oder gesunken ist.

#### Die Verbindungen nahmen zu
<a name="wait-event.cpu.actions.connections.increased"></a>

Wenn die Anzahl der Verbindungen gestiegen ist, vergleichen Sie die Anzahl der Backend-Prozesse, die CPU verbrauchen, mit der Anzahl von v. CPUs Die folgenden Szenarien sind möglich:
+ Die Anzahl der Backend-Prozesse, die CPU verbrauchen, ist geringer als die Anzahl von v. CPUs

  In diesem Fall ist die Anzahl der Verbindungen kein Problem. Möglicherweise versuchen Sie jedoch weiterhin, die CPU-Auslastung zu reduzieren.
+ Die Anzahl der Backend-Prozesse, die CPU verbrauchen, ist größer als die Anzahl von v. CPUs

  Ziehen Sie in diesem Fall die folgenden Optionen in Betracht:
  + Verringern Sie die Anzahl der Backend-Prozesse, die mit Ihrer Datenbank verbunden sind. Implementieren Sie beispielsweise eine Verbindungs-Pooling-Lösung wie RDS Proxy. Weitere Informationen hierzu finden Sie unter [Amazon RDS-Proxy ](rds-proxy.md).
  + Erhöhen Sie Ihre Instanzgröße, um eine höhere Anzahl von v CPUs zu erhalten.
  + Leiten Sie ggf. einige schreibgeschützte Workloads auf Reader-Knoten um.

#### Die Verbindungen haben nicht zugenommen
<a name="wait-event.cpu.actions.connections.decreased"></a>

Untersuchen Sie die `blks_hit`-Metriken in Performance Insights. Suchen Sie nach einer Korrelation zwischen einem Anstieg von `blks_hit` und der CPU-Auslastung. Die folgenden Szenarien sind möglich:
+ CPU-Auslastung und `blks_hit` sind korreliert.

  Suchen Sie in diesem Fall die wichtigsten SQL-Anweisungen, die mit der CPU-Auslastung verknüpft sind, und suchen Sie nach Planänderungen. Sie können eine der folgenden Techniken verwenden:
  + Erklären Sie die Pläne manuell und vergleichen Sie sie mit dem erwarteten Ausführungsplan.
  + Achten Sie auf eine Zunahme der Blocktreffer pro Sekunde und lokalen Blocktreffern pro Sekunde. Wählen Sie im Abschnitt **Top-SQL** des Performance Insights-Dashboards **Einstellungen** aus.
+ CPU-Auslastung und `blks_hit` sind nicht korreliert.

  Stellen Sie in diesem Fall fest, ob einer der folgenden Fälle auftritt:
  + Die Anwendung stellt schnell eine Verbindung zur Datenbank her und trennt sie von dieser. 

    Diagnostizieren Sie dieses Verhalten, indem Sie `log_connections` und `log_disconnections` aktivieren und dann die PostgreSQL-Protokolle analysieren. Ziehen Sie in Erwägung, den `pgbadger`-Protokoll-Analyzer zu verwenden. Weitere Informationen finden Sie unter [https://github.com/darold/pgbadger](https://github.com/darold/pgbadger).
  + Das Betriebssystem ist überlastet.

    In diesem Fall zeigt Performance Insights, dass Backend-Prozesse länger CPU verbrauchen als gewöhnlich. Suchen Sie in den Performance Insights `os.cpuUtilization` Insights-Metriken oder der CloudWatch `CPUUtilization` Metrik nach Belegen. Wenn das Betriebssystem überlastet ist, sehen Sie sich Enhanced Monitoring-Metriken an, um eine weitere Diagnose zu erhalten. Schauen Sie sich insbesondere die Prozessliste und den Prozentsatz der CPU an, die von jedem Prozess verbraucht wird.
  + Top SQL-Anweisungen verbrauchen zu viel CPU.

    Untersuchen Sie Anweisungen, die mit der CPU-Auslastung verknüpft sind, um festzustellen, ob sie weniger CPU verbrauchen können. Führen Sie einen `EXPLAIN`-Befehl aus und konzentrieren Sie sich auf die Planknoten, die die größte Auswirkung haben. Erwägen Sie, einen Visualizer für PostgreSQL-Ausführungspläne zu verwenden. Um dieses Tool auszuprobieren, siehe [http://explain.dalibo.com/](http://explain.dalibo.com/).

### Reagieren auf Workload-Änderungen
<a name="wait-event.cpu.actions.workload"></a>

Wenn sich Ihre Workload geändert hat, suchen Sie nach folgenden Arten von Änderungen:

Neue Anfragen  
Überprüfen Sie, ob die neuen Abfragen erwartet werden. Stellen Sie in diesem Fall sicher, dass ihre Ausführungspläne und die Anzahl der Ausführungen pro Sekunde erwartet werden.

Eine Zunahme der Größe des Datensatzes  
Bestimmen Sie, ob die Partitionierung, falls sie noch nicht implementiert ist, helfen könnte. Diese Strategie könnte die Anzahl der Seiten verringern, die eine Abfrage abrufen muss.

Indexpflege oder -erstellung  
Überprüfen Sie, ob der Zeitplan für die Wartung erwartet wird. Eine bewährte Methode besteht darin, Wartungsarbeiten außerhalb der Hauptverkehrszeiten zu planen.

Neue Funktionen  
Überprüfen Sie, ob diese Funktionen während des Tests erwartungsgemäß funktionieren. Überprüfen Sie insbesondere, ob die Anzahl der Ausführungen pro Sekunde erwartet wird.

Neue Betreiber  
Überprüfen Sie, ob sie während des Tests erwartungsgemäß funktionieren.

Eine Zunahme der laufenden parallelen Abfragen  
Stellen Sie fest, ob eine der folgenden Situationen aufgetreten ist:  
+ Die beteiligten Relationen oder Indizes sind plötzlich so groß geworden, dass sie sich deutlich von `min_parallel_table_scan_size` oder `min_parallel_index_scan_size` unterscheiden.
+ Die letzten Änderungen wurden an `parallel_setup_cost` oder `parallel_tuple_cost` vorgenommen.
+ Die letzten Änderungen wurden an `max_parallel_workers` oder `max_parallel_workers_per_gather` vorgenommen.

# IO: BufFileRead und IO: BufFileWrite
<a name="wait-event.iobuffile"></a>

Die Ereignisse `IO:BufFileRead` und `IO:BufFileWrite` treten auf, wenn RDS für PostgreSQL temporäre Dateien erstellt. Wenn Vorgänge mehr Arbeitsspeicher benötigen, als die derzeit definierten Arbeitsspeicherparameter definieren, schreiben sie temporäre Daten in persistenten Speicher. Dieser Vorgang wird manchmal als Übertragung *auf die Festplatte* bezeichnet. Weitere Informationen zu den temporären Dateien und ihrer Verwendung finden Sie unter [Verwalten temporärer Dateien mit PostgreSQL](PostgreSQL.ManagingTempFiles.md).

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.iobuffile.context.supported)
+ [Kontext](#wait-event.iobuffile.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.iobuffile.causes)
+ [Aktionen](#wait-event.iobuffile.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.iobuffile.context.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt.

## Kontext
<a name="wait-event.iobuffile.context"></a>

`IO:BufFileRead` und `IO:BufFileWrite` beziehen sich auf den Arbeitsspeicherbereich und den Wartungsarbeitsspeicherbereich. Weitere Informationen zu diesen lokalen Speicherbereichen finden Sie unter [Ressourcennutzung](https://www.postgresql.org/docs/current/runtime-config-resource.html) in der PostgreSQL-Dokumentation.

Der Standardwert für `work_mem` ist 4 MB. Wenn eine Sitzung parallel Vorgänge ausführt, verwendet jeder Worker, der die Parallelität bearbeitet, 4 MB Speicher. Stellen Sie `work_mem` daher sorgfältig ein. Wenn Sie den Wert zu stark erhöhen, verbraucht eine Datenbank mit vielen Sitzungen möglicherweise zu viel Speicher. Wenn Sie den Wert zu niedrig festlegen, erstellt RDS für PostgreSQL temporäre Dateien im lokalen Speicher. Die Festplatte I/O für diese temporären Dateien kann die Leistung beeinträchtigen.

Wenn Sie die folgende Ereignisfolge beobachten, generiert Ihre Datenbank möglicherweise temporäre Dateien:

1. Plötzlicher und starker Rückgang der Verfügbarkeit

1. Schnelle Erholung für den freien Speicherplatz

Möglicherweise sehen Sie auch ein „Kettensäge“ -Muster. Dieses Muster kann darauf hinweisen, dass Ihre Datenbank ständig kleine Dateien erstellt.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.iobuffile.causes"></a>

Im Allgemeinen werden diese Warteereignisse durch Vorgänge verursacht, die mehr Speicher verbrauchen, als die Parameter `work_mem` oder `maintenance_work_mem` zuweisen. Um dies zu kompensieren, schreiben die Vorgänge in temporäre Dateien. Häufige Ursachen für die `IO:BufFileRead`- und `IO:BufFileWrite`-Ereignisse sind die folgenden:

**Abfragen, die mehr Speicher benötigen als im Arbeitsspeicherbereich vorhanden**  
Abfragen mit den folgenden Merkmalen verwenden den Arbeitsspeicherbereich:  
+ Hash-Verknüpfungen
+ `ORDER BY`-Klausel
+ `GROUP BY`-Klausel
+ `DISTINCT`
+ Fensterfunktionen
+ `CREATE TABLE AS SELECT`
+ Aktualisierung der materialisierten Ansicht

**Anweisungen, die mehr Speicher benötigen als im Arbeitsspeicherbereich für Wartungsarbeiten vorhanden**  
Die folgenden Anweisungen verwenden den Arbeitsspeicherbereich für Wartungsarbeiten:  
+ `CREATE INDEX`
+ `CLUSTER`

## Aktionen
<a name="wait-event.iobuffile.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen.

**Topics**
+ [Identifizieren Sie das Problem](#wait-event.iobuffile.actions.problem)
+ [Untersuchen Sie Ihre Join-Anfragen](#wait-event.iobuffile.actions.joins)
+ [Überprüfen Sie Ihre ORDER BY- und GROUP BY Anfragen](#wait-event.iobuffile.actions.order-by)
+ [Verwenden Sie den DISTINCT-Vorgang nicht](#wait-event.iobuffile.actions.distinct)
+ [Erwägen Sie, Fensterfunktionen anstelle von GROUP-BY-Funktionen zu verwenden](#wait-event.iobuffile.actions.window)
+ [Untersuchen Sie materialisierte Ansichten und CTAS-Aussagen](#wait-event.iobuffile.actions.mv-refresh)
+ [Verwenden von pg\$1repack beim Neuerstellen von Indizes](#wait-event.iobuffile.actions.pg_repack)
+ [Erhöhen Sie maintenance work\$1mem, wenn Sie Tabellen clustern](#wait-event.iobuffile.actions.cluster)
+ [Passen Sie den Speicher an, um IO: BufFileRead und IO: zu verhindern BufFileWrite](#wait-event.iobuffile.actions.tuning-memory)

### Identifizieren Sie das Problem
<a name="wait-event.iobuffile.actions.problem"></a>

Sie können die Nutzung temporärer Dateien direkt in Performance Insights anzeigen. Weitere Informationen finden Sie unter [Anzeigen der Nutzung temporärer Dateien mit Performance Insights](PostgreSQL.ManagingTempFiles.Example.md). Wenn Performance Insights deaktiviert ist, stellen Sie möglicherweise eine Zunahme der `IO:BufFileRead` `IO:BufFileWrite` Betriebsabläufe fest.

Um die Ursache des Problems zu ermitteln, können Sie den `log_temp_files`-Parameter so festlegen, dass alle Abfragen protokolliert werden, die mehr als den angegebenen Schwellenwert an temporären Dateien in KB generieren. `log_temp_files` ist standardmäßig auf `-1` festgelegt, wodurch diese Protokollierungsfunktion deaktiviert wird. Wenn Sie diesen Parameter auf `0` einstellen, protokolliert RDS für PostgreSQL alle temporären Dateien. Wenn der Wert `1024` ist, protokolliert RDS für PostgreSQL alle Abfragen, die temporäre Dateien erzeugen, die größer als 1 MB sind. Weitere Informationen zu `log_temp_files` finden Sie unter [Fehlerberichte und -protokollierung](https://www.postgresql.org/docs/current/runtime-config-logging.html) in der PostgreSQL-Dokumentation.

### Untersuchen Sie Ihre Join-Anfragen
<a name="wait-event.iobuffile.actions.joins"></a>

Es ist wahrscheinlich, dass Ihre Abfrage Joins verwendet. Die folgende Abfrage verbindet beispielsweise vier Tabellen.

```
SELECT * 
       FROM "order" 
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = order.customer_id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

Eine mögliche Ursache für Spitzen bei der Verwendung temporärer Dateien ist ein Problem in der Abfrage selbst. Beispielsweise filtert eine defekte Klausel die Joins möglicherweise nicht richtig. Betrachten Sie den zweiten inneren Join im folgenden Beispiel.

```
SELECT * 
       FROM "order"
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = customer.id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

Die obige Abfrage verknüpft fälschlicherweise `customer.id` mit `customer.id`, wodurch zwischen jedem Kunden und jeder Bestellung ein kartesisches Produkt generiert wird. Diese Art des versehentlichen Joins generiert große temporäre Dateien. Abhängig von der Größe der Tabellen kann eine kartesische Abfrage sogar Speicher füllen. Wenn die folgenden Bedingungen erfüllt sind, hat Ihre Anwendung möglicherweise kartesische Joins:
+ Sie sehen einen großen, starken Rückgang der Speicherverfügbarkeit, gefolgt von einer schnellen Wiederherstellung.
+ Es werden keine Indizes erstellt.
+ Es werden keine `CREATE TABLE FROM SELECT`-Anweisungen ausgegeben.
+ Es werden keine materialisierten Ansichten aktualisiert.

Um festzustellen, ob die Tabellen mit den richtigen Schlüsseln verbunden werden, überprüfen Sie Ihre Abfrage- und objektrelationalen Mapping-Anweisungen. Denken Sie daran, dass bestimmte Abfragen Ihrer Anwendung nicht ständig aufgerufen werden und einige Abfragen dynamisch generiert werden.

### Überprüfen Sie Ihre ORDER BY- und GROUP BY Anfragen
<a name="wait-event.iobuffile.actions.order-by"></a>

In einigen Fällen kann eine `ORDER BY`-Klausel zu übermäßig vielen temporären Dateien führen. Berücksichtigen Sie die folgenden Hinweise:
+ Schließen Sie Spalten nur dann in eine `ORDER BY`-Klausel ein, wenn sie sortiert werden müssen. Diese Richtlinie ist besonders wichtig für Abfragen, die Tausende von Zeilen zurückgeben und viele Spalten in der `ORDER BY`-Klausel angeben.
+ Ziehen Sie in Betracht, Indizes zu erstellen, um `ORDER BY`-Klauseln zu beschleunigen, wenn sie mit Spalten übereinstimmen, die dieselbe aufsteigende oder absteigende Reihenfolge aufweisen. Partielle Indizes sind vorzuziehen, da sie kleiner sind. Kleinere Indizes werden schneller gelesen und durchquert.
+ Wenn Sie Indizes für Spalten erstellen, die Nullwerte akzeptieren können, überlegen Sie, ob die Nullwerte am Ende oder am Anfang der Indizes gespeichert werden sollen.

  Reduzieren Sie nach Möglichkeit die Anzahl der Zeilen, die sortiert werden müssen, indem Sie die Ergebnismenge filtern. Wenn Sie `WITH`-Klausel-Anweisungen oder Unterabfragen verwenden, denken Sie daran, dass eine innere Abfrage eine Ergebnismenge generiert und an die äußere Abfrage übergibt. Je mehr Zeilen eine Abfrage herausfiltern kann, desto weniger muss die Abfrage erledigen.
+ Wenn Sie nicht die vollständige Ergebnismenge abrufen müssen, verwenden Sie die `LIMIT`-Klausel. Wenn Sie beispielsweise nur die obersten fünf Zeilen benötigen, generiert eine Abfrage mit der `LIMIT`-Klausel keine Ergebnisse. Auf diese Weise benötigt die Abfrage weniger Speicher und temporäre Dateien.

Eine Abfrage, die eine `GROUP BY`-Klausel verwendet, kann auch temporäre Dateien erfordern. `GROUP BY`-Abfragen fassen Werte mithilfe von Funktionen wie den folgenden zusammen:
+ `COUNT`
+ `AVG`
+ `MIN`
+ `MAX`
+ `SUM`
+ `STDDEV`

Befolgen Sie zum Optimieren von `GROUP BY`-Abfragen die Empfehlungen für `ORDER BY`-Abfragen.

### Verwenden Sie den DISTINCT-Vorgang nicht
<a name="wait-event.iobuffile.actions.distinct"></a>

Vermeiden Sie nach Möglichkeit die Verwendung des `DISTINCT`-Vorgangs, um doppelte Zeilen zu entfernen. Je mehr unnötige und doppelte Zeilen Ihre Abfrage zurückgibt, desto teurer wird der `DISTINCT`-Vorgang. Fügen Sie nach Möglichkeit Filter in der `WHERE`-Klausel hinzu, auch wenn Sie dieselben Filter für verschiedene Tabellen verwenden. Das Filtern der Abfrage und der korrekte Beitritt verbessern Ihre Leistung und reduziert den Ressourcennutzung. Es verhindert auch falsche Berichte und Ergebnisse.

Wenn Sie `DISTINCT` für mehrere Zeilen derselben Tabelle verwenden müssen, sollten Sie einen zusammengesetzten Index erstellen. Das Gruppieren mehrerer Spalten in einem Index kann die Zeit zum Auswerten verschiedener Zeilen verbessern. Wenn Sie Version 10 von RDS für PostgreSQL oder höher verwenden, können Sie außerdem mithilfe des `CREATE STATISTICS`-Befehls Statistiken zwischen mehreren Spalten korrelieren.

### Erwägen Sie, Fensterfunktionen anstelle von GROUP-BY-Funktionen zu verwenden
<a name="wait-event.iobuffile.actions.window"></a>

Mit `GROUP BY` ändern Sie die Ergebnismenge und rufen dann das aggregierte Ergebnis ab. Mithilfe von Fensterfunktionen aggregieren Sie Daten, ohne die Ergebnismenge zu ändern. Eine Fensterfunktion verwendet die `OVER`-Klausel, um Berechnungen über die von der Abfrage definierten Mengen durchzuführen und eine Zeile mit einer anderen zu korrelieren. Sie können alle `GROUP BY`-Funktionen in Fensterfunktionen verwenden, aber auch Funktionen wie die folgenden verwenden:
+ `RANK`
+ `ARRAY_AGG`
+ `ROW_NUMBER`
+ `LAG`
+ `LEAD`

Um die Anzahl der temporären Dateien zu minimieren, die von einer Fensterfunktion generiert werden, entfernen Sie Duplikationen für dieselbe Ergebnismenge, wenn Sie zwei verschiedene Aggregationen benötigen. Betrachten Sie folgende Abfrage.

```
SELECT sum(salary) OVER (PARTITION BY dept ORDER BY salary DESC) as sum_salary
     , avg(salary) OVER (PARTITION BY dept ORDER BY salary ASC) as avg_salary
  FROM empsalary;
```

Sie können die Abfrage mit der `WINDOW`-Klausel wie folgt umschreiben.

```
SELECT sum(salary) OVER w as sum_salary
         , avg(salary) OVER w as_avg_salary
    FROM empsalary
  WINDOW w AS (PARTITION BY dept ORDER BY salary DESC);
```

Standardmäßig konsolidiert der Ausführungsplaner von RDS für PostgreSQL ähnliche Knoten, sodass keine Vorgänge dupliziert werden. Durch die Verwendung einer expliziten Deklaration für den Fensterblock können Sie die Abfrage jedoch einfacher pflegen. Sie können die Leistung auch verbessern, indem Sie Doppelarbeit verhindern.

### Untersuchen Sie materialisierte Ansichten und CTAS-Aussagen
<a name="wait-event.iobuffile.actions.mv-refresh"></a>

Wenn eine materialisierte Ansicht aktualisiert wird, wird eine Abfrage ausgeführt. Diese Abfrage kann einen Vorgang wie `GROUP BY`, `ORDER BY` oder `DISTINCT` enthalten. Während einer Aktualisierung können Sie eine große Anzahl temporärer Dateien und die Warteereignisse `IO:BufFileWrite` und `IO:BufFileRead` beobachten. Wenn Sie eine Tabelle basierend auf einer `SELECT`-Anweisung erstellen, führt die `CREATE TABLE`-Anweisung eine Abfrage aus. Um die benötigten temporären Dateien zu reduzieren, optimieren Sie die Abfrage.

### Verwenden von pg\$1repack beim Neuerstellen von Indizes
<a name="wait-event.iobuffile.actions.pg_repack"></a>

Wenn Sie einen Index erstellen, ordnet die Engine die Ergebnismenge an. Wenn Tabellen größer werden und die Werte in der indizierten Spalte vielfältiger werden, benötigen die temporären Dateien mehr Speicherplatz. In den meisten Fällen können Sie die Erstellung temporärer Dateien für große Tabellen nicht verhindern, ohne den Speicherbereich für Wartungsarbeiten zu ändern. Weitere Informationen zu `maintenance_work_mem` finden Sie unter [https://www.postgresql.org/docs/current/runtime-config-resource.html](https://www.postgresql.org/docs/current/runtime-config-resource.html) in der PostgreSQL-Dokumentation. 

Eine mögliche Problemumgehung beim Neuerstellen eines großen Index besteht darin, die pg\$1repack-Erweiterung zu verwenden. Weitere Informationen finden Sie unter [Reorganisieren von Tabellen in PostgreSQL-Datenbanken mit minimalen Sperren](https://reorg.github.io/pg_repack/) in der pg\$1repack-Dokumentation. Informationen zum Einrichten der Erweiterung in Ihrer DB-Instance von RDS for PostgreSQL finden Sie unter [Reduzieren von überflüssigen Daten in Tabellen und Indizes mit der Erweiterung pg\$1repack](Appendix.PostgreSQL.CommonDBATasks.pg_repack.md). 

### Erhöhen Sie maintenance work\$1mem, wenn Sie Tabellen clustern
<a name="wait-event.iobuffile.actions.cluster"></a>

Der Befehl `CLUSTER` gruppiert die durch *table\$1name* angegebene Tabelle basierend auf einem vorhandenen Index, der durch *index\$1name* angegeben wird. RDS für PostgreSQL erstellt die Tabelle physisch so neu, dass sie der Reihenfolge eines bestimmten Indexes entspricht.

Als magnetische Speicherung vorherrschend war, war Clustering üblich, da der Speicherdurchsatz begrenzt war. Jetzt, da SSD-basierter Speicher üblich ist, ist Clustering weniger beliebt. Wenn Sie jedoch Tabellen clustern, können Sie die Leistung je nach Tabellengröße, Index, Abfrage usw. immer noch geringfügig steigern. 

Wenn Sie den Befehl `CLUSTER` ausführen und die Warteereignisse `IO:BufFileWrite` und `IO:BufFileRead` beobachten, stimmen Sie `maintenance_work_mem` ab. Erhöhen Sie die Speichergröße auf einen ziemlich großen Betrag. Ein hoher Wert bedeutet, dass die Engine mehr Speicher für den Clustering-Vorgang verwenden kann.

### Passen Sie den Speicher an, um IO: BufFileRead und IO: zu verhindern BufFileWrite
<a name="wait-event.iobuffile.actions.tuning-memory"></a>

In einigen Situationen müssen Sie den Speicher optimieren. Ihr Ziel ist es, mithilfe der entsprechenden Parameter den Arbeitsspeicher in den folgenden Verbrauchsbereichen wie folgt auszugleichen.
+ Der `work_mem`-Wert 
+ Der Speicher, der nach Abzug des Werts `shared_buffers` verbleibt
+ Die maximale Anzahl geöffneter und verwendeter Verbindungen, die durch `max_connections` begrenzt ist

Weitere Informationen zum Optimieren des Arbeitsspeichers finden Sie unter [Ressourcennutzung](https://www.postgresql.org/docs/current/runtime-config-resource.html) in der PostgreSQL-Dokumentation. 

#### Erhöhen Sie die Größe des Arbeitsspeicherbereichs
<a name="wait-event.iobuffile.actions.tuning-memory.work-mem"></a>

In einigen Situationen besteht Ihre einzige Möglichkeit darin, den von Ihrer Sitzung verwendeten Speicher zu erhöhen. Wenn Ihre Abfragen richtig geschrieben sind und die richtigen Schlüssel für Joins verwenden, sollten Sie den `work_mem`-Wert erhöhen. 

Um herauszufinden, wie viele temporäre Dateien eine Abfrage generiert, setzen Sie `log_temp_files` auf `0`. Wenn Sie den `work_mem`-Wert auf den in den Protokollen angegebenen Höchstwert erhöhen, verhindern Sie, dass die Abfrage temporäre Dateien generiert. `work_mem` legt jedoch das Maximum pro Planknoten für jede Verbindung oder jeden parallelen Worker fest. Wenn die Datenbank über 5.000 Verbindungen verfügt und jede 256 MiB-Speicher verwendet, benötigt die Engine 1,2 TiB RAM. Daher kann es sein, dass Ihrer Instance der Speicher knapp wird.

#### Reservieren Sie ausreichend Speicher für den freigegebenen Pufferpool
<a name="wait-event.iobuffile.actions.tuning-memory.shared-pool"></a>

Ihre Datenbank verwendet Speicherbereiche wie den freigegebenen Pufferpool, nicht nur den Arbeitsspeicherbereich. Berücksichtigen Sie die Anforderungen dieser zusätzlichen Speicherbereiche, bevor Sie `work_mem` erhöhen.

Angenommen, Ihre Instance-Klasse von RDS für PostgreSQL ist db.r5.2xlarge. Diese Klasse hat 64 GiB Speicher. Standardmäßig sind 25 Prozent des Arbeitsspeichers für den freigegebenen Pufferpool reserviert. Nachdem Sie den dem Shared Memory-Bereich zugewiesenen Betrag abgezogen haben, bleiben 16.384 MB übrig. Weisen Sie den verbleibenden Speicher nicht ausschließlich dem Arbeitsspeicherbereich zu, da das Betriebssystem und die Engine ebenfalls Speicher benötigen.

Der Speicher, den Sie `work_mem` zuordnen können, hängt von der Instance-Klasse ab. Wenn Sie eine größere Instance-Klasse verwenden, ist mehr Speicher verfügbar. Im vorhergehenden Beispiel können Sie jedoch nicht mehr als 16 GiB verwenden. Andernfalls ist Ihre Instance nicht verfügbar, wenn ihr der Speicher ausgeht. Um die Instance aus dem nicht verfügbaren Status wiederherzustellen, werden die Automatisierungsdienste von RDS für PostgreSQL automatisch neu gestartet.

#### Verwalten der Anzahl der Verbindungen
<a name="wait-event.iobuffile.actions.tuning-memory.connections"></a>

Angenommen, Ihre Datenbank-Instance hat 5.000 gleichzeitige Verbindungen. Jede Verbindung verwendet mindestens 4 MB `work_mem`. Der hohe Speicherverbrauch der Verbindungen dürfte die Leistung beeinträchtigen. Als Reaktion darauf haben Sie die folgenden Optionen:
+ Aktualisieren Sie auf eine größere Instance-Klasse.
+ Verringern Sie die Anzahl gleichzeitiger Datenbankverbindungen mit einem Verbindungsproxy oder Pooler.

Berücksichtigen Sie bei Proxys Amazon RDS Proxy, PGBouncer oder einen auf Ihrer Anwendung basierenden Verbindungspooler. Diese Lösung lindert die CPU-Last. Es reduziert auch das Risiko, wenn alle Verbindungen den Arbeitsspeicherbereich benötigen. Wenn weniger Datenbankverbindungen vorhanden sind, können Sie den Wert von `work_mem` erhöhen. Auf diese Weise reduzieren Sie das Auftreten der `IO:BufFileRead`- und `IO:BufFileWrite`-Warteereignisse. Auch die Abfragen, die auf den Arbeitsspeicherbereich warten, beschleunigen sich erheblich.

# IO: DataFileRead
<a name="wait-event.iodatafileread"></a>

Das `IO:DataFileRead`-Ereignis tritt auf, wenn eine Verbindung darauf wartet, dass ein Backend-Prozess eine erforderliche Seite aus dem Speicher liest, da die Seite nicht im gemeinsam genutzten Speicher verfügbar ist.

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.iodatafileread.context.supported)
+ [Kontext](#wait-event.iodatafileread.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.iodatafileread.causes)
+ [Aktionen](#wait-event.iodatafileread.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.iodatafileread.context.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt.

## Kontext
<a name="wait-event.iodatafileread.context"></a>

Alle Abfragen und Datenmanipulationsvorgänge (DML) greifen auf Seiten im Pufferpool zu. Zu den Anweisungen, die Lesevorgänge auslösen können, gehören `SELECT`, `UPDATE` und `DELETE`. Ein `UPDATE` kann beispielsweise Seiten aus Tabellen oder Indizes lesen. Wenn sich die angeforderte oder aktualisierte Seite nicht im gemeinsam genutzten Pufferpool befindet, kann dieser Lesevorgang zum `IO:DataFileRead`-Ereignis führen.

Da der gemeinsame Pufferpool endlich ist, kann er sich füllen. In diesem Fall zwingen Anfragen nach Seiten, die sich nicht im Speicher befinden, die Datenbank dazu, Blöcke von der Festplatte zu lesen. Wenn das `IO:DataFileRead`-Ereignis häufig auftritt, ist Ihr gemeinsam genutzter Pufferpool möglicherweise zu klein für Ihre Workload. Dieses Problem ist bei `SELECT`-Abfragen akut, die eine große Anzahl von Zeilen lesen, die nicht in den Pufferpool passen. Weitere Informationen zum Pufferpool finden Sie unter [Ressourcenbnutzung](https://www.postgresql.org/docs/current/runtime-config-resource.html) in der PostgreSQL-Dokumentation.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.iodatafileread.causes"></a>

Häufige Ursachen für das Ereignis `IO:DataFileRead` sind die folgenden:

**Verbindungsspitzen**  
Möglicherweise stellen Sie fest, dass mehrere Verbindungen dieselbe Anzahl von IO: DataFileRead Wait-Ereignissen generieren. In diesem Fall kann eine Spitze (plötzlicher und starker Anstieg) bei `IO:DataFileRead`-Ereignissen auftreten. 

**SELECT- und DML-Anweisungen, die sequentielle Scans durchführen**  
Ihre Anwendung führt möglicherweise einen neuen Vorgang aus. Oder ein vorhandener Vorgang könnte sich aufgrund eines neuen Ausführungsplans ändern. Suchen Sie in solchen Fällen nach Tabellen (insbesondere großen Tabellen), die einen größeren `seq_scan`-Wert haben. Finden Sie sie, indem Sie `pg_stat_user_tables` abfragen. Verwenden Sie die Erweiterung `pg_stat_statements`, um Abfragen zu verfolgen, die mehr Lesevorgänge generieren.

**CTAS und CREATE INDEX für große Datensätze**  
Ein *CTAS* ist eine `CREATE TABLE AS SELECT`-Anweisung. Wenn Sie ein CTAS mit einem großen Datensatz als Quelle ausführen oder einen Index für eine große Tabelle erstellen, kann das `IO:DataFileRead`-Ereignis auftreten. Wenn Sie einen Index erstellen, muss die Datenbank möglicherweise das gesamte Objekt mithilfe eines sequentiellen Scans lesen. Ein CTAS generiert `IO:DataFile`-Reads, wenn Seiten nicht im Speicher sind.

**Mehrere Vakuumarbeiter laufen gleichzeitig**  
Vakuumarbeiter können manuell oder automatisch ausgelöst werden. Wir empfehlen, eine aggressive Vakuumstrategie zu verabschieden. Wenn eine Tabelle jedoch viele aktualisierte oder gelöschte Zeilen enthält, erhöhen sich die `IO:DataFileRead`-Wartezeiten. Nachdem der Raum zurückgewonnen wurde, nimmt die für `IO:DataFileRead` aufgewendete Vakuumzeit ab.

**Aufnahme großer Datenmengen**  
Wenn Ihre Anwendung große Datenmengen aufnimmt, können `ANALYZE`-Vorgänge häufiger auftreten. Der `ANALYZE`-Prozess kann durch einen Autovacuum Launcher ausgelöst oder manuell aufgerufen werden.  
Der `ANALYZE`-Vorgang liest eine Teilmenge der Tabelle. Die Anzahl der zu scannenden Seiten wird berechnet, indem 30 mit dem `default_statistics_target`-Wert multipliziert wird. Weitere Informationen finden Sie in der [PostgreSQL-Dokumentation](https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET). Der Parameter `default_statistics_target` akzeptiert Werte zwischen 1 und 10.000, wobei der Standardwert 100 ist.

**Hungertod**  
Wenn Netzwerkbandbreite oder CPU der Instance verbraucht werden, kann das `IO:DataFileRead`-Ereignis häufiger auftreten.

## Aktionen
<a name="wait-event.iodatafileread.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen.

**Topics**
+ [Überprüfen Sie Prädikatfilter auf Abfragen, die Wartezeiten generieren](#wait-event.iodatafileread.actions.filters)
+ [Minimieren Sie die Auswirkungen von Wartungsvorgängen](#wait-event.iodatafileread.actions.maintenance)
+ [Reagieren Sie auf eine hohe Anzahl von Verbindungen](#wait-event.iodatafileread.actions.connections)

### Überprüfen Sie Prädikatfilter auf Abfragen, die Wartezeiten generieren
<a name="wait-event.iodatafileread.actions.filters"></a>

Angenommen, Sie identifizieren bestimmte Abfragen, die `IO:DataFileRead`-Warteereignisse generieren. Sie können sie mit den folgenden Techniken identifizieren:
+ Performance Insights
+ Katalogansichten wie die der Erweiterung `pg_stat_statements`
+ Die Katalogansicht `pg_stat_all_tables`, wenn sie periodisch eine erhöhte Anzahl von physischen Lesevorgängen anzeigt
+ Die `pg_statio_all_tables`-Ansicht, wenn sie zeigt, dass `_read`-Zähler steigen

Wir empfehlen Ihnen, zu bestimmen, welche Filter im Prädikat (`WHERE`-Klausel) dieser Abfragen verwendet werden. Befolgen Sie diese Richtlinien:
+ Führen Sie den Befehl `EXPLAIN` aus. Geben Sie in der Ausgabe an, welche Arten von Scans verwendet werden. Ein sequentieller Scan weist nicht zwangsläufig ein Problem an. Abfragen, die sequenzielle Scans verwenden, erzeugen im Vergleich zu Abfragen, die Filter verwenden, natürlich mehr `IO:DataFileRead`-Ereignisse.

  Finden Sie heraus, ob die in der `WHERE`-Klausel aufgeführte Spalte indiziert ist. Wenn nicht, erwägen Sie, einen Index für diese Spalte zu erstellen. Dieser Ansatz vermeidet die sequentiellen Scans und reduziert die `IO:DataFileRead`-Ereignisse. Wenn eine Abfrage restriktive Filter enthält und immer noch sequenzielle Scans erzeugt, bewerten Sie, ob die richtigen Indizes verwendet werden.
+ Finden Sie heraus, ob die Abfrage auf eine sehr große Tabelle zugreift. In einigen Fällen kann das Partitionieren einer Tabelle die Leistung verbessern, sodass die Abfrage nur notwendige Partitionen lesen kann.
+ Untersuchen Sie die Kardinalität (Gesamtzahl der Zeilen) Ihrer Join-Vorgänge. Beachten Sie, wie restriktiv die Werte sind, die Sie den Filtern für Ihre `WHERE`-Klausel übergeben. Wenn möglich, stimmen Sie Ihre Abfrage ein, um die Anzahl der Zeilen zu reduzieren, die in jedem Schritt des Plans übergeben werden.

### Minimieren Sie die Auswirkungen von Wartungsvorgängen
<a name="wait-event.iodatafileread.actions.maintenance"></a>

Wartungsvorgänge wie `VACUUM` und `ANALYZE` sind wichtig. Wir empfehlen, sie nicht zu deaktivieren, da Sie `IO:DataFileRead`-Warteereignisse im Zusammenhang mit diesen Wartungsvorgängen finden. Die folgenden Ansätze können die Auswirkungen dieser Vorgänge minimieren:
+ Führen Sie Wartungsvorgänge während außerhalb der Hauptverkehrszeiten manuell aus. Diese Technik verhindert, dass die Datenbank den Schwellenwert für automatische Vorgänge erreicht.
+ Erwägen Sie bei sehr großen Tabellen, die Tabelle zu partitionieren. Diese Technik reduziert den Overhead von Wartungsvorgängen. Die Datenbank greift nur auf die Partitionen zu, die gewartet werden müssen.
+ Wenn Sie große Datenmengen aufnehmen, sollten Sie die Funktion zur automatischen Analyse deaktivieren.

Die Auto-Vakuum-Funktion wird automatisch für eine Tabelle ausgelöst, wenn die folgende Formel zutrifft.

```
pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor) + autovacuum_vacuum_threshold
```

Die Ansicht `pg_stat_user_tables` und der Katalog `pg_class` haben mehrere Zeilen. Eine Zeile kann einer Zeile in Ihrer Tabelle entsprechen. Diese Formel geht davon aus, dass die `reltuples` für eine bestimmte Tabelle stehen. Die Parameter `autovacuum_vacuum_scale_factor` (standardmäßig 0.20) und `autovacuum_vacuum_threshold` (standardmäßig 50 Tupel) werden normalerweise global für die gesamte Instance gesetzt. Sie können jedoch verschiedene Werte für eine bestimmte Tabelle festlegen.

**Topics**
+ [Suchen nach Tabellen, die unnötigerweise Speicherplatz belegen](#wait-event.iodatafileread.actions.maintenance.tables)
+ [Suchen nach Indizes, die unnötigerweise Speicherplatz belegen](#wait-event.iodatafileread.actions.maintenance.indexes)
+ [Finden Sie Tabellen, die für die automatische Vakuumierung berechtigt sind](#wait-event.iodatafileread.actions.maintenance.autovacuumed)

#### Suchen nach Tabellen, die unnötigerweise Speicherplatz belegen
<a name="wait-event.iodatafileread.actions.maintenance.tables"></a>

Um Tabellen zu finden, die unnötig Speicherplatz beanspruchen, können Sie Funktionen der `pgstattuple`-Erweiterung von PostgreSQL verwenden. Diese Erweiterung (Modul) ist standardmäßig auf allen DB-Instances von RDS für PostgreSQL verfügbar und kann mit dem folgenden Befehl auf der Instance instanziiert werden.

```
CREATE EXTENSION pgstattuple;
```

Weitere Informationen zu dieser Erweiterung finden Sie unter [pgstattuple](https://www.postgresql.org/docs/current/pgstattuple.html) in der PostgreSQL-Dokumentation.

Sie können in Ihrer Anwendung nach einer Überlastung von Tabellen und Indizes suchen. Weitere Informationen finden Sie unter [Diagnostizieren einer Überlastung von Tabellen und Indizes](https://docs.aws.amazon.com//AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html).

#### Suchen nach Indizes, die unnötigerweise Speicherplatz belegen
<a name="wait-event.iodatafileread.actions.maintenance.indexes"></a>

Um aufgeblähte Indizes zu finden und abzuschätzen, wie viel Speicherplatz in den Tabellen, für die Sie Leserechte haben, unnötig beansprucht wird, können Sie die folgende Abfrage ausführen.

```
-- WARNING: rows with is_na = 't' are known to have bad statistics ("name" type is not supported).
-- This query is compatible with PostgreSQL 8.2 and later.

SELECT current_database(), nspname AS schemaname, tblname, idxname, bs*(relpages)::bigint AS real_size,
  bs*(relpages-est_pages)::bigint AS extra_size,
  100 * (relpages-est_pages)::float / relpages AS extra_ratio,
  fillfactor, bs*(relpages-est_pages_ff) AS bloat_size,
  100 * (relpages-est_pages_ff)::float / relpages AS bloat_ratio,
  is_na
  -- , 100-(sub.pst).avg_leaf_density, est_pages, index_tuple_hdr_bm, 
  -- maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, sub.reltuples, sub.relpages 
  -- (DEBUG INFO)
FROM (
  SELECT coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)/(4+nulldatahdrwidth)::float)), 0 
       -- ItemIdData size + computed avg size of a tuple (nulldatahdrwidth)
    ) AS est_pages,
    coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)*fillfactor/(100*(4+nulldatahdrwidth)::float))), 0
    ) AS est_pages_ff,
    bs, nspname, table_oid, tblname, idxname, relpages, fillfactor, is_na
    -- , stattuple.pgstatindex(quote_ident(nspname)||'.'||quote_ident(idxname)) AS pst, 
    -- index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, reltuples 
    -- (DEBUG INFO)
  FROM (
    SELECT maxalign, bs, nspname, tblname, idxname, reltuples, relpages, relam, table_oid, fillfactor,
      ( index_tuple_hdr_bm +
          maxalign - CASE -- Add padding to the index tuple header to align on MAXALIGN
            WHEN index_tuple_hdr_bm%maxalign = 0 THEN maxalign
            ELSE index_tuple_hdr_bm%maxalign
          END
        + nulldatawidth + maxalign - CASE -- Add padding to the data to align on MAXALIGN
            WHEN nulldatawidth = 0 THEN 0
            WHEN nulldatawidth::integer%maxalign = 0 THEN maxalign
            ELSE nulldatawidth::integer%maxalign
          END
      )::numeric AS nulldatahdrwidth, pagehdr, pageopqdata, is_na
      -- , index_tuple_hdr_bm, nulldatawidth -- (DEBUG INFO)
    FROM (
      SELECT
        i.nspname, i.tblname, i.idxname, i.reltuples, i.relpages, i.relam, a.attrelid AS table_oid,
        current_setting('block_size')::numeric AS bs, fillfactor,
        CASE -- MAXALIGN: 4 on 32bits, 8 on 64bits (and mingw32 ?)
          WHEN version() ~ 'mingw32' OR version() ~ '64-bit|x86_64|ppc64|ia64|amd64' THEN 8
          ELSE 4
        END AS maxalign,
        /* per page header, fixed size: 20 for 7.X, 24 for others */
        24 AS pagehdr,
        /* per page btree opaque data */
        16 AS pageopqdata,
        /* per tuple header: add IndexAttributeBitMapData if some cols are null-able */
        CASE WHEN max(coalesce(s.null_frac,0)) = 0
          THEN 2 -- IndexTupleData size
          ELSE 2 + (( 32 + 8 - 1 ) / 8) 
          -- IndexTupleData size + IndexAttributeBitMapData size ( max num filed per index + 8 - 1 /8)
        END AS index_tuple_hdr_bm,
        /* data len: we remove null values save space using it fractionnal part from stats */
        sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 1024)) AS nulldatawidth,
        max( CASE WHEN a.atttypid = 'pg_catalog.name'::regtype THEN 1 ELSE 0 END ) > 0 AS is_na
      FROM pg_attribute AS a
        JOIN (
          SELECT nspname, tbl.relname AS tblname, idx.relname AS idxname, 
            idx.reltuples, idx.relpages, idx.relam,
            indrelid, indexrelid, indkey::smallint[] AS attnum,
            coalesce(substring(
              array_to_string(idx.reloptions, ' ')
               from 'fillfactor=([0-9]+)')::smallint, 90) AS fillfactor
          FROM pg_index
            JOIN pg_class idx ON idx.oid=pg_index.indexrelid
            JOIN pg_class tbl ON tbl.oid=pg_index.indrelid
            JOIN pg_namespace ON pg_namespace.oid = idx.relnamespace
          WHERE pg_index.indisvalid AND tbl.relkind = 'r' AND idx.relpages > 0
        ) AS i ON a.attrelid = i.indexrelid
        JOIN pg_stats AS s ON s.schemaname = i.nspname
          AND ((s.tablename = i.tblname AND s.attname = pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE)) 
          -- stats from tbl
          OR  (s.tablename = i.idxname AND s.attname = a.attname))
          -- stats from functional cols
        JOIN pg_type AS t ON a.atttypid = t.oid
      WHERE a.attnum > 0
      GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9
    ) AS s1
  ) AS s2
    JOIN pg_am am ON s2.relam = am.oid WHERE am.amname = 'btree'
) AS sub
-- WHERE NOT is_na
ORDER BY 2,3,4;
```

#### Finden Sie Tabellen, die für die automatische Vakuumierung berechtigt sind
<a name="wait-event.iodatafileread.actions.maintenance.autovacuumed"></a>

Führen Sie die folgende Abfrage aus, um Tabellen zu finden, die für die automatische Vakuumierung berechtigt sind.

```
--This query shows tables that need vacuuming and are eligible candidates.
--The following query lists all tables that are due to be processed by autovacuum. 
-- During normal operation, this query should return very little.
WITH  vbt AS (SELECT setting AS autovacuum_vacuum_threshold 
              FROM pg_settings WHERE name = 'autovacuum_vacuum_threshold')
    , vsf AS (SELECT setting AS autovacuum_vacuum_scale_factor 
              FROM pg_settings WHERE name = 'autovacuum_vacuum_scale_factor')
    , fma AS (SELECT setting AS autovacuum_freeze_max_age 
              FROM pg_settings WHERE name = 'autovacuum_freeze_max_age')
    , sto AS (SELECT opt_oid, split_part(setting, '=', 1) as param, 
                split_part(setting, '=', 2) as value 
              FROM (SELECT oid opt_oid, unnest(reloptions) setting FROM pg_class) opt)
SELECT
    '"'||ns.nspname||'"."'||c.relname||'"' as relation
    , pg_size_pretty(pg_table_size(c.oid)) as table_size
    , age(relfrozenxid) as xid_age
    , coalesce(cfma.value::float, autovacuum_freeze_max_age::float) autovacuum_freeze_max_age
    , (coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
         coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples) 
         as autovacuum_vacuum_tuples
    , n_dead_tup as dead_tuples
FROM pg_class c 
JOIN pg_namespace ns ON ns.oid = c.relnamespace
JOIN pg_stat_all_tables stat ON stat.relid = c.oid
JOIN vbt on (1=1) 
JOIN vsf ON (1=1) 
JOIN fma on (1=1)
LEFT JOIN sto cvbt ON cvbt.param = 'autovacuum_vacuum_threshold' AND c.oid = cvbt.opt_oid
LEFT JOIN sto cvsf ON cvsf.param = 'autovacuum_vacuum_scale_factor' AND c.oid = cvsf.opt_oid
LEFT JOIN sto cfma ON cfma.param = 'autovacuum_freeze_max_age' AND c.oid = cfma.opt_oid
WHERE c.relkind = 'r' 
AND nspname <> 'pg_catalog'
AND (
    age(relfrozenxid) >= coalesce(cfma.value::float, autovacuum_freeze_max_age::float)
    or
    coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
      coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples <= n_dead_tup
    -- or 1 = 1
)
ORDER BY age(relfrozenxid) DESC;
```

### Reagieren Sie auf eine hohe Anzahl von Verbindungen
<a name="wait-event.iodatafileread.actions.connections"></a>

Wenn Sie Amazon überwachen CloudWatch, stellen Sie möglicherweise fest, dass die `DatabaseConnections` Metrik ansteigt. Dieser Anstieg deutet auf eine erhöhte Anzahl von Verbindungen zu Ihrer Datenbank hin. Wir empfehlen folgende Vorgehensweise:
+ Beschränken Sie die Anzahl der Verbindungen, die die Anwendung mit jeder Instance öffnen kann. Wenn Ihre Anwendung über eine eingebettete Verbindungspool-Funktion verfügt, legen Sie eine angemessene Anzahl von Verbindungen fest. Basieren Sie die Zahl darauf, was das v CPUs in Ihrer Instance effektiv parallelisieren kann.

  Wenn Ihre Anwendung keine Verbindungspool-Funktion verwendet, sollten Sie den Amazon RDS Proxy oder eine Alternative in Betracht ziehen. Mit diesem Ansatz können Ihre Anwendung mehrere Verbindungen mit dem Load Balancer öffnen. Der Balancer kann dann eine begrenzte Anzahl von Verbindungen mit der Datenbank öffnen. Da weniger Verbindungen parallel laufen, führt Ihre DB-Instance weniger Kontextwechsel im Kernel durch. Abfragen sollten schneller voranschreiten und zu weniger Warteereignissen führen. Weitere Informationen finden Sie unter [Amazon RDS-Proxy ](rds-proxy.md).
+ Nutzen Sie nach Möglichkeit die Lesereplikate für RDS für PostgreSQL. Wenn Ihre Anwendung eine schreibgeschützten Operation ausführt, senden Sie diese Anfragen an das bzw. die Lesereplikate. Diese Technik reduziert den I/O Druck auf den primären Knoten (Writer).
+ Ziehen Sie, Ihre DB-Instance zu skalieren. Eine Instance-Klasse mit höherer Kapazität bietet mehr Speicher, was RDS für PostgreSQL einen größeren freigegebenen Pufferpool zum Speichern von Seiten gibt. Die größere Größe gibt der DB-Instance auch mehr V CPUs für die Verarbeitung von Verbindungen. Mehr v CPUs sind besonders hilfreich, wenn es sich bei den Vorgängen, die `IO:DataFileRead` Warte-Ereignisse erzeugen, um Schreibvorgänge handelt.

# IO:WALWrite
<a name="wait-event.iowalwrite"></a>



**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.iowalwrite.context.supported)
+ [Kontext](#wait-event.iowalwrite.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.iowalwrite.causes)
+ [Aktionen](#wait-event.iowalwrite.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.iowalwrite.context.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL 10 und höher unterstützt.

## Kontext
<a name="wait-event.iowalwrite.context"></a>

Die Aktivität in der Datenbank, die Write-Ahead-Protokolldaten generiert, füllt zuerst die WAL-Puffer und schreibt dann asynchron auf die Festplatte. Das Warteereignis `IO:WALWrite` wird generiert, wenn die SQL-Sitzung darauf wartet, dass die WAL-Daten das Schreiben auf die Festplatte abgeschlossen haben, damit sie den COMMIT-Aufruf der Transaktion freigeben kann. 

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.iowalwrite.causes"></a>

Wenn dieses Warteereignis häufig auftritt, sollten Sie Ihre Workload und die Art der Aktualisierungen, die Ihre Workload durchführt, sowie deren Häufigkeit überprüfen. Suchen Sie insbesondere nach folgender Art von Aktivität.

**Starke DML-Aktivität**  
Das Ändern von Daten in Datenbanktabellen erfolgt nicht sofort. Beim Einfügen in eine Tabelle muss möglicherweise auf eine Einfügung oder Aktualisierung derselben Tabelle von einem anderen Client gewartet werden. Die Data Manipulation Language (DML)-Anweisungen zum Ändern von Datenwerten (INSERT, UPDATE, DELETE, COMMIT, ROLLBACK TRANSACTION) können Konflikte verursachen, die dazu führen, dass die Write-Ahead-Protokolldatei darauf wartet, dass die Puffer geleert werden. Diese Situation wird in den folgenden Metriken für Erkenntnisse zur Amazon-RDS-Leistung erfasst, die auf eine starke DML-Aktivität hinweisen.  
+  `tup_inserted`
+ `tup_updated`
+ `tup_deleted`
+ `xact_rollback`
+ `xact_commit`
Weitere Informationen zu diesen Metriken finden Sie unter [Performance-Insights-Zähler für Amazon RDS für PostgreSQL](USER_PerfInsights_Counters.md#USER_PerfInsights_Counters.PostgreSQL).

**Häufige Checkpoint-Aktivitäten**  
Häufige Checkpoints tragen zu einer höheren Anzahl von WAL-Dateien bei. In RDS für PostgreSQL sind Schreibvorgänge für vollständige Seiten immer aktiviert. Schreibvorgänge für vollständige Seiten schützen vor Datenverlust. Wenn Checkpoints jedoch zu häufig auftreten, kann es zu Leistungseinbußen des Systems kommen. Dies gilt insbesondere für Systeme mit starker DML-Aktivität. In einigen Fällen finden Sie möglicherweise Fehlermeldungen in Ihrem `postgresql.log`, dass „Checkpoints zu häufig vorkommen“.   
Wir empfehlen, bei der Optimierung von Checkpoints die Leistung sorgfältig gegen den erwarteten Zeitbedarf für die Wiederherstellung im Falle eines abnormalen Shutdowns abzuwägen. 

## Aktionen
<a name="wait-event.iowalwrite.actions"></a>

Wir empfehlen die folgenden Aktionen, um die Vorkommen dieses Warteereignis zu reduzieren.

**Topics**
+ [Reduzieren Sie die Anzahl der Commits](#wait-event.iowalwrite.actions.problem)
+ [Überwachen Ihrer Checkpoints](#wait-event.iowalwrite.actions.monitor)
+ [Hochskalieren von I/O](#wait-event.iowalwrite.actions.scale-io)
+ [Dediziertes Protokoll-Volume (DLV)](#wait-event.iowalwrite.actions.dlv)

### Reduzieren Sie die Anzahl der Commits
<a name="wait-event.iowalwrite.actions.problem"></a>

Um die Anzahl der Commits zu reduzieren, können Sie Anweisungen in Transaktionsblöcke kombinieren. Verwenden Sie Erkenntnisse zur Amazon-RDS-Leistung, um die Art der ausgeführten Abfragen zu untersuchen. Sie können große Wartungsvorgänge auch auf Zeiten außerhalb der Spitzenzeiten verlegen. Erstellen Sie beispielsweise Indizes oder verwenden Sie `pg_repack`-Operationen außerhalb der Produktionszeiten.

### Überwachen Ihrer Checkpoints
<a name="wait-event.iowalwrite.actions.monitor"></a>

Es gibt zwei Parameter, die Sie überwachen können, um zu sehen, wie oft Ihre DB-Instance von RDS für PostgreSQL wegen Checkpoints in die WAL-Datei schreibt. 
+ `log_checkpoints` – Dieser Parameter ist standardmäßig aktiviert. Dadurch wird für jeden Checkpoint eine Nachricht an das PostgreSQL-Protokoll gesendet. Diese Protokollnachrichten enthalten die Anzahl der geschriebenen Puffer, die für das Schreiben aufgewendete Zeit und die Anzahl der für den angegebenen Checkpoint hinzugefügten, entfernten oder recycelten WAL-Dateien. 

  Weitere Informationen zu diesem Parameter finden Sie unter [Fehlerberichte und -protokollierung](https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-CHECKPOINTS) in der PostgreSQL-Dokumentation. 
+ `checkpoint_warning` – Dieser Parameter legt einen Schwellenwert (in Sekunden) für die Checkpoint-Häufigkeit fest, bei dessen Überschreitung eine Warnung generiert wird. Standardmäßig ist dieser Parameter in RDS für PostgreSQL nicht festgelegt. Sie können den Wert dieses Parameters festlegen, um eine Warnung zu erhalten, wenn die Datenbankänderungen in Ihrer RDS-für-PostgreSQL-DB-Instance mit einer Geschwindigkeit geschrieben werden, für die die WAL-Dateien nicht dimensioniert sind. Angenommen, Sie haben diesen Parameter auf 30 festgelegt. Wenn Ihre RDS-für-PostgreSQL-Instance Änderungen öfter als alle 30 Sekunden schreiben muss, wird die Warnung bezüglich zu häufig vorkommender Checkpoints an das PostgreSQL-Protokoll gesendet. Dies kann darauf hindeuten, dass Ihr `max_wal_size`-Wert erhöht werden sollte. 

  Weitere Informationen finden Sie unter [Write-Ahead-Protokoll](https://www.postgresql.org/docs/current/runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS) in der PostgreSQL-Dokumentation. 

### Hochskalieren von I/O
<a name="wait-event.iowalwrite.actions.scale-io"></a>

Diese Art von Input/Output-Warteereignis (I/O) kann behoben werden, indem die Eingabe-/Ausgabevorgänge pro Sekunde (IOPs) skaliert werden, um schnellere I/O bereitzustellen. Die Skalierung von I/O ist der Skalierung der CPU vorzuziehen, da die Skalierung der CPU zu noch mehr I/O-Konflikten führen kann. Der Grund hierfür ist, dass die erhöhte CPU mehr Arbeit bewältigen kann und somit den I/O-Engpass noch verschlimmert. Im Allgemeinen empfehlen wir, die Workload zu optimieren, bevor Sie Skalierungsvorgänge durchführen.

### Dediziertes Protokoll-Volume (DLV)
<a name="wait-event.iowalwrite.actions.dlv"></a>

Sie können ein dediziertes Protokoll-Volume (DLV) für eine DB-Instance, die Provisioned IOPS (PIOPS)-Speicher verwendet, mithilfe der Amazon-RDS-Konsole, AWS CLI oder der Amazon-RDS-API verwenden. Ein DLV verschiebt PostgreSQL-Datenbank-Transaktionsprotokolle auf ein Speicher-Volume, das von dem Volume getrennt ist, das die Datenbanktabellen enthält. Weitere Informationen finden Sie unter [Dediziertes Protokoll-Volume (DLV)](CHAP_Storage.md#CHAP_Storage.dlv).

# IPC:parallel-Warteereignisse
<a name="rpg-ipc-parallel"></a>

Die folgenden `IPC:parallel wait events` weisen darauf hin, dass eine Sitzung auf die Interprozesskommunikation in Bezug auf parallele Abfrageausführungen wartet.
+ `IPC:BgWorkerStartup` - Ein Prozess wartet darauf, dass ein paralleler Worker-Prozess seine Startsequenz abgeschlossen hat. Dies geschieht, wenn Worker für eine parallele Abfrageausführung initialisiert werden.
+ `IPC:BgWorkerShutdown` - Ein Prozess wartet darauf, dass ein paralleler Worker-Prozess seine Shutdown-Sequenz abgeschlossen hat. Dies geschieht während der Bereinigungsphase der parallelen Abfrageausführung.
+ `IPC:ExecuteGather` - Ein Prozess wartet darauf, während der Abfrageausführung Daten von parallelen Worker-Prozessen zu empfangen. Dies ist der Fall, wenn der Leader-Prozess Ergebnisse von seinen Workern erfassen muss.
+ `IPC:ParallelFinish` - Ein Prozess wartet darauf, dass parallele Worker ihre Ausführung beenden und ihre Endergebnisse melden. Dies geschieht während der Abschlussphase der parallelen Abfrageausführung.

**Topics**
+ [Unterstützte Engine-Versionen](#rpg-ipc-parallel-context-supported)
+ [Kontext](#rpg-ipc-parallel-context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#rpg-ipc-parallel-causes)
+ [Aktionen](#rpg-ipc-parallel-actions)

## Unterstützte Engine-Versionen
<a name="rpg-ipc-parallel-context-supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von Aurora PostgreSQL unterstützt.

## Kontext
<a name="rpg-ipc-parallel-context"></a>

Bei der parallelen Abfrageausführung in PostgreSQL arbeiten mehrere Prozesse zusammen, um eine einzelne Abfrage zu verarbeiten. Wenn festgestellt wird, dass eine Abfrage für die Parallelisierung geeignet ist, koordiniert ein Leader-Prozess die Arbeit mit einem oder mehreren parallelen Worker-Prozessen je nach `max_parallel_workers_per_gather`-Parametereinstellung. Der Leader-Prozess teilt die Arbeit auf die einzelnen Worker auf und jeder Worker verarbeitet unabhängig seinen Teil der Daten. Die Ergebnisse werden dann an den Leader-Prozess zurückgemeldet.

**Anmerkung**  
Jeder parallele Worker fungiert als separater Prozess mit Ressourcenanforderungen, die einer vollständigen Benutzersitzung ähneln. Das bedeutet, dass eine parallel Abfrage mit 4 Workern bis zu fünfmal so viele Ressourcen (CPU, Arbeitsspeicher, I/O Bandbreite) verbrauchen kann wie eine nicht parallele Abfrage, da sowohl der Leader-Prozess als auch jeder Worker-Prozess ihre eigenen Ressourcenzuweisungen beibehalten. So werden beispielsweise Einstellungen wie `work_mem` individuell auf jeden Worker angewendet, wodurch sich die gesamte Speicherbelegung aller Prozesse vervielfachen kann.

Die Architektur einer parallelen Abfrage besteht aus drei Hauptkomponenten:
+ Leader-Prozess: Dies ist der Hauptprozess, der den Parallelbetrieb einleitet, den Workload aufteilt und die Abstimmung mit den Worker-Prozessen vornimmt.
+ Worker-Prozesse: Dies sind Hintergrundprozesse, die Teile der Abfrage parallel ausführen.
+ Gather/Gather merge: Dies sind Operationen, die Ergebnisse mehrerer Worker-Prozesse kombinieren und zurück an den Leader melden.

Während der parallelen Ausführung müssen Prozesse über Mechanismen der Interprozesskommunikation (IPC) miteinander kommunizieren. Diese IPC-Warteereignisse treten in verschiedenen Phasen auf:
+ Worker-Start: wenn parallele Worker initialisiert werden
+ Datenaustausch: wenn Worker Daten verarbeiten und Ergebnisse an den Leader senden
+ Worker-Shutdown: wenn die parallele Ausführung abgeschlossen ist und Worker beendet werden
+ Synchronisierungspunkte: wenn Prozesse koordiniert werden oder darauf warten müssen, dass andere Prozesse ihre Aufgaben abschließen

Das Kennen dieser Warteereignisse ist entscheidend für die Diagnose von Leistungsproblemen im Zusammenhang mit der parallelen Abfrageausführung, insbesondere in Umgebungen mit hoher Nichtsequentialität, in denen mehrere parallele Abfragen gleichzeitig ausgeführt werden.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="rpg-ipc-parallel-causes"></a>

Verschiedene Faktoren können zu einer Zunahme parallel-bezogener IPC-Warteereignisse beitragen:

**Hohe Nichtsequentialität paralleler Abfragen**  
Wenn viele parallele Abfragen gleichzeitig ausgeführt werden, kann dies zu Ressourcenkonflikten und längeren Wartezeiten für IPC-Operationen führen. Dies ist besonders häufig bei Systemen mit hohem Transaktionsvolumen oder analytischen Workloads der Fall.

**Suboptimale Pläne für parallele Abfragen**  
Wenn der Abfrageplaner ineffiziente Parallelisierungspläne auswählt, kann dies zu unnötiger Parallelisierung oder schlechter Arbeitsverteilung unter den Workern führen. Dies kann zu höheren IPC-Wartezeiten führen, insbesondere bei den Ereignissen `IPC:ExecuteGather` und `IPC:ParallelFinish`. Diese Planungsprobleme sind häufig auf veraltete Statistiken und table/index unübersichtliche Datenmengen zurückzuführen.

**Häufiges Starten und Herunterfahren paralleler Worker**  
Kurzlebige Abfragen, die häufig parallele Worker initiieren und beenden, können zu einer Zunahme von `IPC:BgWorkerStartup`- und `IPC:BgWorkerShutdown`-Ereignissen führen. Dies kommt oftmals bei OLTP-Workloads mit vielen kleinen, parallelisierbaren Abfragen vor.

**Einschränkungen für Ressourcen**  
Eine begrenzte CPU, ein begrenzter Arbeitsspeicher oder eine begrenzte I/O Kapazität können zu Engpässen bei der parallel Ausführung führen, was zu längeren Wartezeiten bei allen IPC-Ereignissen führt. Wenn beispielsweise die CPU ausgelastet ist, kann es länger dauern, bis Worker-Prozesse starten oder ihren Teil der Arbeit erledigen.

**Komplexe Abfragestrukturen**  
Abfragen mit mehreren Parallelitätsebenen (z. B. parallele Joins, auf die parallele Aggregationen folgen) können zu komplexeren IPC-Mustern und potenziell längeren Wartezeiten führen, insbesondere bei `IPC:ExecuteGather`-Ereignissen.

**Große Ergebnismengen**  
Abfragen, die große Ergebnismengen liefern, können zu längeren `IPC:ExecuteGather`-Wartezeiten führen, da der Leader-Prozess mehr Zeit damit verbringt, Ergebnisse von Worker-Prozessen zu erfassen und zu verarbeiten.

Das Kennen dieser Faktoren kann bei der Diagnose und Behebung von Leistungsproblemen im Zusammenhang mit der parallelen Abfrageausführung in Aurora PostgreSQL hilfreich sein.

## Aktionen
<a name="rpg-ipc-parallel-actions"></a>

Wenn Sie Wartezeiten im Zusammenhang mit parallelen Abfragen bemerken, bedeutet dies in der Regel, dass ein Backend-Prozess parallele Worker-Prozesse koordiniert oder auf diese wartet. Diese Wartezeiten treten häufig bei der Ausführung von Parallelisierungsplänen auf. Sie können die Auswirkungen dieser Wartezeiten untersuchen und abmildern, indem Sie die Verwendung paralleler Worker überwachen, die Parametereinstellungen überprüfen und die Abfrageausführung und Ressourcenzuweisung optimieren.

**Topics**
+ [Analysieren von Abfrageplänen in Bezug auf ineffiziente Parallelität](#rpg-ipc-parallel-analyze-plans)
+ [Überwachen der Verwendung paralleler Abfragen](#rpg-ipc-parallel-monitor)
+ [Überprüfen und Anpassen von Einstellungen für parallele Abfragen](#rpg-ipc-parallel-adjust-settings)
+ [Optimieren der Ressourcenzuweisung](#rpg-ipc-parallel-optimize-resources)
+ [Untersuchen der Verbindungsverwaltung](#rpg-ipc-parallel-connection-management)
+ [Überprüfen und Optimieren von Wartungsvorgängen](#rpg-ipc-parallel-maintenance)

### Analysieren von Abfrageplänen in Bezug auf ineffiziente Parallelität
<a name="rpg-ipc-parallel-analyze-plans"></a>

Die parallele Ausführung von Abfragen kann häufig zu Systeminstabilität, CPU-Spitzen und unvorhersehbaren Leistungsschwankungen bei Abfragen führen. Es ist wichtig, gründlich zu analysieren, ob eine Parallelität Ihrem spezifischen Workload tatsächlich zugutekommt. Verwenden Sie EXPLAIN ANALYZE, um Pläne für die parallele Ausführung von Abfragen zu überprüfen.

Deaktivieren Sie zur Ermittlung der Planeffizienz vorübergehend die Parallelität auf Sitzungsebene:

```
SET max_parallel_workers_per_gather = 0;
EXPLAIN ANALYZE <your_query>;
```

Aktivieren Sie zwecks Vergleich wieder die Parallelität:

```
RESET max_parallel_workers_per_gather;
EXPLAIN ANALYZE <your_query>;
```

Wenn die Deaktivierung der Parallelität zu besseren oder konsistenteren Ergebnissen führt, sollten Sie erwägen, sie für bestimmte Abfragen auf Sitzungsebene mithilfe von SET-Befehlen zu deaktivieren. Um eine umfassendere Wirkung zu erzielen, können Sie die Parallelität auf Instance-Ebene deaktivieren, indem Sie die entsprechenden Parameter in Ihrer DB-Parametergruppe anpassen. Weitere Informationen finden Sie unter [Ändern von Parametern in einer DB-Parametergruppe in Amazon RDS](USER_WorkingWithParamGroups.Modifying.md).

### Überwachen der Verwendung paralleler Abfragen
<a name="rpg-ipc-parallel-monitor"></a>

Verwenden Sie die folgenden Abfragen, um einen Einblick in die Aktivität und Kapazität paralleler Abfragen zu gewinnen:

Überprüfen Sie die aktiven, parallelen Worker-Prozesse:

```
SELECT
    COUNT(*)
FROM
    pg_stat_activity
WHERE
    backend_type = 'parallel worker';
```

Diese Abfrage zeigt die Anzahl der aktiven, parallelen Worker-Prozesse. Ein hoher Wert kann darauf hinweisen, dass Ihr „max\$1parallel\$1workers“ mit einem hohen Wert konfiguriert ist. Erwägen Sie, diesen zu verringern.

Überprüfen Sie gleichzeitige parallele Abfragen:

```
SELECT
    COUNT(DISTINCT leader_pid)
FROM
    pg_stat_activity
WHERE
    leader_pid IS NOT NULL;
```

Diese Abfrage gibt die Anzahl der verschiedenen Leader-Prozesse zurück, durch die parallele Abfragen gestartet wurden. Eine hohe Zahl weist hier darauf hin, dass mehrere Sitzungen gleichzeitig parallele Abfragen ausführen, was die CPU- und Speicherauslastung erhöhen kann.

### Überprüfen und Anpassen von Einstellungen für parallele Abfragen
<a name="rpg-ipc-parallel-adjust-settings"></a>

Überprüfen Sie die folgenden Parameter, um sicherzustellen, dass sie Ihrem Workload entsprechen:
+ `max_parallel_workers`: Gesamtzahl der parallelen Worker in allen Sitzungen
+ `max_parallel_workers_per_gather`: Max. Worker-Anzahl pro Abfrage

Bei OLAP-Workloads kann eine Erhöhung dieser Werte die Leistung verbessern. Für OLTP-Workloads werden im Allgemeinen niedrigere Werte bevorzugt.

```
SHOW max_parallel_workers;
SHOW max_parallel_workers_per_gather;
```

### Optimieren der Ressourcenzuweisung
<a name="rpg-ipc-parallel-optimize-resources"></a>

Überwachen Sie die CPU-Auslastung und erwägen Sie, die Anzahl von v CPUs anzupassen, wenn sie konstant hoch ist und Ihre Anwendung von parallel Abfragen profitiert. Stellen Sie sicher, dass ausreichend Speicher für parallele Operationen verfügbar ist.
+ Ermitteln Sie anhand von Performance Insights, ob das System CPU-gebunden ist.
+ Jeder parallele Worker verwendet seinen eigenen `work_mem`. Stellen Sie sicher, dass die Gesamtspeichernutzung innerhalb der Instance-Grenzen liegt.

Parallele Abfragen können erheblich mehr Ressourcen verbrauchen als nicht parallele, da jeder Worker-Prozess ein vollständig separater Prozess ist, der ungefähr die gleichen Auswirkungen auf das System hat wie eine zusätzliche Benutzersitzung. Dies sollte bei der Auswahl eines Werts für diese Einstellung sowie bei der Konfiguration anderer Einstellungen zur Steuerung der Ressourcennutzung berücksichtigt werden, zum Beispiel `work_mem`. Weitere Informationen finden Sie in der [PostgreSQL-Dokumentation](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM). Ressourcenbegrenzungen, wie `work_mem` werden individuell auf jeden Worker angewendet, das bedeutet, dass die Gesamtauslastung über alle Prozesse hinweg viel höher sein kann, als dies normalerweise für einen einzelnen Prozess der Fall wäre.

Erwägen Sie, v zu erhöhen CPUs oder die Speicherparameter zu optimieren, wenn Ihre Arbeitslast stark parallelisiert ist.

### Untersuchen der Verbindungsverwaltung
<a name="rpg-ipc-parallel-connection-management"></a>

Wenn die Verbindung überlastet ist, prüfen Sie Strategien für ein Verbindungspooling der Anwendung. Erwägen Sie die Implementierung von Verbindungspooling auf Anwendungsebene, sofern es nicht bereits verwendet wird.

### Überprüfen und Optimieren von Wartungsvorgängen
<a name="rpg-ipc-parallel-maintenance"></a>

Koordinieren Sie die Indexerstellung und andere Wartungsaufgaben, um Ressourcenkonflikte zu vermeiden. Erwägen Sie, diese Vorgänge für Zeiten außerhalb der Spitzenzeiten einzuplanen. Vermeiden Sie es, umfangreiche Wartungsvorgänge (z. B. parallele Indexerstellungen) für Zeiten mit hoher Benutzerabfragelast einzuplanen. Diese Operationen können parallele Worker beanspruchen und die Leistung bei regulären Abfragen negativ beeinträchtigen.

# IPC: ProcArrayGroupUpdate
<a name="apg-rpg-ipcprocarraygroup"></a>

Das `IPC:ProcArrayGroupUpdate` Ereignis tritt ein, wenn eine Sitzung darauf wartet, dass der Gruppenleiter den Transaktionsstatus am Ende des Vorgangs aktualisiert. Während PostgreSQL im Allgemeinen Warteereignisse vom Typ IPC mit parallel Abfrageoperationen verknüpft, ist dieses spezielle Wartungsereignis nicht spezifisch für parallel Abfragen.

**Topics**
+ [Unterstützte Engine-Versionen](#apg-rpg-ipcprocarraygroup.supported)
+ [Kontext](#apg-rpg-ipcprocarraygroup.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#apg-rpg-ipcprocarraygroup.causes)
+ [Aktionen](#apg-rpg-ipcprocarraygroup.actions)

## Unterstützte Engine-Versionen
<a name="apg-rpg-ipcprocarraygroup.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt.

## Kontext
<a name="apg-rpg-ipcprocarraygroup.context"></a>

**Das Prozessarray verstehen** — Das Prozessarray (proc) ist eine gemeinsam genutzte Speicherstruktur in PostgreSQL. Es enthält Informationen über alle laufenden Prozesse, einschließlich Transaktionsdetails. Während des Abschlusses der Transaktion (`COMMIT`oder`ROLLBACK`) ProcArray muss die Datei aktualisiert werden, um die Änderung widerzuspiegeln und die TransactionID aus dem Array zu löschen. Die Sitzung, die versucht, ihre Transaktion abzuschließen, muss eine exklusive Sperre für erhalten. ProcArray Dadurch wird verhindert, dass andere Prozesse gemeinsame oder exklusive Sperren für die Datei erhalten.

**Mechanismus zur Gruppenaktualisierung** — Wenn ein Back-End-Prozess bei der Ausführung eines COMMIT- oder ROLLBACK-Vorgangs ProcArrayLock im exklusiven Modus keinen Wert abrufen kann, aktualisiert er ein spezielles Feld mit dem Namen. ProcArrayGroupMember Dadurch wird die Transaktion der Liste der Sitzungen hinzugefügt, die beendet werden sollen. Dieser Backend-Prozess schläft dann, und die Zeit, in der er sich befindet, wird als ProcArrayGroupUpdate Warteereignis instrumentiert. Der erste Prozess im ProcArray procArrayGroup With-Member, der als Leader-Prozess bezeichnet wird, erfolgt ProcArrayLock im exklusiven Modus. Anschließend wird die Liste der Prozesse gelöscht, die auf das Löschen der GruppentransactionID warten. Sobald dieser Vorgang abgeschlossen ist, gibt der Leader alle Prozesse in dieser Liste frei ProcArrayLock und aktiviert sie, sodass sie darüber informiert werden, dass ihre Transaktion abgeschlossen ist.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="apg-rpg-ipcprocarraygroup.causes"></a>

Je mehr Prozesse ausgeführt werden, desto länger hält ein Leader an einem procArrayLock im exklusiven Modus fest. Je mehr Schreibtransaktionen in einem Gruppenaktualisierungsszenario enden, was zu einer potenziellen Anhäufung von Prozessen führt, die auf das Warteereignis `ProcArrayGroupUpdate` warten. In der Top-SQL-Ansicht von Database Insights werden Sie sehen, dass COMMIT die Anweisung ist, bei der der Großteil dieses Warteereignisses auftritt. Dies ist zu erwarten, erfordert jedoch eine eingehendere Untersuchung der spezifischen Schreib-SQL, die gerade ausgeführt wird, um festzustellen, welche geeigneten Maßnahmen zu ergreifen sind.

## Aktionen
<a name="apg-rpg-ipcprocarraygroup.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen. Identifizieren Sie `IPC:ProcArrayGroupUpdate` Ereignisse mithilfe von Amazon RDS Performance Insights oder durch Abfragen der PostgreSQL-Systemansicht. `pg_stat_activity`

**Topics**
+ [Überwachung von Transaktions-, Commit- und Rollback-Vorgängen](#apg-rpg-ipcprocarraygroup.actions.monitor)
+ [Reduzierung der Parallelität](#apg-rpg-ipcprocarraygroup.actions.concurrency)
+ [Implementierung von Verbindungspooling](#apg-rpg-ipcprocarraygroup.actions.pooling)
+ [Schnelleren Speicher verwenden](#apg-rpg-ipcprocarraygroup.actions.storage)

### Überwachung von Transaktions-, Commit- und Rollback-Vorgängen
<a name="apg-rpg-ipcprocarraygroup.actions.monitor"></a>

**Überwachen Sie Commits und Rollbacks** — Eine erhöhte Anzahl von Commits und Rollbacks kann zu einem erhöhten Druck auf die führen. ProcArray Wenn beispielsweise eine SQL-Anweisung aufgrund einer erhöhten Anzahl von Verletzungen doppelter Schlüssel zu scheitern beginnt, kann es zu einer Zunahme von Rollbacks kommen, was wiederum zu Konflikten und zu einer Überlastung der Tabellen führen kann. ProcArray

Amazon RDS Database Insights stellt die PostgreSQL-Metriken `xact_rollback` bereit `xact_commit` und berichtet über die Anzahl der Commits und Rollbacks pro Sekunde.

### Reduzierung der Parallelität
<a name="apg-rpg-ipcprocarraygroup.actions.concurrency"></a>

**Batch-Transaktionen** — Wenn möglich, sollten Operationen in Einzeltransaktionen gebündelt werden, um die Anzahl der Operationen zu reduzieren commit/rollback .

**Parallelität einschränken** — Reduzieren Sie die Anzahl der gleichzeitig aktiven Transaktionen, um Sperrkonflikte bei der zu vermeiden. ProcArray Es sind zwar einige Tests erforderlich, aber eine Reduzierung der Gesamtzahl gleichzeitiger Verbindungen kann Konflikte reduzieren und den Durchsatz aufrechterhalten.

### Implementierung von Verbindungspooling
<a name="apg-rpg-ipcprocarraygroup.actions.pooling"></a>

**Verbindungspooling-Lösungen** — Verwenden Sie Verbindungspooling, um Datenbankverbindungen effizient zu verwalten und so die Gesamtzahl der Backends und damit die Arbeitslast auf dem zu reduzieren. ProcArray Es sind zwar einige Tests erforderlich, aber die Reduzierung der Gesamtzahl gleichzeitiger Verbindungen kann Konflikte reduzieren und den Durchsatz aufrechterhalten.

**Reduzieren Sie Verbindungsstürme** — In ähnlicher Weise führt ein Muster, bei dem häufig Verbindungen hergestellt und beendet werden, zu zusätzlichem Druck auf die. ProcArray Durch die Reduzierung dieses Musters werden Konflikte insgesamt reduziert.

### Schnelleren Speicher verwenden
<a name="apg-rpg-ipcprocarraygroup.actions.storage"></a>

**Dediziertes Protokollvolumen** — Wenn das `IPC:ProcArrayGroupUpdate` Warteereignis mit Ereignissen mit hoher `IO:WALWrite` Wartezeit einhergeht, kann durch die Einrichtung eines dedizierten Protokollvolumes der Engpass beim Schreiben in WAL reduziert werden. Dies wiederum verbessert die Leistung von Commits.

Weitere Informationen finden Sie unter [Dediziertes Protokollvolumen](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PIOPS.dlv.html).

# Lock:advisory
<a name="wait-event.lockadvisory"></a>

Das `Lock:advisory`-Ereignis tritt auf, wenn eine PostgreSQL-Anwendung eine Sperre verwendet, um Aktivitäten über mehrere Sitzungen hinweg zu koordinieren.

**Topics**
+ [Relevante Engine-Versionen](#wait-event.lockadvisory.context.supported)
+ [Kontext](#wait-event.lockadvisory.context)
+ [Ursachen](#wait-event.lockadvisory.causes)
+ [Aktionen](#wait-event.lockadvisory.actions)

## Relevante Engine-Versionen
<a name="wait-event.lockadvisory.context.supported"></a>

Diese Warteereignisinformationen sind für die RDS-für-PostgreSQL-Versionen 9.6 und höher relevant.

## Kontext
<a name="wait-event.lockadvisory.context"></a>

PostgreSQL-Beratungssperren sind Anwendungsebene, kooperative Sperren werden explizit durch den Anwendungscode des Benutzers gesperrt und freigeschaltet. Eine Anwendung kann PostgreSQL-Beratungssperren verwenden, um Aktivitäten über mehrere Sitzungen hinweg zu koordinieren. Im Gegensatz zu normalen Sperren auf Objekt- oder Zeilenebene hat die Anwendung die volle Kontrolle über die Lebensdauer des Schlosses. Weitere Informationen finden Sie unter [Empfohlene Sperren](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) in der PostgreSQL-Dokumentation.

Beratungssperren können vor dem Ende einer Transaktion freigegeben werden oder von einer Sitzung über Transaktionen hinweg gehalten werden. Dies gilt nicht für implizite, vom System erzwungene Sperren, wie z. B. eine zugriffsexklusive Sperre für eine Tabelle, die von einer `CREATE INDEX`-Anweisung abgerufen wird.

Eine Beschreibung der Funktionen zum Erlangen (Sperren) und Freigeben (Entsperren) von Advisory Locks finden Sie unter [Advisory Lock Functions](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS) in der PostgreSQL-Dokumentation.

Advisory Locks werden zusätzlich zum regulären PostgreSQL-Locking-System implementiert und sind in der `pg_locks`-Systemansicht sichtbar.

## Ursachen
<a name="wait-event.lockadvisory.causes"></a>

Dieser Schlosstyp wird ausschließlich von einer Anwendung gesteuert, die ihn explizit verwendet. Beratungssperren, die für jede Zeile als Teil einer Abfrage erworben werden, können zu einem Anstieg der Sperren oder zu einem langfristigen Aufbau führen.

Diese Effekte treten auf, wenn die Abfrage so ausgeführt wird, dass Sperren für mehr Zeilen erwirbt, als von der Abfrage zurückgegeben werden. Die Anwendung muss schließlich jede Sperre freigeben, aber wenn Sperren für Zeilen erworben werden, die nicht zurückgegeben werden, kann die Anwendung nicht alle Sperren finden.

Das folgende Beispiel stammt aus [Empfohlene Sperren](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) in der PostgreSQL-Dokumentation.

```
SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100;
```

In diesem Beispiel kann die `LIMIT`-Klausel die Ausgabe der Abfrage nur stoppen, nachdem die Zeilen bereits intern ausgewählt und ihre ID-Werte gesperrt wurden. Dies kann plötzlich passieren, wenn ein wachsendes Datenvolumen dazu führt, dass der Planer einen anderen Ausführungsplan auswählt, der während der Entwicklung nicht getestet wurde. Der Aufbau erfolgt in diesem Fall, weil die Anwendung `pg_advisory_unlock` explizit für jeden gesperrten ID-Wert aufruft. In diesem Fall kann es jedoch nicht die Sperren finden, die für Zeilen erworben wurden, die nicht zurückgegeben wurden. Da die Sperren auf Sitzungsebene erworben werden, werden sie am Ende der Transaktion nicht automatisch freigegeben.

Eine weitere mögliche Ursache für Spikes bei blockierten Sperrversuchen sind unbeabsichtigte Konflikte. In diesen Konflikten teilen sich nicht verwandte Teile der Anwendung versehentlich denselben Sperren-ID-Raum.

## Aktionen
<a name="wait-event.lockadvisory.actions"></a>

Überprüfen Sie die Anwendungsnutzung von Beratungssperren und Details, wo und wann im Anwendungsablauf jede Art von Beratungssperre erworben und freigegeben wird.

Stellen Sie fest, ob eine Sitzung zu viele Sperren erwirbt oder eine lang andauernde Sitzung keine Sperren früh genug freigibt, was zu einem langsamen Aufbau von Sperren führt. Sie können einen langsamen Aufbau von Sperren auf Sitzungsebene korrigieren, indem Sie die Sitzung mit `pg_terminate_backend(pid)` beenden. 

Ein Client, der auf eine Beratungssperre wartet, erscheint in `pg_stat_activity` mit `wait_event_type=Lock` und `wait_event=advisory`. Sie können bestimmte Sperrwerte erhalten, indem Sie die `pg_locks`-Systemansicht nach demselben `pid` abfragen und nach `locktype=advisory` und `granted=f` suchen.

Sie können dann die blockierende Sitzung identifizieren, indem Sie `pg_locks` nach derselben beratenden Sperre mit `granted=t` abfragen, wie im folgenden Beispiel gezeigt.

```
SELECT blocked_locks.pid AS blocked_pid,
         blocking_locks.pid AS blocking_pid,
         blocked_activity.usename AS blocked_user,
         blocking_activity.usename AS blocking_user,
         now() - blocked_activity.xact_start AS blocked_transaction_duration,
         now() - blocking_activity.xact_start AS blocking_transaction_duration,
         concat(blocked_activity.wait_event_type,':',blocked_activity.wait_event) AS blocked_wait_event,
         concat(blocking_activity.wait_event_type,':',blocking_activity.wait_event) AS blocking_wait_event,
         blocked_activity.state AS blocked_state,
         blocking_activity.state AS blocking_state,
         blocked_locks.locktype AS blocked_locktype,
         blocking_locks.locktype AS blocking_locktype,
         blocked_activity.query AS blocked_statement,
         blocking_activity.query AS blocking_statement
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks blocking_locks
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
    WHERE NOT blocked_locks.GRANTED;
```

Alle API-Funktionen für beratende Sperren haben zwei Sätze von Argumenten, entweder ein `bigint`-Argument oder zwei `integer`-Argumente:
+ Bei den API-Funktionen mit einem `bigint`-Argument befinden sich die oberen 32 Bit in `pg_locks.classid` und die unteren 32 Bit in `pg_locks.objid`.
+ Bei den API-Funktionen mit zwei `integer`-Argumenten ist das erste Argument `pg_locks.classid` und das zweite Argument ist `pg_locks.objid`.

Der `pg_locks.objsubid`-Wert gibt an, welches API-Formular verwendet wurde: `1` bedeutet ein `bigint`-Argument; `2` bedeutet zwei `integer`-Argumente.

# Lock:extend
<a name="wait-event.lockextend"></a>

Das `Lock:extend`-Ereignis tritt ein, wenn ein Backend-Prozess darauf wartet, eine Beziehung zu sperren, um sie zu erweitern, während ein anderer Prozess diese Beziehung für denselben Zweck gesperrt hat.

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.lockextend.context.supported)
+ [Kontext](#wait-event.lockextend.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.lockextend.causes)
+ [Aktionen](#wait-event.lockextend.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.lockextend.context.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt.

## Kontext
<a name="wait-event.lockextend.context"></a>

Das Ereignis `Lock:extend` zeigt an, dass ein Backend-Prozess darauf wartet, eine Beziehung zu erweitern, für die ein anderer Backend-Prozess eine Sperre hält, während er diese Beziehung erweitert. Da jeweils nur ein Prozess eine Beziehung erweitern kann, generiert das System ein `Lock:extend`-Warteereignis. `INSERT`-, `COPY`- und `UPDATE`-Vorgänge können dieses Ereignis erzeugen.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.lockextend.causes"></a>

Wenn das `Lock:extend`-Ereignis mehr als normal auftritt, was möglicherweise auf ein Leistungsproblem hinweist, sind die folgenden typischen Ursachen:

**Anstieg der gleichzeitigen Einfügungen oder Aktualisierungen derselben Tabelle **  
Es kann zu einer Zunahme der Anzahl gleichzeitiger Sitzungen mit Abfragen kommen, die in dieselbe Tabelle einfügen oder aktualisieren.

**Unzureichende Netzwerkbandbreite**  
Die Netzwerkbandbreite auf der DB-Instance reicht möglicherweise nicht aus, um die Speicherkommunikationsanforderungen der aktuellen Workload zu gewährleisten. Dies kann zu einer Speicherlatenz führen, die zu einem Anstieg der `Lock:extend`-Ereignisse führt.

## Aktionen
<a name="wait-event.lockextend.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen.

**Topics**
+ [Reduzieren Sie gleichzeitige Einfügungen und Aktualisierungen auf dieselbe Beziehung](#wait-event.lockextend.actions.action1)
+ [Erhöhung der Netzwerkbandbreite](#wait-event.lockextend.actions.increase-network-bandwidth)

### Reduzieren Sie gleichzeitige Einfügungen und Aktualisierungen auf dieselbe Beziehung
<a name="wait-event.lockextend.actions.action1"></a>

Stellen Sie zunächst fest, ob die `tup_inserted`- und `tup_updated`-Metriken und damit auch dieses Warteereignis gestiegen ist. Überprüfen Sie in diesem Fall, welche Beziehungen für Einfüge- und Aktualisierungsvorgänge in hohem Streit stehen. Um dies zu ermitteln, fragen Sie die `pg_stat_all_tables`-Ansicht nach den Werten in den `n_tup_ins`- und `n_tup_upd`-Feldern ab. Informationen zur Ansicht `pg_stat_all_tables` finden Sie unter [pg\$1stat\$1all\$1tables](https://www.postgresql.org/docs/13/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW) in der PostgreSQL-Dokumentation. 

Um weitere Informationen über das Blockieren und blockierte Abfragen zu erhalten, fragen Sie `pg_stat_activity` wie im folgenden Beispiel ab:

```
SELECT
    blocked.pid,
    blocked.usename,
    blocked.query,
    blocking.pid AS blocking_id,
    blocking.query AS blocking_query,
    blocking.wait_event AS blocking_wait_event,
    blocking.wait_event_type AS blocking_wait_event_type
FROM pg_stat_activity AS blocked
JOIN pg_stat_activity AS blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid))
where
blocked.wait_event = 'extend'
and blocked.wait_event_type = 'Lock';
 
   pid  | usename  |            query             | blocking_id |                         blocking_query                           | blocking_wait_event | blocking_wait_event_type
  ------+----------+------------------------------+-------------+------------------------------------------------------------------+---------------------+--------------------------
   7143 |  myuser  | insert into tab1 values (1); |        4600 | INSERT INTO tab1 (a) SELECT s FROM generate_series(1,1000000) s; | DataFileExtend      | IO
```

Nachdem Sie Beziehungen identifiziert haben, die zur Erhöhung von `Lock:extend`-Ereignissen beitragen, verwenden Sie die folgenden Techniken, um die Konflikte zu reduzieren:
+ Finden Sie heraus, ob Sie Partitionierung verwenden können, um die Konflikte für dieselbe Tabelle zu reduzieren. Das Trennen eingefügter oder aktualisierter Tupel in verschiedene Partitionen kann die Konflikte verringern. Weitere Informationen zur Partitionierung finden Sie unter [Verwalten von PostgreSQL-Partitionen mit der Erweiterung pg\$1partman](PostgreSQL_Partitions.md).
+ Wenn das Warteereignis hauptsächlich auf Aktualisierungsaktivitäten zurückzuführen ist, sollten Sie erwägen, den Füllfaktor-Wert der Beziehung zu reduzieren. Dies kann Anfragen nach neuen Blöcken während des Updates reduzieren. Der Füllfaktor ist ein Speicherparameter für eine Tabelle, der den maximalen Speicherplatz zum Packen einer Tabellenseite bestimmt. Es wird als Prozentsatz des gesamten Speicherplatzes für eine Seite ausgedrückt. Weitere Informationen zum Parameter fillfactor finden Sie unter [CREATE TABLE](https://www.postgresql.org/docs/13/sql-createtable.html) in der PostgreSQL-Dokumentation. 
**Wichtig**  
Wir empfehlen dringend, Ihr System zu testen, wenn Sie den Füllfaktor ändern, da sich die Änderung dieses Wertes je nach Workload negativ auf die Leistung auswirken kann.

### Erhöhung der Netzwerkbandbreite
<a name="wait-event.lockextend.actions.increase-network-bandwidth"></a>

Um zu sehen, ob die Schreiblatenz zunimmt, überprüfen Sie die `WriteLatency`-Metrik in CloudWatch. Wenn dies der Fall ist, verwenden Sie die Amazon-CloudWatch-Metriken `WriteThroughput` und `ReadThroughput`, um den speicherbezogenen Datenverkehr auf der DB-Instance zu überwachen. Diese Metriken können Ihnen helfen festzustellen, ob die Netzwerkbandbreite für die Speicheraktivität Ihrer Workload ausreicht.

Wenn Ihre Netzwerkbandbreite nicht ausreicht, erhöhen Sie sie. Wenn Ihre DB-Instance die Grenzen der Netzwerkbandbreite erreicht, besteht die einzige Möglichkeit, die Bandbreite zu erhöhen, darin, die Größe Ihrer DB-Instance zu erhöhen.

Weitere Informationen zu CloudWatch-Metriken finden Sie unter [Metriken CloudWatch auf Amazon-Instanzebene für Amazon RDS](rds-metrics.md#rds-cw-metrics-instance). Informationen zur Netzwerkleistung für jede DB-Instance-Klasse finden Sie unter [Metriken CloudWatch auf Amazon-Instanzebene für Amazon RDS](rds-metrics.md#rds-cw-metrics-instance). 

# Lock:Relation
<a name="wait-event.lockrelation"></a>

Das `Lock:Relation`-Ereignis tritt ein, wenn eine Abfrage darauf wartet, eine Sperre für eine Tabelle oder Sicht (Relation) zu erhalten, die derzeit von einer anderen Transaktion gesperrt ist.

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.lockrelation.context.supported)
+ [Kontext](#wait-event.lockrelation.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.lockrelation.causes)
+ [Aktionen](#wait-event.lockrelation.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.lockrelation.context.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt.

## Kontext
<a name="wait-event.lockrelation.context"></a>

Die meisten PostgreSQL-Befehle verwenden implizit Sperren, um den gleichzeitigen Zugriff auf Daten in Tabellen zu steuern. Sie können diese Sperren auch explizit mit dem `LOCK`-Befehl in Ihrem Anwendungscode verwenden. Viele Sperrmodi sind nicht miteinander kompatibel und können Transaktionen blockieren, wenn sie versuchen, auf dasselbe Objekt zuzugreifen. In diesem Fall generiert RDS für PostgreSQL ein `Lock:Relation`-Ereignis. Einige gängige Beispiele sind die folgenden:
+ Exklusive Sperren wie `ACCESS EXCLUSIVE` können alle gleichzeitigen Zugriffe blockieren. Vorgänge in der Datendefinitionssprache (DDL) wie `DROP TABLE`, `TRUNCATE`, `VACUUM FULL` und `CLUSTER` erwerben implizit `ACCESS EXCLUSIVE`-Sperren. `ACCESS EXCLUSIVE` ist auch der Standardsperrmodus für `LOCK TABLE`-Anweisungen, die keinen Modus explizit angeben.
+ Die Verwendung von `CREATE INDEX (without CONCURRENT)` für eine Tabelle steht in Konflikt mit den DML-Anweisungen `UPDATE`, `DELETE` und `INSERT`, die `ROW EXCLUSIVE`-Sperren anfordern.

Weitere Informationen zu Sperren auf Tabellenebene und widersprüchlichen Sperrmodi finden Sie unter [Explizite Sperren](https://www.postgresql.org/docs/13/explicit-locking.html) in der PostgreSQL-Dokumentation.

Blockieren von Abfragen und Transaktionen entsperren in der Regel auf eine der folgenden Arten:
+ Blockierende Abfrage — Die Anwendung kann die Abfrage abbrechen oder der Benutzer kann den Prozess beenden. Die Engine kann die Abfrage auch aufgrund des Statement-Timeouts einer Sitzung oder eines Deadlock-Erkennungsmechanismus zum Ende zwingen.
+ Blockieren einer Transaktion – Eine Transaktion stoppt die Blockierung, wenn sie eine `ROLLBACK`- oder `COMMIT`-Anweisung ausführt. Rollbacks erfolgen auch automatisch, wenn Sitzungen von einem Client oder durch Netzwerkprobleme getrennt oder beendet werden. Sitzungen können beendet werden, wenn das Datenbank-Engine heruntergefahren wird, wenn das System keinen Arbeitsspeicher mehr hat usw.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.lockrelation.causes"></a>

Wenn das `Lock:Relation`-Ereignis häufiger als normal auftritt, kann dies auf ein Leistungsproblem hinweisen. Zu den typischen Ursachen zählen auch die Folgenden:

**Gleichzeitige Sitzungen mit widersprüchlichen Tabellensperren erhöht**  
Es kann zu einer Zunahme der Anzahl gleichzeitiger Sitzungen mit Abfragen kommen, die dieselbe Tabelle mit widersprüchlichen Sperrmodi sperren.

**Wartungsvorgänge**  
Zustandswartungsvorgänge wie `VACUUM` und `ANALYZE` können die Anzahl widersprüchlicher Sperren erheblich erhöhen. `VACUUM FULL` erhält eine `ACCESS EXCLUSIVE`-Sperre und `ANALYSE` erhält eine `SHARE UPDATE EXCLUSIVE`-Sperre. Beide Arten von Sperren können ein `Lock:Relation`-Wait-Ereignis verursachen. Wartungsvorgänge für Anwendungsdaten wie das Aktualisieren einer materialisierten Ansicht können auch blockierte Abfragen und Transaktionen erhöhen.

**Sperrt bei Reader-In**  
Es könnte ein Konflikt zwischen den Beziehungssperren bestehen, die vom Writer und den Readern gehalten werden. Derzeit werden nur `ACCESS EXCLUSIVE`-Beziehungssperren auf Reader-Instances repliziert. Allerdings gerät die `ACCESS EXCLUSIVE`-Beziehungssperre in Konflikt mit jeder `ACCESS SHARE`-Beziehungssperre, die vom Reader gehalten wird. Dies kann zu einer Erhöhung der Warteereignisse für die Sperrbeziehung des Readers führen. 

## Aktionen
<a name="wait-event.lockrelation.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen.

**Topics**
+ [Reduzieren Sie die Auswirkungen der Blockierung von SQL-Anweisungen](#wait-event.lockrelation.actions.reduce-blocks)
+ [Minimieren Sie die Auswirkungen von Wartungsvorgängen](#wait-event.lockrelation.actions.maintenance)

### Reduzieren Sie die Auswirkungen der Blockierung von SQL-Anweisungen
<a name="wait-event.lockrelation.actions.reduce-blocks"></a>

Um die Auswirkungen des Blockierens von SQL-Anweisungen zu reduzieren, ändern Sie Ihren Anwendungscode nach Möglichkeit. Es folgen zwei gängige Techniken zum Reduzieren von Blöcken:
+ Verwenden Sie die Option `NOWAIT` – Einige SQL-Befehle, wie z. B. `SELECT`- und `LOCK`-Anweisungen, unterstützen diese Option. Die `NOWAIT`-Direktive bricht die Sperre anfordernde Abfrage ab, wenn die Sperre nicht sofort erworben werden kann. Diese Technik kann dazu beitragen, zu verhindern, dass eine Blockiersitzung eine Anhäufung blockierter Sitzungen dahinter verursacht.

  Beispiel: Angenommen, Transaktion A wartet auf eine Sperre, die von Transaktion B gehalten wird. Wenn B nun eine Sperre für eine Tabelle anfordert, die durch Transaktion C gesperrt ist, könnte Transaktion A blockiert werden, bis die Transaktion C abgeschlossen ist. Wenn Transaktion B jedoch ein `NOWAIT` verwendet, wenn sie die Sperre für C anfordert, kann sie schnell fehlschlagen und sicherstellen, dass Transaktion A nicht unbegrenzt warten muss.
+ Verwenden Sie `SET lock_timeout` – Legen Sie einen `lock_timeout`-Wert fest, um die Zeit zu begrenzen, die eine SQL-Anweisung wartet, um eine Sperre für eine Beziehung zu erhalten. Wenn die Sperre nicht innerhalb des angegebenen Timeouts erworben wird, wird die Transaktion, die die Sperre anfordert, abgebrochen. Stellen Sie diesen Wert auf Sitzungsebene ein.

### Minimieren Sie die Auswirkungen von Wartungsvorgängen
<a name="wait-event.lockrelation.actions.maintenance"></a>

Wartungsvorgänge wie `VACUUM` und `ANALYZE` sind wichtig. Wir empfehlen, sie nicht zu deaktivieren, da Sie `Lock:Relation`-Warteereignisse im Zusammenhang mit diesen Wartungsvorgängen finden. Die folgenden Ansätze können die Auswirkungen dieser Vorgänge minimieren:
+ Führen Sie Wartungsvorgänge während außerhalb der Hauptverkehrszeiten manuell aus.
+ Um `Lock:Relation`-Wartezeiten zu reduzieren, die durch Autovacuum-Aufgaben verursacht werden, führen Sie alle erforderlichen Autovacuum-Optimierungen durch. Informationen zum Optimieren von Autovacuum finden Sie unter [Arbeiten mit PostgreSQL Autovacuum auf Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html) im *Amazon-RDS-Benutzerhandbuch*.

# Lock:transactionid
<a name="wait-event.locktransactionid"></a>

Das `Lock:transactionid`-Ereignis tritt ein, wenn eine Transaktion auf eine Sperre auf Zeilenebene wartet.

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.locktransactionid.context.supported)
+ [Kontext](#wait-event.locktransactionid.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.locktransactionid.causes)
+ [Aktionen](#wait-event.locktransactionid.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.locktransactionid.context.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt.

## Kontext
<a name="wait-event.locktransactionid.context"></a>

Das Ereignis `Lock:transactionid` tritt ein, wenn eine Transaktion versucht, eine Sperre auf Zeilenebene zu erlangen, die bereits einer gleichzeitig laufenden Transaktion gewährt wurde. Die Sitzung, die das `Lock:transactionid`-Wait-Ereignis anzeigt, ist aufgrund dieser Sperre blockiert. Nachdem die blockierende Transaktion entweder in einer `COMMIT`- oder `ROLLBACK`-Anweisung endet, kann die blockierte Transaktion fortgesetzt werden.

Die Semantik der Multiversions-Parallelität von RDS für PostgreSQL garantiert, dass Leser keine Autoren blockieren und Autoren Leser nicht blockieren. Damit Konflikte auf Zeilenebene auftreten können, müssen blockierende und blockierte Transaktionen widersprüchliche Anweisungen der folgenden Typen ausgeben:
+ `UPDATE`
+ `SELECT … FOR UPDATE`
+ `SELECT … FOR KEY SHARE`

Die Anweisung `SELECT … FOR KEY SHARE` ist ein Sonderfall. Die Datenbank verwendet die Klausel `FOR KEY SHARE`, um die Leistung der referenziellen Integrität zu optimieren. Eine Sperre auf Zeilenebene für eine Zeile kann `INSERT`-, `UPDATE`- und `DELETE`-Befehle für andere Tabellen blockieren, die auf die Zeile verweisen.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.locktransactionid.causes"></a>

Wenn dieses Ereignis mehr als normal auftritt, sind die Ursache normalerweise `UPDATE`-, `SELECT … FOR UPDATE`-, `SELECT … FOR KEY SHARE`-Anweisungen in Kombination mit den folgenden Bedingungen.

**Topics**
+ [Hohe Gleichzeitigkeit](#wait-event.locktransactionid.concurrency)
+ [Leerlauf in Transaktion](#wait-event.locktransactionid.idle)
+ [Lang laufende Transaktionen](#wait-event.locktransactionid.long-running)

### Hohe Gleichzeitigkeit
<a name="wait-event.locktransactionid.concurrency"></a>

RDS für PostgreSQL kann eine körnige Sperrsemantik auf Zeilenebene verwenden. Die Wahrscheinlichkeit von Konflikten auf Zeilenebene steigt, wenn die folgenden Bedingungen erfüllt sind:
+ Eine sehr gleichzeitige Workload beansprucht dieselben Zeilen.
+ Parallelbetrieb steigt.

### Leerlauf in Transaktion
<a name="wait-event.locktransactionid.idle"></a>

Manchmal zeigt die Spalte `pg_stat_activity.state` den Wert `idle in transaction` an. Dieser Wert wird für Sitzungen angezeigt, die eine Transaktion gestartet, aber noch kein `COMMIT` oder `ROLLBACK` ausgegeben haben. Wenn der `pg_stat_activity.state`-Wert nicht `active` ist, ist die in `pg_stat_activity` angezeigte Abfrage die letzte, die ausgeführt wurde. Die blockierende Sitzung verarbeitet eine Abfrage nicht aktiv, da eine offene Transaktion eine Sperre hält.

Wenn eine Leerlauf-Transaktion eine Sperre auf Zeilenebene erworben hat, kann dies verhindern, dass andere Sitzungen sie erwerben. Diese Bedingung führt zu einem häufigen Auftreten des Warteereignisses `Lock:transactionid`. Um das Problem zu diagnostizieren, überprüfen Sie die Ausgabe von `pg_stat_activity` und `pg_locks`.

### Lang laufende Transaktionen
<a name="wait-event.locktransactionid.long-running"></a>

Transaktionen, die lange laufen, erhalten lange Zeit Sperren. Diese langjährigen Sperren können die Ausführung anderer Transaktionen verhindern.

## Aktionen
<a name="wait-event.locktransactionid.actions"></a>

Zeilensperre ist ein Konflikt zwischen `UPDATE`-, `SELECT … FOR UPDATE`- oder `SELECT … FOR KEY SHARE`-Anweisungen. Bevor Sie eine Lösung versuchen, sollten Sie herausfinden, wann diese Anweisungen in derselben Zeile ausgeführt werden. Wählen Sie mit diesen Informationen eine in den folgenden Abschnitten beschriebene Strategie aus.

**Topics**
+ [Reagieren auf hohe Parallelbetrieb](#wait-event.locktransactionid.actions.problem)
+ [Reagieren Sie auf ungenutzte Transaktionen](#wait-event.locktransactionid.actions.find-blocker)
+ [Reagieren Sie auf lang andauernde Transaktionen](#wait-event.locktransactionid.actions.concurrency)

### Reagieren auf hohe Parallelbetrieb
<a name="wait-event.locktransactionid.actions.problem"></a>

Wenn Parallelität das Problem darstellt, versuchen Sie eine der folgenden Techniken:
+ Senken Sie die Parallelität in der Anwendung. Verringern Sie beispielsweise die Anzahl der aktiven Sitzungen.
+ Implementieren Sie einen Verbindungspool. Informationen zum Poolen von Verbindungen mit RDS-Proxy finden Sie unter [Amazon RDS-Proxy ](rds-proxy.md).
+ Entwerfen Sie die Anwendung oder das Datenmodell, um konkurrierende `UPDATE`- und `SELECT … FOR UPDATE`-Anweisungen zu vermeiden. Sie können auch die Anzahl der Fremdschlüssel verringern, auf die von `SELECT … FOR KEY SHARE`-Anweisungen zugegriffen wird.

### Reagieren Sie auf ungenutzte Transaktionen
<a name="wait-event.locktransactionid.actions.find-blocker"></a>

Wenn `pg_stat_activity.state` `idle in transaction` anzeigt, verwenden Sie die folgenden Strategien:
+ Schalten Sie nach Möglichkeit Autocommit ein. Dieser Ansatz verhindert, dass Transaktionen andere Transaktionen blockieren, während sie auf ein `COMMIT` oder `ROLLBACK` warten.
+ Suchen Sie nach Codepfaden, denen `COMMIT`, `ROLLBACK` oder `END` fehlt.
+ Stellen Sie sicher, dass die Ausnahmebehandlungslogik in Ihrer Anwendung immer einen Pfad zu einem gültigen `end of transaction` hat.
+ Stellen Sie sicher, dass Ihre Anwendung Abfrageergebnisse verarbeitet, nachdem die Transaktion mit `COMMIT` oder `ROLLBACK` beendet wurde.

### Reagieren Sie auf lang andauernde Transaktionen
<a name="wait-event.locktransactionid.actions.concurrency"></a>

Wenn Transaktionen mit langer Laufzeit das häufige Auftreten von `Lock:transactionid` verursachen, versuchen Sie die folgenden Strategien:
+ Halten Sie Zeilensperren von lang andauernden Transaktionen fern.
+ Beschränken Sie die Länge von Abfragen, indem Sie nach Möglichkeit Autocommit implementieren.

# Lock:tuple
<a name="wait-event.locktuple"></a>

Das `Lock:tuple`-Ereignis tritt ein, wenn ein Backend-Prozess darauf wartet, eine Sperre für ein Tupel zu erlangen.

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.locktuple.context.supported)
+ [Kontext](#wait-event.locktuple.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.locktuple.causes)
+ [Aktionen](#wait-event.locktuple.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.locktuple.context.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt.

## Kontext
<a name="wait-event.locktuple.context"></a>

Das Ereignis `Lock:tuple` zeigt an, dass ein Back-End darauf wartet, eine Sperre für ein Tupel zu erlangen, während ein anderes Back-End eine widersprüchliche Sperre für dasselbe Tupel hält. Die folgende Tabelle veranschaulicht ein Szenario, in dem Sitzungen das `Lock:tuple`-Ereignis generieren.


|  Zeit  |  1. Sitzung  |  2. Sitzung  |  3. Sitzung  | 
| --- | --- | --- | --- | 
|  t1  |  Startet eine Transaktion.  |    |    | 
|  t2  |  Aktualisiert Zeile 1.  |    |    | 
|  t3  |    |  Aktualisiert Zeile 1. Die Sitzung erwirbt eine exklusive Sperre für das Tupel und wartet dann darauf, dass Sitzung 1 die Sperre durch Commit oder Rollback freigibt.  |    | 
|  t4  |    |    |  Aktualisiert Zeile 1. Die Sitzung wartet darauf, dass Sitzung 2 die exklusive Sperre für das Tupel freigibt.  | 

Oder Sie können dieses Warteereignis simulieren, indem Sie das Benchmarking-Tool `pgbench` verwenden. Konfigurieren Sie eine hohe Anzahl gleichzeitiger Sitzungen, um dieselbe Zeile in einer Tabelle mit einer benutzerdefinierten SQL-Datei zu aktualisieren.

Weitere Informationen zu widersprüchlichen Sperrmodi finden Sie unter [Explizite Sperren](https://www.postgresql.org/docs/current/explicit-locking.html) in der PostgreSQL-Dokumentation. Weitere Informationen zu `pgbench` finden Sie unter [pgbench](https://www.postgresql.org/docs/current/pgbench.html) in der PostgreSQL-Dokumentation.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.locktuple.causes"></a>

Wenn dieses Ereignis mehr als normal auftritt und möglicherweise auf ein Leistungsproblem hinweist, sind typische Ursachen:
+ Eine große Anzahl gleichzeitiger Sitzungen versucht, eine widersprüchliche Sperre für dasselbe Tupel zu erlangen, indem sie `UPDATE`- oder `DELETE`-Anweisungen ausführen.
+ In hochgradig gleichzeitigen Sitzungen wird eine `SELECT`-Anweisung ausgeführt, die den `FOR UPDATE`- oder `FOR NO KEY UPDATE`-Sperrmodus verwendet.
+ Verschiedene Faktoren veranlassen Anwendungs- oder Verbindungspools dazu, weitere Sitzungen zu öffnen, um dieselben Vorgänge auszuführen. Wenn neue Sitzungen versuchen, dieselben Zeilen zu ändern, kann die DB-Last stark ansteigen und `Lock:tuple` kann erscheinen.

Weitere Informationen finden Sie unter [Sperren auf Zeilenebene](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS) in der PostgreSQL-Dokumentation.

## Aktionen
<a name="wait-event.locktuple.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen.

**Topics**
+ [Untersuchen Sie Ihre Anwendungslogik](#wait-event.locktuple.actions.problem)
+ [Finde die Blocker-Sitzung](#wait-event.locktuple.actions.find-blocker)
+ [Reduzieren Sie Parallelität, wenn es hoch ist](#wait-event.locktuple.actions.concurrency)
+ [Beheben von Engpässen](#wait-event.locktuple.actions.bottlenecks)

### Untersuchen Sie Ihre Anwendungslogik
<a name="wait-event.locktuple.actions.problem"></a>

Finden Sie heraus, ob sich eine Blocker-Sitzung schon lange im `idle in transaction`-Zustand befindet. Wenn ja, erwägen Sie, die Blocker-Sitzung als kurzfristige Lösung zu beenden. Sie können die Funktion `pg_terminate_backend` verwenden. Weitere Informationen zu dieser Funktion finden Sie unter [Server-Signalisierungsfunktionen](https://www.postgresql.org/docs/13/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL) in der PostgreSQL-Dokumentation.

Gehen Sie für eine langfristige Lösung wie folgt vor:
+ Passen Sie die Anwendungslogik an.
+ Verwenden Sie den Parameter `idle_in_transaction_session_timeout`. Dieser Parameter beendet jede Sitzung mit einer offenen Transaktion, die länger als die angegebene Zeitspanne im Leerlauf ist. Weitere Informationen finden Sie unter [Standardeinstellungen für Clientverbindungen](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT) in der PostgreSQL-Dokumentation.
+ Verwenden Sie Autocommit so weit wie möglich. Weitere Informationen finden Sie unter [SET AUTOCOMMIT](https://www.postgresql.org/docs/current/ecpg-sql-set-autocommit.html) in der PostgreSQL-Dokumentation.

### Finde die Blocker-Sitzung
<a name="wait-event.locktuple.actions.find-blocker"></a>

Identifizieren Sie während des `Lock:tuple`-Wait-Ereignisses den Blocker und die blockierte Sitzung, indem Sie herausfinden, welche Sperren voneinander abhängen. Weitere Informationen finden Sie unter [Informationen zur Sperrabhängigkeit](https://wiki.postgresql.org/wiki/Lock_dependency_information) im PostgreSQL-Wiki. 

Im folgenden Beispiel werden alle Sitzungen abgefragt, nach `tuple` gefiltert und nach `wait_time` sortiert.

```
SELECT blocked_locks.pid AS blocked_pid,
         blocking_locks.pid AS blocking_pid,
         blocked_activity.usename AS blocked_user,
         blocking_activity.usename AS blocking_user,
         now() - blocked_activity.xact_start AS blocked_transaction_duration,
         now() - blocking_activity.xact_start AS blocking_transaction_duration,
         concat(blocked_activity.wait_event_type,':',blocked_activity.wait_event) AS blocked_wait_event,
         concat(blocking_activity.wait_event_type,':',blocking_activity.wait_event) AS blocking_wait_event,
         blocked_activity.state AS blocked_state,
         blocking_activity.state AS blocking_state,
         blocked_locks.locktype AS blocked_locktype,
         blocking_locks.locktype AS blocking_locktype,
         blocked_activity.query AS blocked_statement,
         blocking_activity.query AS blocking_statement
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks blocking_locks
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
    WHERE NOT blocked_locks.GRANTED;
```

### Reduzieren Sie Parallelität, wenn es hoch ist
<a name="wait-event.locktuple.actions.concurrency"></a>

Das `Lock:tuple`-Ereignis kann ständig auftreten, insbesondere in einer arbeitsreichen Zeit. Erwägen Sie in dieser Situation, die hohe Parallelität für sehr belegte Reihen zu reduzieren. Oft steuern nur wenige Zeilen eine Warteschlange oder die boolesche Logik, was diese Zeilen sehr ausgelastet macht.

Sie können die Parallelität reduzieren, indem Sie verschiedene Ansätze verwenden, die auf der Geschäftsanforderung, der Anwendungslogik und dem Workload-Typ basieren. Sie können z. B. Folgendes tun:
+ Gestalten Sie Ihre Tabellen- und Datenlogik neu, um hohe Parallelität zu reduzieren.
+ Ändern Sie die Anwendungslogik, um die hohe Parallelität auf Zeilenebene zu reduzieren.
+ Nutzen und gestalten Sie Abfragen mit Sperren auf Zeilenebene.
+ Verwenden Sie die `NOWAIT`-Klausel mit Wiederholungsvorgänge.
+ Erwägen Sie, optimistische und hybridsperrende Logik-Parallelitätssteuerung zu nutzen.
+ Überlegen Sie, die Isolationsstufe der Datenbank zu ändern.

### Beheben von Engpässen
<a name="wait-event.locktuple.actions.bottlenecks"></a>

Das `Lock:tuple` kann bei Engpässen wie CPU-Aushungerungen oder maximaler Nutzung der Amazon EBS-Bandbreite auftreten. Um Engpässe zu verringern, sollten Sie die folgenden Ansätze berücksichtigen:
+ Skalieren Sie Ihren Instance-Klassentyp hoch.
+ Optimieren Sie ressourcenintensive Abfragen.
+ Ändern Sie die Anwendungslogik.
+ Archivieren Sie Daten, die selten zugegriffen wird.

# LWLock: BufferMapping (:buffer\$1mapping) LWLock
<a name="wait-event.lwl-buffer-mapping"></a>

Dieses Ereignis tritt ein, wenn eine Sitzung darauf wartet, einen Datenblock einem Puffer im gemeinsam genutzten Pufferpool zuzuordnen.

**Anmerkung**  
Dieses Ereignis trägt in RDS für PostgreSQL Version 13 und höheren Versionen den Namen `LWLock:BufferMapping`. In PostgreSQL Version 12 und älteren Versionen lautet die Bezeichnung dieses Ereignisses `LWLock:buffer_mapping`. 

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.lwl-buffer-mapping.context.supported)
+ [Kontext](#wait-event.lwl-buffer-mapping.context)
+ [Ursachen](#wait-event.lwl-buffer-mapping.causes)
+ [Aktionen](#wait-event.lwl-buffer-mapping.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.lwl-buffer-mapping.context.supported"></a>

Diese Warteereignisinformationen sind für RDS für PostgreSQL Version 9.6 und höher relevant.

## Kontext
<a name="wait-event.lwl-buffer-mapping.context"></a>

Der *freigegebene Pufferpool* ist ein PostgreSQL-Speicherbereich, der alle Seiten enthält, die von Prozessen verwendet werden oder wurden. Wenn ein Prozess eine Seite benötigt, liest er die Seite in den freigegebenen Pufferpool. Der Parameter `shared_buffers` legt die Größe des gemeinsam genutzten Puffers fest und reserviert einen Speicherbereich zum Speichern der Tabellen- und Indexseiten. Wenn Sie diesen Parameter ändern, stellen Sie sicher, dass Sie die Datenbank neu starten.

Das `LWLock:buffer_mapping`-Wait-Ereignis tritt in den folgenden Szenarien auf:
+ Ein Prozess durchsucht die Puffertabelle nach einer Seite und erwirbt eine freigegebene Puffer-Mapping-Sperre.
+ Ein Prozess lädt eine Seite in den Pufferpool und erwirbt eine exklusive Puffer-Mapping-Sperre.
+ Ein Prozess entfernt eine Seite aus dem Pool und erwirbt eine exklusive Puffer-Mapping-Sperre.

## Ursachen
<a name="wait-event.lwl-buffer-mapping.causes"></a>

Wenn dieses Ereignis mehr als normal auftritt, was möglicherweise auf ein Leistungsproblem hinweist, greift die Datenbank in und aus dem freigegebenen Pufferpool aus. Zu den typischen Ursachen zählen auch die Folgenden:
+ Große Abfragen
+ Aufgeblähte Indizes und Tabellen
+ Vollständige Tabellenscans
+ Eine gemeinsame Poolgröße, die kleiner als der Arbeitssatz ist

## Aktionen
<a name="wait-event.lwl-buffer-mapping.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen.

**Topics**
+ [Überwachen Sie pufferbezogene Metriken](#wait-event.lwl-buffer-mapping.actions.monitor-metrics)
+ [Bewerten Sie Ihre Indexierungsstrategie](#wait-event.lwl-buffer-mapping.actions.indexes)
+ [Reduzieren Sie die Anzahl der Puffer, die schnell zugewiesen werden müssen](#wait-event.lwl-buffer-mapping.actions.buffers)

### Überwachen Sie pufferbezogene Metriken
<a name="wait-event.lwl-buffer-mapping.actions.monitor-metrics"></a>

Wenn `LWLock:buffer_mapping` auf Spitze wartet, untersuchen Sie die Puffertrefferquote. Sie können diese Metriken verwenden, um ein besseres Verständnis dafür zu erhalten, was im Puffer-Cache passiert. Untersuchen Sie die folgenden Metriken:

`blks_hit`  
Diese Zählermetrik für Performance Insights gibt die Anzahl der Blöcke an, die aus dem freigegebenen Pufferpool abgerufen wurden. Nachdem das Wait-Ereignis `LWLock:buffer_mapping` aufgetreten ist, können Sie eine Spitze in `blks_hit` beobachten.

`blks_read`  
Diese Performance Insights Insights-Zählermetrik gibt die Anzahl der Blöcke I/O an, die in den gemeinsam genutzten Pufferpool eingelesen werden mussten. Sie können im Vorfeld des `LWLock:buffer_mapping`-Warteereignisses eine Spitze in `blks_read` beobachten.

### Bewerten Sie Ihre Indexierungsstrategie
<a name="wait-event.lwl-buffer-mapping.actions.indexes"></a>

Überprüfen Sie Folgendes, um zu bestätigen, dass Ihre Indexierungsstrategie die Leistung nicht beeinträchtigt:

Indexblähung  
Stellen Sie sicher, dass Index und Tabellenaufblähungen nicht dazu führen, dass unnötige Seiten in den freigegebenen Puffer gelesen werden. Wenn Ihre Tabellen nicht verwendete Zeilen enthalten, sollten Sie die Daten archivieren und die Zeilen aus den Tabellen entfernen. Sie können dann die Indizes für die skalierten Tabellen neu erstellen.

Indizes für häufig verwendete Abfragen  
Um festzustellen, ob Sie über die optimalen Indizes verfügen, überwachen Sie die Metriken der DB-Engine in Performance Insights. Die `tup_returned`-Metrik zeigt die Anzahl der gelesenen Zeilen an. Die `tup_fetched`-Metrik zeigt die Anzahl der an den Client zurückgegebenen Zeilen. Wenn `tup_returned` deutlich größer als `tup_fetched` ist, werden die Daten möglicherweise nicht richtig indiziert. Außerdem sind Ihre Tabellenstatistiken möglicherweise nicht aktuell.

### Reduzieren Sie die Anzahl der Puffer, die schnell zugewiesen werden müssen
<a name="wait-event.lwl-buffer-mapping.actions.buffers"></a>

Um die `LWLock:buffer_mapping`-Warteereignisse zu reduzieren, versuchen Sie, die Anzahl der Puffer zu reduzieren, die schnell zugewiesen werden müssen. Eine Strategie besteht darin, kleinere Batch-Vorgänge durchzuführen. Möglicherweise können Sie kleinere Batches erreichen, indem Sie Ihre Tabellen partitionieren.

# LWLock:BufferIO (IPC:BufferIO)
<a name="wait-event.lwlockbufferio"></a>

Das `LWLock:BufferIO`-Ereignis tritt auf, wenn RDS für PostgreSQL darauf wartet, dass andere Prozesse ihre Eingabe-/Ausgabe-(I/O)-Vorgänge beenden, wenn sie gleichzeitig versuchen, auf eine Seite zuzugreifen. Sein Zweck besteht darin, dass dieselbe Seite in den freigegebenen Puffer eingelesen wird.

**Topics**
+ [Relevante Engine-Versionen](#wait-event.lwlockbufferio.context.supported)
+ [Kontext](#wait-event.lwlockbufferio.context)
+ [Ursachen](#wait-event.lwlockbufferio.causes)
+ [Aktionen](#wait-event.lwlockbufferio.actions)

## Relevante Engine-Versionen
<a name="wait-event.lwlockbufferio.context.supported"></a>

Diese Warteereignisinformationen sind für alle Versionen von RDS für PostgreSQL relevant. Für Aurora PostgreSQL 12 und frühere Versionen wird dieses Warteereignis als lwlock:buffer\$1io bezeichnet, während es in der Version RDS für PostgreSQL 13 den Namen lwlock:bufferio trägt. Aus der Version RDS für PostgreSQL 14 wurde das BufferIO-Warteereignis von `LWLock` zum Warteereignistyp `IPC` (IPC:BufferIO) verschoben. 

## Kontext
<a name="wait-event.lwlockbufferio.context"></a>

Jeder gemeinsam genutzte Puffer hat eine I/O-Sperre, die mit dem `LWLock:BufferIO`-Warteereignis verbunden ist, jedes Mal, wenn ein Block (oder eine Seite) außerhalb des gemeinsam genutzten Pufferpools abgerufen werden muss.

Diese Sperre wird verwendet, um mehrere Sitzungen zu behandeln, die alle Zugriff auf denselben Block benötigen. Dieser Block muss von außerhalb des gemeinsam genutzten Pufferpools gelesen werden, der durch den `shared_buffers`-Parameter definiert wird.

Sobald die Seite innerhalb des Shared Buffer Pool gelesen wird, wird die `LWLock:BufferIO`-Sperre freigegeben.

**Anmerkung**  
Das `LWLock:BufferIO`-Wait-Ereignis geht dem [IO: DataFileRead](wait-event.iodatafileread.md)-Warteereignis voraus. Das `IO:DataFileRead`-Wait-Ereignis tritt auf, während Daten aus dem Speicher gelesen werden.

Weitere Informationen zu leichten Sperren finden Sie unter [Übersicht über Sperren](https://github.com/postgres/postgres/blob/65dc30ced64cd17f3800ff1b73ab1d358e92efd8/src/backend/storage/lmgr/README#L20).

## Ursachen
<a name="wait-event.lwlockbufferio.causes"></a>

Häufige Gründe dafür, dass das `LWLock:BufferIO`-Ereignis in den Top-Wartezeiten angezeigt wird, sind die folgenden:
+ Mehrere Backends oder Verbindungen, die versuchen, auf dieselbe Seite zuzugreifen, für die auch ein I/O-Vorgang aussteht
+ Das Verhältnis zwischen der Größe des gemeinsam genutzten Pufferpools (definiert durch den `shared_buffers`-Parameter) und der Anzahl der Puffer, die von der aktuellen Workload benötigt werden
+ Die Größe des freigegebenen Pufferpools ist nicht gut mit der Anzahl der Seiten, die durch andere Vorgänge geräumt werden
+ Große oder aufgeblähte Indizes, bei denen die Engine mehr Seiten als nötig in den freigegebenen Pufferpool lesen muss
+ Mangel an Indizes, die die DB-Engine dazu zwingen, mehr Seiten aus den Tabellen als nötig zu lesen
+ Checkpoints, die zu häufig auftreten oder zu viele geänderte Seiten leeren müssen
+ Plötzliche Spitzen für Datenbankverbindungen, die versuchen, Vorgänge auf derselben Seite auszuführen

## Aktionen
<a name="wait-event.lwlockbufferio.actions"></a>

Abhängig von den Ursachen Ihres Wait-Ereignisses empfehlen wir verschiedene Aktionen:
+ Stimmen Sie `max_wal_size` und `checkpoint_timeout` basierend auf der Spitzenzeit Ihrer Workload ab, wenn Sie sehen, dass `LWLock:BufferIO` mit Einbrüchen der Metrik `BufferCacheHitRatio` zusammenfällt. Identifizieren Sie dann, welche Abfrage sie möglicherweise verursachen könnte.
+ Überprüfen Sie, ob Sie nicht verwendete Indizes haben, und entfernen Sie sie dann.
+ Verwenden Sie partitionierte Tabellen (die auch partitionierte Indizes haben). Dies hilft, die Neuordnung des Index niedrig zu halten und ihre Auswirkungen zu reduzieren.
+ Vermeiden Sie, Spalten unnötig zu indizieren.
+ Verhindern Sie plötzliche Spitzen der Datenbankverbindung, indem Sie einen Verbindungspool verwenden.
+ Beschränken Sie die maximale Anzahl von Verbindungen zur Datenbank als bewährte Methode

# LWLock:buffer\$1content (BufferContent)
<a name="wait-event.lwlockbuffercontent"></a>

Das Ereignis `LWLock:buffer_content` tritt ein, wenn eine Sitzung darauf wartet, eine Datenseite im Speicher zu lesen oder zu schreiben, während eine andere Sitzung diese Seite zum Schreiben gesperrt hat. In RDS für PostgreSQL 13 und höher heißt dieses Warteereignis `BufferContent`.

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.lwlockbuffercontent.context.supported)
+ [Kontext](#wait-event.lwlockbuffercontent.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.lwlockbuffercontent.causes)
+ [Aktionen](#wait-event.lwlockbuffercontent.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.lwlockbuffercontent.context.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt.

## Kontext
<a name="wait-event.lwlockbuffercontent.context"></a>

Um Daten zu lesen oder zu manipulieren, greift PostgreSQL über Shared Memory Puffer darauf zu. Um aus dem Puffer zu lesen, erhält ein Prozess eine leichte Sperre (LWLock) für den Pufferinhalt im freigegebenen Modus. Um in den Puffer zu schreiben, wird diese Sperre im exklusiven Modus angezeigt. Gemeinsame Sperren ermöglichen es anderen Prozessen, gleichzeitig gemeinsame Sperren für diesen Inhalt zu erwerben. Exklusive Sperren verhindern, dass andere Prozesse irgendeine Art von Sperre erhalten.

Die`LWLock:buffer_content`(`BufferContent`)-Ereignis zeigt an, dass mehrere Prozesse versuchen, den Inhalt eines bestimmten Puffers zu sperren.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.lwlockbuffercontent.causes"></a>

Wenn das `LWLock:buffer_content`(`BufferContent`)-Ereignis mehr als normal auftritt, was möglicherweise auf ein Leistungsproblem hinweist, sind die folgenden typischen Ursachen:

**Die gleichzeitigen Aktualisierungen der gleichen Daten wurden erhöht**  
Es kann zu einer Zunahme der Anzahl gleichzeitiger Sitzungen mit Abfragen kommen, die denselben Pufferinhalt aktualisieren. Diese Behauptung kann bei Tabellen mit vielen Indizes ausgeprägter sein.

**Workload-Daten befinden sich nicht im Speicher**  
Wenn sich Daten, die die aktive Workload verarbeitet, nicht im Speicher befinden, können diese Warteereignisse zunehmen. Dieser Effekt liegt daran, dass Prozesse, die Sperren halten, sie länger halten können, während sie Festplatten-I/O-Vorgänge ausführen.

**Übermäßiger Einsatz von Fremdschlüsselbeschränkungen**  
Fremdschlüsseleinschränkungen können die Zeit erhöhen, die ein Prozess an einer Pufferinhaltssperre hält. Dieser Effekt liegt daran, dass Lesevorgänge eine gemeinsame Pufferinhaltssperre für den referenzierten Schlüssel erfordern, während dieser Schlüssel aktualisiert wird.

## Aktionen
<a name="wait-event.lwlockbuffercontent.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen. Sie können `LWLock:buffer_content`(`BufferContent`)-Ereignisse identifizieren, indem Sie Amazon RDS Performance Insights verwenden oder die Ansicht `pg_stat_activity` abfragen.

**Topics**
+ [Verbessern Sie die Effizienz im Speicher](#wait-event.lwlockbuffercontent.actions.in-memory)
+ [Reduzieren Sie die Verwendung von Fremdschlüsselbeschränkungen](#wait-event.lwlockbuffercontent.actions.foreignkey)
+ [Entferne nicht verwendete Indizes](#wait-event.lwlockbuffercontent.actions.indexes)
+ [Erhöhen der Cachegröße bei Verwendung von Sequenzen](#wait-event.lwlockbuffercontent.actions.sequences)

### Verbessern Sie die Effizienz im Speicher
<a name="wait-event.lwlockbuffercontent.actions.in-memory"></a>

Um die Wahrscheinlichkeit zu erhöhen, dass sich aktive Workload-Daten im Speicher befinden, partitionieren Sie Tabellen oder skalieren Sie Ihre Instance-Klasse hoch. Weitere Informationen zu DB-Instance-Klassen finden Sie unter [](Concepts.DBInstanceClass.md).

### Reduzieren Sie die Verwendung von Fremdschlüsselbeschränkungen
<a name="wait-event.lwlockbuffercontent.actions.foreignkey"></a>

Untersuchen Sie Workloads, bei denen eine hohe Anzahl von `LWLock:buffer_content`(`BufferContent`)-Wait-Ereignissen auf die Verwendung von Fremdschlüsseleinschränkungen auftritt. Entfernen Sie unnötige Fremdschlüsselbeschränkungen.

### Entferne nicht verwendete Indizes
<a name="wait-event.lwlockbuffercontent.actions.indexes"></a>

Identifizieren Sie bei Workloads mit einer hohen Anzahl von `LWLock:buffer_content`(`BufferContent`)-Wait-Ereignissen nicht verwendete Indizes und entfernen Sie sie.

### Erhöhen der Cachegröße bei Verwendung von Sequenzen
<a name="wait-event.lwlockbuffercontent.actions.sequences"></a>

Wenn Ihre Tabellen Sequenzen verwenden, erhöhen Sie die Cachegröße, um Konflikte auf Sequenzseiten und Indexseiten zu vermeiden. Jede Sequenz ist eine einzelne Seite im gemeinsam genutzten Arbeitsspeicher. Der vordefinierte Cache gilt pro Verbindung. Dies reicht möglicherweise nicht aus, um die Workload zu bewältigen, wenn viele gleichzeitige Sitzungen einen Sequenzwert erhalten. 

# LWLock:lock\$1manager (:lockmanager) LWLock
<a name="wait-event.lw-lock-manager"></a>

Dieses Ereignis tritt auf, wenn die Engine von RDS für PostgreSQL den Speicherbereich der gemeinsam genutzten Sperre verwaltet, um eine Sperre zuzuweisen, zu überprüfen und aufzuheben, wenn eine Fast-Path-Sperre nicht möglich ist.

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.lw-lock-manager.context.supported)
+ [Kontext](#wait-event.lw-lock-manager.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.lw-lock-manager.causes)
+ [Aktionen](#wait-event.lw-lock-manager.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.lw-lock-manager.context.supported"></a>

Diese Warteereignisinformationen sind für RDS für PostgreSQL Version 9.6 und höher relevant. Für ältere Version von RDS für PostgreSQL als Version 13 lautet der Name dieses Warteereignisses `LWLock:lock_manager`. Für RDS für PostgreSQL Version 13 und höher lautet der Name dieses Warteereignisses `LWLock:lockmanager`. 

## Kontext
<a name="wait-event.lw-lock-manager.context"></a>

Wenn Sie eine SQL-Anweisung ausgeben, zeichnet RDS für PostgreSQL Sperren auf, um die Struktur, Daten und Integrität Ihrer Datenbank während gleichzeitiger Vorgänge zu schützen. Der Motor kann dieses Ziel mit einer schnellen Pfadsperre oder einer nicht schnellen Pfadsperre erreichen. Eine Pfadsperre, die nicht schnell ist, ist teurer und erzeugt mehr Overhead als eine schnelle Pfadsperre.

### Schnelle Pfadsperre
<a name="wait-event.lw-lock-manager.context.fast-path"></a>

Um den Overhead von Sperren zu reduzieren, die häufig genommen und freigegeben werden, aber selten in Konflikt geraten, können Backend-Prozesse eine schnelle Pfadsperrung verwenden. Die Datenbank verwendet diesen Mechanismus für Sperren, die die folgenden Kriterien erfüllen:
+ Sie verwenden die STANDARD–Sperrmethode.
+ Sie stellen eine Sperre für eine Datenbankbeziehung statt einer gemeinsamen Beziehung dar.
+ Sie sind schwache Sperren, die wahrscheinlich nicht in Konflikt stehen.
+ Die Engine kann schnell überprüfen, dass keine widersprüchlichen Sperren existieren können.

Die Engine kann keine schnelle Pfadsperre verwenden, wenn eine der folgenden Bedingungen erfüllt ist:
+ Die Sperre erfüllt nicht die vorhergehenden Kriterien.
+ Für den Backend-Prozess sind keine Slots mehr verfügbar.

Wenn Sie Ihre Abfragen für die Fast-Path-Sperrung optimieren möchten, können Sie die folgende Abfrage verwenden.

```
SELECT count(*), pid, mode, fastpath
  FROM pg_locks
 WHERE fastpath IS NOT NULL
 GROUP BY 4,3,2
 ORDER BY pid, mode;
 count | pid  |      mode       | fastpath
-------+------+-----------------+----------
16 | 9185 | AccessShareLock | t
336 | 9185 | AccessShareLock | f
1 | 9185 | ExclusiveLock   | t
```

Die folgende Abfrage zeigt nur die Gesamtsumme in der gesamten Datenbank.

```
SELECT count(*), mode, fastpath
  FROM pg_locks
 WHERE fastpath IS NOT NULL
 GROUP BY 3,2
 ORDER BY mode,1;
count |      mode       | fastpath
-------+-----------------+----------
16 | AccessShareLock | t
337 | AccessShareLock | f
1 | ExclusiveLock   | t
(3 rows)
```

Weitere Informationen zum Sperren von Fast Path finden Sie unter [Fast Path](https://github.com/postgres/postgres/blob/master/src/backend/storage/lmgr/README#L70-L76) in der README-Datei des PostgreSQL-Sperrmanagers und unter [pg-locks](https://www.postgresql.org/docs/9.3/view-pg-locks.html#AEN98195) in der PostgreSQL-Dokumentation. 

### Beispiel für ein Skalierungsproblem für den Sperrmanager
<a name="wait-event.lw-lock-manager.context.lock-manager"></a>

In diesem Beispiel speichert eine Tabelle mit dem Namen `purchases` Daten aus fünf Jahren, aufgeteilt nach Tagen. Jede Partition hat zwei Indizes. Die folgende Abfolge von Ereignissen tritt auf:

1. Sie fragen Daten für viele Tage ab, wodurch die Datenbank viele Partitionen lesen muss.

1. Die Datenbank erstellt einen Sperreintrag für jede Partition. Wenn Partitionsindizes Teil des Optimizer-Zugriffspfads sind, erstellt die Datenbank auch für sie einen Sperreintrag.

1. Wenn die Anzahl der angeforderten Sperreneinträge für denselben Backend-Prozess höher als 16 ist, was dem Wert von `FP_LOCK_SLOTS_PER_BACKEND` entspricht, verwendet der Sperrenmanager die Sperrmethode ohne Fast Path.

Moderne Anwendungen haben möglicherweise Hunderte von Sitzungen. Wenn gleichzeitige Sitzungen das übergeordnete Element ohne ordnungsgemäßen Schnitt von Partitionen abfragen, erstellt die Datenbank möglicherweise Hunderte oder sogar Tausende von nicht schnellen Pfadsperren. Wenn diese Parallelität höher als die Anzahl von v ist, tritt normalerweise das Ereignis wait auf. CPUs `LWLock:lock_manager`

**Anmerkung**  
Das Wait-Ereignis `LWLock:lock_manager` hat nichts mit der Anzahl der Partitionen oder Indizes in einem Datenbankschema zu tun. Stattdessen hängt es mit der Anzahl der nicht schnellen Pfadsperren zusammen, die die Datenbank steuern muss.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.lw-lock-manager.causes"></a>

Wenn das `LWLock:lock_manager` häufiger als normal auftritt, was möglicherweise auf ein Leistungsproblem hinweist, sind die wahrscheinlichsten Ursachen für plötzliche Spitzen wie folgt:
+ Gleichzeitige aktive Sitzungen führen Abfragen aus, die keine schnellen Pfadsperren verwenden. Diese Sitzungen überschreiten auch die maximale vCPU.
+ Eine große Anzahl gleichzeitiger aktiver Sitzungen greift auf eine stark partitionierte Tabelle zu. Jede Partition hat mehrere Indizes.
+ Die Datenbank erlebt einen Verbindungssturm. Standardmäßig erzeugen einige Anwendungen und Connection Pool-Software mehr Verbindungen, wenn die Datenbank langsam ist. Diese Praxis verschlimmert das Problem. Optimieren Sie Ihre Connection Pool-Software so, dass keine Verbindungsstürme auftreten.
+ Eine große Anzahl von Sitzungen fragt eine übergeordnete Tabelle ab, ohne Partitionen zu beschneiden.
+ Eine Datendefinitionssprache (DDL), Datenmanipulationssprache (DML) oder ein Wartungsbefehl sperrt ausschließlich eine Beleg-Beziehung oder Tupel, auf die häufig zugegriffen oder geändert werden.

## Aktionen
<a name="wait-event.lw-lock-manager.actions"></a>

Wenn das `CPU`-Wait-Ereignis auftritt, weist dies nicht unbedingt auf ein Leistungsproblem hin. Reagieren Sie auf dieses Ereignis nur, wenn sich die Leistung verschlechtert und dieses Wait-Ereignis die DB-Last dominiert.

**Topics**
+ [Verwenden Sie das Beschneiden von Partitionen](#wait-event.lw-lock-manager.actions.pruning)
+ [Entfernen unnötiger Indizes](#wait-event.lw-lock-manager.actions.indexes)
+ [Optimieren Sie Ihre Abfragen für schnelles Pfadsperren](#wait-event.lw-lock-manager.actions.tuning)
+ [Tune auf andere Warteereignisse](#wait-event.lw-lock-manager.actions.other-waits)
+ [Reduzieren von Hardware-Engpässen](#wait-event.lw-lock-manager.actions.hw-bottlenecks)
+ [Verwenden eines Verbindungs-Poolers](#wait-event.lw-lock-manager.actions.pooler)
+ [Durchführen eines Upgrades Ihrer Version von RDS für PostgreSQL](#wait-event.lw-lock-manager.actions.pg-version)

### Verwenden Sie das Beschneiden von Partitionen
<a name="wait-event.lw-lock-manager.actions.pruning"></a>

Die *Partitionsbereinigung* ist eine Strategie zur Abfrageoptimierung für deklarativ partitionierte Tabellen, die nicht benötigte Partitionen von Tabellenscans ausschließt und dadurch die Leistung verbessert. Das Beschneiden der Partition ist standardmäßig aktiviert. Wenn es ausgeschaltet ist, schalten Sie es wie folgt ein.

```
SET enable_partition_pruning = on;
```

Abfragen können die Partitionsbereinigung nutzen, wenn ihre `WHERE`-Klausel die für die Partitionierung verwendete Spalte enthält. Weitere Informationen finden Sie unter [Partitionsbereinigung](https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITION-PRUNING) in der PostgreSQL-Dokumentation.

### Entfernen unnötiger Indizes
<a name="wait-event.lw-lock-manager.actions.indexes"></a>

Ihre Datenbank enthält möglicherweise nicht verwendete oder selten verwendete Indizes. Wenn ja, erwägen Sie, sie zu löschen. Führen Sie eine der folgenden Aufgaben aus:
+ Erfahren Sie, wie Sie unnötige Indizes finden, indem Sie [Ungenutzte Indizes](https://wiki.postgresql.org/wiki/Index_Maintenance#Unused_Indexes) im PostgreSQL-Wiki lesen.
+ Führen Sie PG Collector aus. Dieses SQL-Skript sammelt Datenbankinformationen und präsentiert sie in einem konsolidierten HTML-Bericht. Überprüfen Sie den Abschnitt „Unbenutzte Indizes“. Weitere Informationen finden Sie unter [pg-collector im Labs-Repository](https://github.com/awslabs/pg-collector). AWS GitHub 

### Optimieren Sie Ihre Abfragen für schnelles Pfadsperren
<a name="wait-event.lw-lock-manager.actions.tuning"></a>

Um herauszufinden, ob Ihre Abfragen Fast Path Locking verwenden, fragen Sie die `fastpath`-Spalte in der `pg_locks`-Tabelle ab. Wenn Ihre Abfragen keine schnelle Pfadsperre verwenden, versuchen Sie, die Anzahl der Beziehungen pro Abfrage auf weniger als 16 zu reduzieren.

### Tune auf andere Warteereignisse
<a name="wait-event.lw-lock-manager.actions.other-waits"></a>

Wenn `LWLock:lock_manager` in der Liste der Top-Waits an erster oder zweiter Stelle steht, überprüfen Sie, ob die folgenden Wait-Ereignisse auch in der Liste erscheinen:
+ `Lock:Relation`
+ `Lock:transactionid`
+ `Lock:tuple`

Wenn die vorhergehenden Ereignisse in der Liste hoch erscheinen, sollten Sie zuerst diese Warteereignisse optimieren. Diese Ereignisse können ein Treiber für `LWLock:lock_manager`.

### Reduzieren von Hardware-Engpässen
<a name="wait-event.lw-lock-manager.actions.hw-bottlenecks"></a>

Möglicherweise haben Sie einen Hardware-Engpass wie CPU-Hunger oder maximale Auslastung Ihrer Amazon EBS-Bandbreite. Ziehen Sie in diesen Fällen die Verringerung der Hardware-Engpässe in Betracht. Berücksichtigen Sie die folgenden Aktionen:
+ Skalieren Sie Ihre Instance-Klasse hoch.
+ Optimieren Sie Abfragen, die große Mengen an CPU und Speicher verbrauchen.
+ Ändern Sie Ihre Anwendungslogik.
+ Archiviere deine Daten.

Weitere Informationen zu CPU, Arbeitsspeicher und EBS-Netzwerkbandbreite finden Sie unter [Amazon-RDS-Instance-Typen](https://aws.amazon.com/rds/instance-types/).

### Verwenden eines Verbindungs-Poolers
<a name="wait-event.lw-lock-manager.actions.pooler"></a>

Wenn Ihre Gesamtzahl aktiver Verbindungen die maximale vCPU überschreitet, benötigen mehr Betriebssystemprozesse CPU, als Ihr Instance-Typ unterstützen kann. Ziehen Sie in diesem Fall die Verwendung oder Abstimmung eines Verbindungspool in Betracht. Weitere Informationen über das v CPUs für Ihren Instance-Typ finden Sie unter [Amazon RDS-Instance-Typen](https://aws.amazon.com/rds/instance-types/).

Weitere Informationen zum Verbindungspooling finden Sie in den folgenden Ressourcen:
+ [Amazon RDS-Proxy ](rds-proxy.md)
+ [pgbouncer](http://www.pgbouncer.org/usage.html)
+ [Verbindungspools und Datenquellen](https://www.postgresql.org/docs/7.4/jdbc-datasource.html) in der *PostgreSQL-Dokumentation*

### Durchführen eines Upgrades Ihrer Version von RDS für PostgreSQL
<a name="wait-event.lw-lock-manager.actions.pg-version"></a>

Wenn Ihre aktuelle Version von RDS für PostgreSQL niedriger als 12 ist, aktualisieren Sie auf Version 12 oder höher. Die PostgreSQL-Versionen 12 und höher haben einen verbesserten Partitionsmechanismus. Weitere Informationen zu Version 12 finden Sie in den [Versionshinweisen zu PostgreSQL 12.0]( https://www.postgresql.org/docs/release/12.0/). Weitere Informationen zum Aktualisieren von RDS für PostgreSQL finden Sie unter [Upgrades der DB-Engine von RDS für PostgreSQL](USER_UpgradeDBInstance.PostgreSQL.md).

# LWLock:pg\$1stat\$1statements
<a name="apg-rpg-lwlockpgstat"></a>

Das LWLock Warteereignis:PG\$1STAT\$1STATEMENTS tritt ein, wenn die Erweiterung die Hashtabelle, die SQL-Anweisungen verfolgt, exklusiv sperrt. `pg_stat_statements` Dies passiert in folgenden Szenarien:
+ Wenn die Anzahl der nachverfolgten Anweisungen den konfigurierten `pg_stat_statements.max`-Parameterwert erreicht und Platz für weitere Einträge geschaffen werden muss, sortiert die Erweiterung die Anzahl der Aufrufe, entfernt die 5 % der am wenigsten ausgeführten Anweisungen und füllt den Hash mit den verbleibenden Einträgen neu auf.
+ Wenn `pg_stat_statements` eine `garbage collection`-Operation für die `pgss_query_texts.stat`-Datei auf der Festplatte durchführt und die Datei neu schreibt

**Topics**
+ [Unterstützte Engine-Versionen](#apg-rpg-lwlockpgstat.supported)
+ [Kontext](#apg-rpg-lwlockpgstat.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#apg-rpg-lwlockpgstat.causes)
+ [Aktionen](#apg-rpg-lwlockpgstat.actions)

## Unterstützte Engine-Versionen
<a name="apg-rpg-lwlockpgstat.supported"></a>

 Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt. 

## Kontext
<a name="apg-rpg-lwlockpgstat.context"></a>

**Grundlagen der pg\$1stat\$1statements-Erweiterung** – Die pg\$1stat\$1statements-Erweiterung verfolgt Statistiken zur Ausführung von SQL-Anweisungen in einer Hash-Tabelle nach. Die Erweiterung verfolgt SQL-Anweisungen bis zu dem durch den `pg_stat_statements.max`-Parameter definierten Grenzwert nach. Dieser Parameter bestimmt die maximale Anzahl von Anweisungen, die nachverfolgt werden können, was der maximalen Anzahl von Zeilen in der pg\$1stat\$1statements-Ansicht entspricht.

**Persistenz von Anweisungsstatistiken** – Die Erweiterung behält die Anweisungsstatistiken über Instance-Neustarts hinweg bei, indem sie Folgendes durchführt:
+ Schreiben von Daten in eine Datei mit dem Namen pg\$1stat\$1statements.stat
+ Steuern des Persistenzverhaltens mit dem pg\$1stat\$1statements.save-Parameter

Wenn pg\$1stat\$1statements.save auf Folgendes gesetzt ist:
+ on (Standard): Statistiken werden beim Herunterfahren gespeichert und beim Serverstart neu geladen
+ off: Statistiken werden weder beim Herunterfahren gespeichert noch beim Serverstart neu geladen

**Abfragetextspeicher** – Die Erweiterung speichert den Text nachverfolgter Abfragen in einer Datei mit dem Namen `pgss_query_texts.stat`. Diese Datei kann auf das Doppelte der durchschnittlichen Größe aller nachverfolgten SQL-Anweisungen anwachsen, ehe eine Garbage Collection erfolgt. Die Erweiterung erfordert eine exklusive Hash-Tabellen-Sperre während der Bereinigungsvorgänge und beim Neuschreiben der `pgss_query_texts.stat`-Datei.

**Prozess der Freigabe von Anweisungen** – Wenn die Anzahl der nachverfolgten Anweisungen den `pg_stat_statements.max`-Grenzwert erreicht und neue Anweisungen nachverfolgt werden müssen, führt die Erweiterung Folgendes durch:
+ Erhält eine exklusive Sperre (LWLock:pg\$1stat\$1statements) für die Hashtabelle.
+ Sie lädt vorhandene Daten in den lokalen Speicher.
+ Sie führt eine Schnellsortierung auf der Grundlage der Anzahl der Aufrufe durch.
+ Sie entfernt die am wenigsten aufgerufenen Anweisungen (unterste 5 %).
+ Sie füllt die Hash-Tabelle mit den verbleibenden Einträgen neu auf.

**Überwachung der Anweisungsfreigabe** – In PostgreSQL 14 und höher können Sie die Freigabe von Anweisungen mit der pg\$1stat\$1statements\$1info-Ansicht überwachen. Diese Ansicht enthält eine Freigabe-Spalte, in der angezeigt wird, wie oft Anweisungen freigegeben wurden, um Platz für neue Anweisungen zu schaffen.

Wenn die Freigabe von Anweisungen häufig erfolgt, führt dies zu einer häufigeren Garbage Collection bei der `pgss_query_texts.stat`-Datei auf der Festplatte.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="apg-rpg-lwlockpgstat.causes"></a>

Zu den typischen Ursachen für eine Zunahme bei den `LWLock:pg_stat_statements`-Wartezeiten gehören:
+ eine Zunahme bei der Anzahl eindeutiger Abfragen, die von der Anwendung verwendet werden
+ ein `pg_stat_statements.max`-Parameterwert, der im Vergleich zur Anzahl der verwendeten eindeutigen Abfragen klein ist

## Aktionen
<a name="apg-rpg-lwlockpgstat.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen. Sie können `LWLock:pg_stat_statements`-Ereignisse identifizieren, indem Sie Erkenntnisse zur Amazon-RDS-Leistung verwenden oder die `pg_stat_activity`-Ansicht abfragen.

Passen Sie die folgenden `pg_stat_statements` Parameter an, um das Tracking-Verhalten zu steuern und die Warteereignisse von pg\$1stat\$1-Anweisungen zu reduzieren. LWLock

**Topics**
+ [Deaktivieren des pg\$1stat\$1statements.track-Parameters](#apg-rpg-lwlockpgstat.actions.disabletrack)
+ [Erhöhen des pg\$1stat\$1statements.max-Parameters](#apg-rpg-lwlockpgstat.actions.increasemax)
+ [Deaktivieren des pg\$1stat\$1statements.track\$1utility-Parameters](#apg-rpg-lwlockpgstat.actions.disableutility)

### Deaktivieren des pg\$1stat\$1statements.track-Parameters
<a name="apg-rpg-lwlockpgstat.actions.disabletrack"></a>

Wenn sich das LWLock Warteereignis:pg\$1stat\$1statements negativ auf die Datenbankleistung auswirkt und eine schnelle Lösung erforderlich ist, bevor die Ansicht weiter analysiert wird, um die Ursache `pg_stat_statements` zu ermitteln, kann der Parameter deaktiviert werden, indem er auf gesetzt wird. `pg_stat_statements.track` `none` Dadurch wird die Erfassung von Anweisungsstatistiken deaktiviert.

### Erhöhen des pg\$1stat\$1statements.max-Parameters
<a name="apg-rpg-lwlockpgstat.actions.increasemax"></a>

Erhöhen Sie den Wert des `pg_stat_statements.max`-Parameters, um die Freigabe zu reduzieren und die Garbage Collection für die `pgss_query_texts.stat`-Datei auf der Festplatte zu minimeren. Der Standardwert ist `5,000`.

**Anmerkung**  
Der `pg_stat_statements.max`-Parameter ist statisch. Sie müssen Ihre DB-Instance neu starten, um Änderungen an diesem Parameter zu übernehmen. 

### Deaktivieren des pg\$1stat\$1statements.track\$1utility-Parameters
<a name="apg-rpg-lwlockpgstat.actions.disableutility"></a>

Sie können die pg\$1stat\$1statements-Ansicht analysieren, um festzustellen, welche Dienstprogrammbefehle die meisten Ressourcen verbrauchen, die von `pg_stat_statements` nachverfolgt werden.

Der `pg_stat_statements.track_utility`-Parameter steuert, ob das Modul Dienstprogrammbefehle nachverfolgt, zu denen alle Befehle außer SELECT, INSERT, UPDATE, DELETE und MERGE gehören. Dieser Parameter ist standardmäßig auf `on` festgelegt.

Wenn Ihre Anwendung beispielsweise viele Savepoint-Abfragen verwendet, die von Natur aus eindeutig sind, kann dies die Freigabe von Anweisungen erhöhen. Als Abhilfemaßnahme können Sie den `pg_stat_statements.track_utility`-Parameter deaktivieren, sodass Savepoint-Abfragen nicht mehr von `pg_stat_statements` nachverfolgt werden.

**Anmerkung**  
Der `pg_stat_statements.track_utility`-Parameter ist ein dynamischer Parameter. Sie können dessen Wert ändern, ohne Ihre Datenbank-Instance neu starten zu müssen.

**Example Beispiel für eindeutige Savepoint-Abfragen in pg\$1stat\$1statements**  <a name="savepoint-queries"></a>

```
                     query                       |       queryid       
-------------------------------------------------+---------------------
 SAVEPOINT JDBC_SAVEPOINT_495701                 | -7249565344517699703
 SAVEPOINT JDBC_SAVEPOINT_1320                   | -1572997038849006629
 SAVEPOINT JDBC_SAVEPOINT_26739                  |  54791337410474486
 SAVEPOINT JDBC_SAVEPOINT_1294466                |  8170064357463507593
 ROLLBACK TO SAVEPOINT JDBC_SAVEPOINT_65016      | -33608214779996400
 SAVEPOINT JDBC_SAVEPOINT_14185                  | -2175035613806809562
 SAVEPOINT JDBC_SAVEPOINT_45837                  | -6201592986750645383
 SAVEPOINT JDBC_SAVEPOINT_1324                   |  6388797791882029332
```

PostgreSQL 17 führt mehrere Verbesserungen für die Nachverfolgung von Dienstprogrammbefehlen ein:
+ Savepoint-Namen werden jetzt als Konstanten angezeigt.
+ Die globale Transaktion IDs (GIDs) von zweiphasigen Commit-Befehlen wird jetzt als Konstanten angezeigt.
+ Die Namen von DEALLOCATE-Anweisungen werden als Konstanten angezeigt.
+ CALL-Parameter werden jetzt als Konstanten angezeigt.

# LWLock:subtransSLRU (:) LWLock SubtransControlLock
<a name="wait-event.lwlocksubtransslru"></a>

Die Ereignisse `LWLock:SubtransSLRU` und `LWLock:SubtransBuffer` wait weisen darauf hin, dass eine Sitzung darauf wartet, auf den SLRU-Cache (Simple Least Recently Used) für Subtransaktionsinformationen zuzugreifen. Dies tritt auf, wenn die Sichtbarkeit von Transaktionen und die Beziehungen zwischen übergeordneten und untergeordneten Objekten bestimmt werden.
+ `LWLock:SubtransSLRU`: Ein Prozess wartet darauf, auf den einfachen SLRU-Cache (Least-Recently Used) für eine Subtransaktion zuzugreifen. In RDS für PostgreSQL vor Version 13 wird dieses Warteereignis aufgerufen. `SubtransControlLock`
+ `LWLock:SubtransBuffer`: Ein Prozess wartet I/O auf einen einfachen Puffer, der zuletzt zuletzt verwendet wurde (SLRU) für eine Subtransaktion. In RDS für PostgreSQL vor Version 13 wird dieses Warteereignis aufgerufen. `subtrans`

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.lwlocksubtransslru.supported)
+ [Kontext](#wait-event.lwlocksubtransslru.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.lwlocksubtransslru.causes)
+ [Aktionen](#wait-event.lwlocksubtransslru.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.lwlocksubtransslru.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt.

## Kontext
<a name="wait-event.lwlocksubtransslru.context"></a>

**Subtransaktionen verstehen** — Eine Subtransaktion ist eine Transaktion innerhalb einer Transaktion in PostgreSQL. Sie wird auch als verschachtelte Transaktion bezeichnet.

Untertransaktionen werden normalerweise erstellt, wenn Sie Folgendes verwenden:
+ `SAVEPOINT`-Befehle
+ Ausnahmeblöcke () `BEGIN/EXCEPTION/END`

Mit Untertransaktionen können Sie Teile einer Transaktion rückgängig machen, ohne dass sich dies auf die gesamte Transaktion auswirkt. Auf diese Weise haben Sie eine detaillierte Kontrolle über das Transaktionsmanagement.

**Implementierungsdetails** — PostgreSQL implementiert Subtransaktionen als verschachtelte Strukturen innerhalb von Haupttransaktionen. Jede Subtransaktion erhält ihre eigene Transaktions-ID.

Wichtigste Aspekte der Implementierung:
+ Transaktionen IDs werden nachverfolgt `pg_xact`
+ Beziehungen zwischen Eltern und Kindern werden im `pg_subtrans` Unterverzeichnis unter gespeichert `PGDATA`
+ Jede Datenbanksitzung kann bis zu aktive Untertransaktionen verwalten `64`
+ Eine Überschreitung dieses Limits führt zu einem Überlauf der Subtransaktionen, was den Zugriff auf den SLRU-Cache (Simple Least-Recently Used) für Subtransaktionsinformationen erfordert

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.lwlocksubtransslru.causes"></a>

Zu den häufigsten Ursachen für Konflikte mit der Subtransaktion SLRU gehören:
+ **Übermäßiger Einsatz von SAVEPOINT- und EXCEPTION-Behandlung — PL/pgSQL Prozeduren mit `EXCEPTION` Handlern erstellen automatisch implizite Savepoints, unabhängig davon, ob Ausnahmen** auftreten. Jede initiiert eine neue Subtransaktion. `SAVEPOINT` Wenn eine einzelne Transaktion mehr als 64 Subtransaktionen ansammelt, löst sie einen SLRU-Überlauf für die Subtransaktion aus.
+ **Treiber- und ORM-Konfigurationen** — Die `SAVEPOINT` Verwendung kann explizit im Anwendungscode oder implizit durch Treiberkonfigurationen erfolgen. Viele häufig verwendete ORM-Tools und Anwendungsframeworks unterstützen verschachtelte Transaktionen nativ. Hier sind einige gängige Beispiele:
  + Wenn der JDBC-Treiberparameter `autosave` auf `always` oder gesetzt ist`conservative`, generiert er vor jeder Abfrage Savepoints.
  + Spring Framework-Transaktionsdefinitionen, wenn auf gesetzt. `propagation_nested`
  + Rails, wenn gesetzt `requires_new: true` ist.
  + SQLAlchemy wann `session.begin_nested` wird verwendet.
  + Django, wenn verschachtelte `atomic()` Blöcke verwendet werden.
  + GORM wann `Savepoint` wird verwendet.
  + psqlODBC, wenn die Einstellung der Rollback-Stufe auf Rollback auf Anweisungsebene gesetzt ist (z. B.). `PROTOCOL=7.4-2`
+ **Hohe gleichzeitige Workloads mit lang andauernden Transaktionen und Subtransaktionen — Wenn bei hohen gleichzeitigen Workloads und lang andauernden Transaktionen** und Subtransaktionen ein SLRU-Überlauf der Subtransaktion auftritt, kommt es bei PostgreSQL zu erhöhten Konflikten. Dies äußert `LWLock:SubtransBuffer` sich `LWLock:SubtransSLRU` in erhöhten Wartezeiten und Sperren.

## Aktionen
<a name="wait-event.lwlocksubtransslru.actions"></a>

Abhängig von den Ursachen Ihres Warteereignisses empfehlen wir verschiedene Aktionen. Einige Maßnahmen bieten sofortige Abhilfe, während andere Untersuchungen und langfristige Korrekturen erfordern.

**Topics**
+ [Überwachung der Nutzung von Subtransaktionen](#wait-event.lwlocksubtransslru.actions.monitor)
+ [Konfiguration von Speicherparametern](#wait-event.lwlocksubtransslru.actions.memory)
+ [Langfristige Maßnahmen](#wait-event.lwlocksubtransslru.actions.longterm)

### Überwachung der Nutzung von Subtransaktionen
<a name="wait-event.lwlocksubtransslru.actions.monitor"></a>

Verwenden Sie für PostgreSQL-Versionen 16.1 und höher die folgende Abfrage, um die Anzahl der Subtransaktionen und den Überlaufstatus pro Backend zu überwachen. Diese Abfrage verknüpft Backend-Statistiken mit Aktivitätsinformationen, um zu zeigen, welche Prozesse Subtransaktionen verwenden:

```
SELECT a.pid, usename, query, state, wait_event_type,
       wait_event, subxact_count, subxact_overflowed
FROM (SELECT id, pg_stat_get_backend_pid(id) pid, subxact_count, subxact_overflowed
      FROM pg_stat_get_backend_idset() id
           JOIN LATERAL pg_stat_get_backend_subxact(id) AS s ON true
     ) a
JOIN pg_stat_activity b ON a.pid = b.pid;
```

Überwachen Sie bei PostgreSQL-Versionen 13.3 und höher die `pg_stat_slru` Ansicht auf den Druck des Subtransaktions-Caches. Die folgende SQL-Abfrage ruft SLRU-Cachestatistiken für die Subtrans-Komponente ab:

```
SELECT * FROM pg_stat_slru WHERE name = 'Subtrans';
```

Ein konstant steigender `blks_read` Wert weist auf häufigen Festplattenzugriff für nicht zwischengespeicherte Untertransaktionen hin, was auf eine potenzielle Belastung des SLRU-Caches hindeutet.

### Konfiguration von Speicherparametern
<a name="wait-event.lwlocksubtransslru.actions.memory"></a>

Für PostgreSQL 17.1 und höher können Sie die Größe des SLRU-Caches der Subtransaktion mithilfe des Parameters konfigurieren. `subtransaction_buffers` Das folgende Konfigurationsbeispiel zeigt, wie der Parameter für den Subtransaktionspuffer festgelegt wird:

```
subtransaction_buffers = 128
```

Dieser Parameter gibt die Menge an gemeinsam genutztem Speicher an, die zum Zwischenspeichern von Subtransaktionsinhalten () `pg_subtrans` verwendet wird. Wenn der Wert ohne Einheiten angegeben wird, steht er für `BLCKSZ` Byteblöcke, in der Regel jeweils 8 KB. Wenn Sie den Wert beispielsweise auf 128 setzen, wird 1 MB (128 \$1 8 KB) Speicher für den Subtransaktions-Cache zugewiesen.

**Anmerkung**  
Sie können diesen Parameter auf Clusterebene festlegen, sodass alle Instanzen konsistent bleiben. Testen Sie den Wert und passen Sie ihn an Ihre spezifischen Workload-Anforderungen und Ihre Instance-Klasse an. Sie müssen die Writer-Instanz neu starten, damit die Parameteränderungen wirksam werden.

### Langfristige Maßnahmen
<a name="wait-event.lwlocksubtransslru.actions.longterm"></a>
+ **Überprüfen Sie den Anwendungscode und die Konfigurationen** — Überprüfen Sie Ihren Anwendungscode und Ihre Datenbanktreiberkonfigurationen auf explizite und implizite Verwendung sowie auf die `SAVEPOINT` Verwendung von Untertransaktionen im Allgemeinen. Identifizieren Sie Transaktionen, die potenziell über 64 Untertransaktionen generieren.
+ **Reduzieren Sie die Nutzung von Savepoints** — Minimieren Sie die Verwendung von Savepoints in Ihren Transaktionen:
  + Überprüfen Sie PL/pgSQL Verfahren und Funktionen mit EXCEPTION-Blöcken. EXCEPTION-Blöcke erstellen automatisch implizite Savepoints, die zu einem Überlauf von Subtransaktionen beitragen können. Jede EXCEPTION-Klausel erstellt eine Untertransaktion, unabhängig davon, ob während der Ausführung tatsächlich eine Ausnahme auftritt.  
**Example**  

    Beispiel 1: Problematische Verwendung von EXCEPTION-Blocks

    Das folgende Codebeispiel zeigt die problematische Verwendung von EXCEPTION-Blocks, die mehrere Untertransaktionen erzeugt:

    ```
    CREATE OR REPLACE FUNCTION process_user_data()
    RETURNS void AS $$
    DECLARE
        user_record RECORD;
    BEGIN
        FOR user_record IN SELECT * FROM users LOOP
            BEGIN
                -- This creates a subtransaction for each iteration
                INSERT INTO user_audit (user_id, action, timestamp)
                VALUES (user_record.id, 'processed', NOW());
                
                UPDATE users 
                SET last_processed = NOW() 
                WHERE id = user_record.id;
                
            EXCEPTION
                WHEN unique_violation THEN
                    -- Handle duplicate audit entries
                    UPDATE user_audit 
                    SET timestamp = NOW() 
                    WHERE user_id = user_record.id AND action = 'processed';
            END;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    ```

    Das folgende verbesserte Codebeispiel reduziert die Nutzung von Subtransaktionen, indem UPSERT anstelle der Ausnahmebehandlung verwendet wird:

    ```
    CREATE OR REPLACE FUNCTION process_user_data()
    RETURNS void AS $$
    DECLARE
        user_record RECORD;
    BEGIN
        FOR user_record IN SELECT * FROM users LOOP
            -- Use UPSERT to avoid exception handling
            INSERT INTO user_audit (user_id, action, timestamp)
            VALUES (user_record.id, 'processed', NOW())
            ON CONFLICT (user_id, action) 
            DO UPDATE SET timestamp = NOW();
            
            UPDATE users 
            SET last_processed = NOW() 
            WHERE id = user_record.id;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    ```  
**Example**  

    Beispiel 2: STRICT-Ausnahmebehandler

    Das folgende Codebeispiel zeigt die problematische EXCEPTION-Behandlung mit NO\$1DATA\$1FOUND:

    ```
    CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER)
    RETURNS TEXT AS $$
    DECLARE
        user_email TEXT;
    BEGIN
        BEGIN
            -- STRICT causes an exception if no rows or multiple rows found
            SELECT email INTO STRICT user_email 
            FROM users 
            WHERE id = p_user_id;
            
            RETURN user_email;
            
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                RETURN 'Email not found';
        END;
    END;
    $$ LANGUAGE plpgsql;
    ```

    Das folgende verbesserte Codebeispiel vermeidet Untertransaktionen, indem IF NOT FOUND anstelle der Ausnahmebehandlung verwendet wird:

    ```
    CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER)
    RETURNS TEXT AS $$
    DECLARE
        user_email TEXT;
    BEGIN
         SELECT email INTO user_email 
         FROM users 
         WHERE id = p_user_id;
            
         IF NOT FOUND THEN
             RETURN 'Email not found';
         ELSE
             RETURN user_email;
         END IF;
    END;
    $$ LANGUAGE plpgsql;
    ```
  + JDBC-Treiber — Wenn der `autosave` Parameter auf `always` oder gesetzt ist`conservative`, generiert er vor jeder Abfrage Savepoints. Prüfen Sie, ob die `never` Einstellung für Ihre Anwendung akzeptabel wäre.
  + PostgreSQL ODBC-Treiber (psqlODBC) — Die Rollback-Level-Einstellung (für Rollback auf Anweisungsebene) erstellt implizite Savepoints, um die Rollback-Funktionalität für Anweisungen zu aktivieren. Prüfen Sie, ob ein Rollback auf Transaktionsebene oder kein Rollback für Ihre Anwendung akzeptabel wäre. 
  + Untersuchen Sie ORM-Transaktionskonfigur
  + Erwägen Sie alternative Strategien zur Fehlerbehandlung, für die keine Savepoints erforderlich sind
+ **Optimieren Sie das Transaktionsdesign** — Strukturieren Sie Transaktionen neu, um übermäßige Verschachtelungen zu vermeiden und die Wahrscheinlichkeit eines Überlaufs von Subtransaktionen zu verringern.
+ **Reduzierung lang andauernder Transaktionen — Langfristige Transaktionen** können Probleme mit Subtransaktionen verschärfen, da sie die Informationen zu Subtransaktionen länger speichern. Überwachen Sie Performance Insights Insights-Metriken und konfigurieren Sie den `idle_in_transaction_session_timeout` Parameter so, dass inaktive Transaktionen automatisch beendet werden.
+ Performance Insights Insights-Metriken überwachen — Verfolgen Sie Metriken wie `idle_in_transaction_count` (Anzahl der inaktiven Sitzungen im Transaktionsstatus) und `idle_in_transaction_max_time` (Dauer der am längsten laufenden inaktiven Transaktion), um Transaktionen mit langer Laufzeit zu erkennen.
+ Konfigurieren `idle_in_transaction_session_timeout` — Stellen Sie diesen Parameter in Ihrer Parametergruppe so ein, dass inaktive Transaktionen nach einer bestimmten Dauer automatisch beendet werden.
+ Proaktive Überwachung — Überwachen Sie häufig auftretende Ereignisse `LWLock:SubtransBuffer` und `LWLock:SubtransSLRU` warten Sie, bis Konflikte im Zusammenhang mit Untertransaktionen erkannt werden, bevor sie kritisch werden.

# Timeout:PgSleep
<a name="wait-event.timeoutpgsleep"></a>

Das `Timeout:PgSleep`-Ereignis tritt ein, wenn ein Serverprozess die `pg_sleep`-Funktion aufgerufen hat und auf das Ablaufen des Sleep-Timeouts wartet.

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.timeoutpgsleep.context.supported)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.timeoutpgsleep.causes)
+ [Aktionen](#wait-event.timeoutpgsleep.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.timeoutpgsleep.context.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt.

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.timeoutpgsleep.causes"></a>

Dieses Wait-Ereignis tritt auf, wenn eine Anwendung, eine gespeicherte Funktion oder ein Benutzer eine SQL-Anweisung ausgibt, die eine der folgenden Funktionen aufruft:
+ `pg_sleep`
+ `pg_sleep_for`
+ `pg_sleep_until`

Die vorhergehenden Funktionen verzögern die Ausführung, bis die angegebene Anzahl von Sekunden verstrichen ist. Beispielsweise pausiert `SELECT pg_sleep(1)` für 1 Sekunde. Weitere Informationen finden Sie unter [Ausführung verzögern](https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-DELAY) in der PostgreSQL-Dokumentation.

## Aktionen
<a name="wait-event.timeoutpgsleep.actions"></a>

Identifizieren Sie die Anweisung, die die `pg_sleep`-Funktion ausgeführt hat. Überprüfen Sie, ob die Verwendung der Funktion angemessen ist.

# Timeout:VacuumDelay
<a name="wait-event.timeoutvacuumdelay"></a>

Das `Timeout:VacuumDelay`-Ereignis weist darauf hin, dass das Kostenlimit für Bereinigungs-I/O überschritten wurde und dass der Bereinigungsprozess in den Ruhezustand versetzt wurde. Bereinigungsoperationen werden für die im jeweiligen Kostenverzögerungsparameter angegebene Dauer unterbrochen und setzen ihren Betrieb danach fort. Für den manuellen Bereinigungsbefehl ist die Verzögerung im `vacuum_cost_delay`-Parameter angegeben. Für den Selbstbereinigungs-Daemon ist die Verzögerung im Parameter `autovacuum_vacuum_cost_delay parameter.` festgelegt. 

**Topics**
+ [Unterstützte Engine-Versionen](#wait-event.timeoutvacuumdelay.context.supported)
+ [Kontext](#wait-event.timeoutvacuumdelay.context)
+ [Wahrscheinliche Ursachen für erhöhte Wartezeiten](#wait-event.timeoutvacuumdelay.causes)
+ [Aktionen](#wait-event.timeoutvacuumdelay.actions)

## Unterstützte Engine-Versionen
<a name="wait-event.timeoutvacuumdelay.context.supported"></a>

Diese Warteereignisinformationen werden für alle Versionen von RDS für PostgreSQL unterstützt.

## Kontext
<a name="wait-event.timeoutvacuumdelay.context"></a>

PostgreSQL verfügt sowohl über einen Selbstbereinigungs-Daemon als auch über einen manuellen Bereinigungsbefehl. Der Selbstbereinigungsprozess ist für DB-Instances von RDS für PostgreSQL standardmäßig aktiviert. Der manuelle Bereinigungsbefehl wird je nach Bedarf verwendet, um beispielsweise Tabellen von toten Tupeln zu bereinigen oder neue Statistiken zu generieren.

Während des Bereinigungsvorgangs verwendet PostgreSQL einen internen Zähler, um die geschätzten Kosten zu verfolgen, während das System verschiedene I/O-Operationen durchführt. Wenn der Zähler den im Kostenlimitparameter angegebenen Wert erreicht, hält der Prozess, der den Vorgang ausführt, für die kurze Dauer an, die im Kostenverzögerungsparameter angegeben ist. Dann setzt er den Zähler zurück und den Betrieb fort. 

Der Bereinigungsprozess verfügt über Parameter, mit denen der Ressourcenverbrauch reguliert werden kann. Die Selbstbereinigung und der manuelle Bereinigungsbefehl haben jeweils eigene Parameter zur Einstellung des Kostenlimits. Sie haben auch jeweils eigene Parameter, um eine Kostenverzögerung festzulegen, d. h. eine Zeitspanne, in der die Bereinigung in den Ruhezustand versetzt wird, wenn das Limit erreicht ist. Auf diese Weise fungiert der Kostenverzögerungsparameter als Drosselungsmechanismus für den Ressourcenverbrauch. Die Beschreibung dieser Parameter finden Sie in den folgenden Listen. 

**Parameter, die die Drosselung des Selbstbereinigungs-Daemons beeinflussen**
+ `[autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)` – Gibt den Kostenlimitwert an, der bei Selbstbereinigungsoperationen verwendet werden soll. Wenn Sie die Einstellung für diesen Parameter erhöhen, kann der Bereinigungsprozess mehr Ressourcen verbrauchen und das `Timeout:VacuumDelay`-Warteereignis wird verringert. 
+ `[autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)` – Gibt den Kostenverzögerungswert an, der bei Selbstbereinigungsoperationen verwendet werden soll. Der Standardwert ist 2 Millisekunden. Wenn Sie den Verzögerungsparameter auf 0 festlegen, wird der Drosselungsmechanismus deaktiviert, sodass das `Timeout:VacuumDelay`-Warteereignis nicht angezeigt wird. 

Weitere Informationen finden Sie unter [Selbstbereinigung](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY) in der PostgreSQL-Dokumentation.

**Parameter, die die Drosselung des manuellen Bereinigungsprozesses beeinflussen**
+ `vacuum_cost_limit` – Die Schwelle, bei der der Bereinigungsvorgang in den Ruhezustand versetzt wird. In der Standardeinstellung ist das Limit 200. Diese Zahl steht für die kumulierten Kostenschätzungen für zusätzliche I/O, die von verschiedenen Ressourcen benötigt werden. Wenn Sie diesen Wert erhöhen, verringert sich die Anzahl der `Timeout:VacuumDelay`-Warteereignisse. 
+ `vacuum_cost_delay` – Die Zeitspanne, die der Bereinigungsprozess ruht, wenn das Bereinigungskostenlimit erreicht ist. Die Standardeinstellung ist 0, was bedeutet, dass diese Funktion deaktiviert ist. Sie können diese Einstellung auf einen ganzzahligen Wert festlegen, um die Anzahl der Millisekunden anzugeben und damit diese Funktion zu aktivieren. Wir empfehlen jedoch, die Standardeinstellung beizubehalten.

Weitere Informationen zum `vacuum_cost_delay`-Parameter finden Sie unter [Ressourcennutzung](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST) in der PostgreSQL-Dokumentation. 

Weitere Informationen zur Konfiguration und Verwendung der Selbstbereinigung mit RDS für PostgreSQL finden Sie unter [Arbeiten mit der PostgreSQL-Selbstbereinigung in Amazon RDS für PostgreSQL ](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md). 

## Wahrscheinliche Ursachen für erhöhte Wartezeiten
<a name="wait-event.timeoutvacuumdelay.causes"></a>

Die `Timeout:VacuumDelay` wird durch das Gleichgewicht zwischen Kostenlimitparametern (`vacuum_cost_limit`, `autovacuum_vacuum_cost_limit`) und Kostenverzögerungsparametern (`vacuum_cost_delay`, `autovacuum_vacuum_cost_delay`) beeinflusst, die die Dauer des Ruhezustands des Bereinigungsprozesses steuern. Durch die Erhöhung eines Parameterwerts für das Kostenlimit können mehr Ressourcen vom Bereinigungsprozess verbraucht werden, bevor er in den Ruhezustand versetzt wird. Das führt zu weniger `Timeout:VacuumDelay`-Warteereignissen. Wenn Sie einen der Verzögerungsparameter erhöhen, tritt das `Timeout:VacuumDelay`-Warteereignis häufiger und für längere Zeiträume auf. 

Die `autovacuum_max_workers`-Parametereinstellung kann auch die Anzahl der `Timeout:VacuumDelay` erhöhen. Jeder zusätzliche Selbstbereinigungs-Worker-Prozess trägt zum internen Zählermechanismus bei, sodass das Limit schneller erreicht werden kann als mit einem einzelnen Selbstbereinigungs-Worker-Prozess. Da das Kostenlimit schneller erreicht wird, tritt die Kostenverzögerung häufiger in Kraft, was zu mehr`Timeout:VacuumDelay`-Warteereignissen führt. Weitere Informationen finden Sie unter [autovacuum\$1max\$1workers](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS) in der PostgreSQL-Dokumentation.

Große Objekte, z. B. 500 GB oder mehr, lösen dieses Warteereignis ebenfalls aus, da es einige Zeit dauern kann, bis der Bereinigungsprozess die Verarbeitung großer Objekte abgeschlossen hat.

## Aktionen
<a name="wait-event.timeoutvacuumdelay.actions"></a>

Wenn die Bereinigungsoperationen wie erwartet abgeschlossen werden, ist keine Abhilfe erforderlich. Mit anderen Worten, dieses Warteereignis weist nicht zwingend auf ein Problem hin. Es gibt an, dass der Bereinigungsprozess für den im Verzögerungsparameter angegebenen Zeitraum in den Ruhezustand versetzt wird, sodass Ressourcen für andere Prozesse verwendet werden können, die abgeschlossen werden müssen. 

Wenn Sie möchten, dass Bereinigungsoperationen schneller abgeschlossen werden, können Sie die Verzögerungsparameter niedriger ansetzen. Dadurch wird die Ruhezeit des Bereinigungsprozesses verkürzt. 