

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Réglage avec les événements d'attente pour RDS for PostgreSQL
<a name="PostgreSQL.Tuning"></a>

Les événements d'attente constituent un outil de réglage important pour RDS for PostgreSQL. Lorsque vous parvenez à déterminer pourquoi les sessions sont en attente de ressources et ce qu’elles font, vous êtes mieux à même de réduire les goulets d’étranglement. Vous pouvez utiliser les informations de cette section pour déterminer les causes possibles et les actions correctives à mettre en œuvre. Cette section décrit également les concepts de base du réglage de PostgreSQL.

Les événements d'attente présentés dans cette section sont spécifiques à RDS for PostgreSQL.

**Topics**
+ [

# Concepts essentiels à connaître pour le réglage de RDS for PostgreSQL
](PostgreSQL.Tuning.concepts.md)
+ [

# Événements d'attente RDS for PostgreSQL
](PostgreSQL.Tuning.concepts.summary.md)
+ [

# Cliente : ClientRead
](wait-event.clientread.md)
+ [

# Cliente : ClientWrite
](wait-event.clientwrite.md)
+ [

# CPU
](wait-event.cpu.md)
+ [

# IO : BufFileRead et IO : BufFileWrite
](wait-event.iobuffile.md)
+ [

# IO : DataFileRead
](wait-event.iodatafileread.md)
+ [

# IO:WALWrite
](wait-event.iowalwrite.md)
+ [

# IPC:parallel wait events
](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)

# Concepts essentiels à connaître pour le réglage de RDS for PostgreSQL
<a name="PostgreSQL.Tuning.concepts"></a>

Avant de procéder au réglage de votre base de données RDS for PostgreSQL, découvrez ce que sont les événements d'attente et pourquoi ils se produisent. Examinez également l'architecture de base de RDS for PostgreSQL en termes de mémoire et de disque. Un diagramme d'architecture très utile est disponible dans le wikibook [PostgreSQL](https://en.wikibooks.org/wiki/PostgreSQL/Architecture).

**Topics**
+ [

# Événements d'attente RDS for PostgreSQL
](PostgreSQL.Tuning.concepts.waits.md)
+ [

# Mémoire RDS pour PostgreSQL
](PostgreSQL.Tuning.concepts.memory.md)
+ [

# Processus RDS for PostgreSQL
](PostgreSQL.Tuning.concepts.processes.md)

# Événements d'attente RDS for PostgreSQL
<a name="PostgreSQL.Tuning.concepts.waits"></a>

Un *événement d'attente* indique que la session est en attente d'une ressource. Par exemple, l'événement d'attente `Client:ClientRead` se produit quand RDS for PostgreSQL attend de recevoir des données du client. Les sessions attendent généralement des ressources telles que les suivantes.
+ Accès monothread à une mémoire tampon, par exemple lorsqu'une session tente de modifier une mémoire tampon
+ Ligne verrouillée par une autre session
+ Lecture d'un fichier de données
+ Écriture de fichier journal

Par exemple, pour répondre à une requête, la session peut effectuer une analyse complète de la table. Si les données ne sont pas déjà en mémoire, la session attend la fin des opérations d'I/O disque. Lorsque les mémoires tampons sont lues en mémoire, la session peut être contrainte d'attendre parce que d'autres sessions accèdent aux mêmes mémoires tampons. La base de données enregistre les attentes à l'aide d'un événement d'attente prédéfini. Ces événements sont regroupés en catégories.

En soi, un événement d'attente individuel n'indique pas un problème de performances. Par exemple, si les données demandées ne sont pas en mémoire, il est nécessaire de les lire sur le disque. Si une session verrouille une ligne pour une mise à jour, une autre session attend que la ligne soit déverrouillée pour pouvoir la mettre à jour. Une validation nécessite d'attendre la fin de l'écriture dans un fichier journal. Les attentes font partie intégrante du fonctionnement normal d'une base de données. 

D'un autre côté, un grand nombre d'événements d'attente indiquent généralement un problème de performances. Dans ce cas, vous pouvez utiliser les données des événements d'attente pour déterminer où les sessions passent du temps. Par exemple, si plusieurs heures sont désormais nécessaires à l'exécution d'un rapport qui ne prend habituellement que quelques minutes, vous pouvez identifier les événements d'attente qui contribuent le plus au temps d'attente total. La détermination des causes des principaux événements d'attente peut vous permettre d'apporter des modifications qui auront pour effet d'améliorer les performances. Par exemple, si votre session est en attente sur une ligne qui a été verrouillée par une autre session, vous pouvez mettre fin à la session à l'origine du verrouillage. 

# Mémoire RDS pour PostgreSQL
<a name="PostgreSQL.Tuning.concepts.memory"></a>

La mémoire RDS pour PostgreSQL se décompose en deux parties : la mémoire partagée et la mémoire locale.

**Topics**
+ [

## Mémoire partagée dans RDS pour PostgreSQL
](#PostgreSQL.Tuning.concepts.shared)
+ [

## Mémoire locale dans RDS pour PostgreSQL
](#PostgreSQL.Tuning.concepts.local)

## Mémoire partagée dans RDS pour PostgreSQL
<a name="PostgreSQL.Tuning.concepts.shared"></a>

RDS pour PostgreSQL alloue de la mémoire partagée au démarrage de l’instance. La mémoire partagée se décompose en sous-zones. Les sections suivantes décrivent les principales.

**Topics**
+ [

### Mémoires tampons partagées
](#PostgreSQL.Tuning.concepts.buffer-pool)
+ [

### Mémoires tampons WAL (Write-Ahead Log)
](#PostgreSQL.Tuning.concepts.WAL)

### Mémoires tampons partagées
<a name="PostgreSQL.Tuning.concepts.buffer-pool"></a>

Le *groupe de mémoires tampons partagées* est une zone de mémoire RDS pour PostgreSQL qui contient toutes les pages actuellement ou précédemment utilisées par les connexions d’applications. Une *page* correspond à la version mémoire d'un bloc de disque. Le groupe de mémoires tampons partagées met en cache les blocs de données lus sur le disque. Le groupe réduit la nécessité de relire les données à partir du disque, ce qui améliore l'efficacité de la base de données.

Chaque table et chaque index est stocké sous la forme d'un tableau de pages de taille fixe. Chaque bloc contient plusieurs tuples, qui correspondent à des lignes. Un tuple peut être stocké sur n'importe quelle page.

Le groupe de mémoires tampons partagées dispose d'une mémoire limitée. Si une nouvelle demande requiert une page qui n’est pas en mémoire, et qu’il n’y a plus de mémoire disponible, RDS pour PostgreSQL expulse une page moins fréquemment utilisée pour répondre à la demande. La politique d'expulsion est implémentée par un algorithme de balayage horaire.

Le paramètre `shared_buffers` détermine la quantité de mémoire que le serveur consacre à la mise en cache des données. La valeur par défaut est définie sur `{DBInstanceClassMemory/32768}` octets, en fonction de la mémoire disponible pour l’instance de base de données.

### Mémoires tampons WAL (Write-Ahead Log)
<a name="PostgreSQL.Tuning.concepts.WAL"></a>

Une *mémoire tampon WAL (Write-Ahead Log)* contient des données de transaction que RDS pour PostgreSQL écrit ultérieurement sur un stockage permanent. Le mécanisme WAL permet à RDS pour PostgreSQL d’effectuer les opérations suivantes :
+ Récupérer des données après une défaillance
+ Réduisez le disque I/O en évitant les écritures fréquentes sur le disque

Quand un client modifie des données, RDS pour PostgreSQL écrit les modifications dans la mémoire tampon WAL. Lorsque le client émet une commande `COMMIT`, le processus d'écriture WAL écrit les données de transaction dans le fichier WAL.

Le paramètre `wal_level` détermine la quantité d’informations écrites dans la mémoire tampon WAL, les valeurs possibles étant par exemple `minimal`, `replica` et `logical`.

## Mémoire locale dans RDS pour PostgreSQL
<a name="PostgreSQL.Tuning.concepts.local"></a>

Chaque processus dorsal alloue de la mémoire locale pour le traitement des requêtes.

**Topics**
+ [

### Zone de mémoire de travail
](#PostgreSQL.Tuning.concepts.local.work_mem)
+ [

### Zone de mémoire des travaux de maintenance
](#PostgreSQL.Tuning.concepts.local.maintenance_work_mem)
+ [

### Zone de mémoire tampon temporaire
](#PostgreSQL.Tuning.concepts.temp)

### Zone de mémoire de travail
<a name="PostgreSQL.Tuning.concepts.local.work_mem"></a>

La *zone de mémoire de travail* contient des données temporaires pour les requêtes qui effectuent des opérations de tri et de hachage. Par exemple, une requête contenant une clause `ORDER BY` effectue un tri. Les requêtes utilisent des tables de hachage dans les jointures de hachage et les agrégations.

Le paramètre `work_mem` indique la quantité de mémoire à utiliser par les tables de hachage et les opérations de tri internes avant d’écrire dans des fichiers disque temporaires, mesurée en mégaoctets. La valeur par défaut est de 4 Mo. Plusieurs sessions peuvent s'exécuter simultanément et chacune peut exécuter des opérations de maintenance en parallèle. La mémoire de travail totale utilisée peut donc être un multiple du paramètre `work_mem`. 

### Zone de mémoire des travaux de maintenance
<a name="PostgreSQL.Tuning.concepts.local.maintenance_work_mem"></a>

La *zone de mémoire des travaux de maintenance* met les données en cache pour les opérations de maintenance. Ces opérations incluent l'opération VACUUM, la création d'un index et l'ajout de clés étrangères.

Le paramètre `maintenance_work_mem` spécifie la quantité maximale de mémoire à utiliser par les opérations de maintenance, mesurée en mégaoctets. La valeur par défaut est de 64 Mo. Une session de base de données ne peut exécuter qu'une seule opération de maintenance à la fois.

### Zone de mémoire tampon temporaire
<a name="PostgreSQL.Tuning.concepts.temp"></a>

La *zone de mémoire tampon temporaire* met en cache les tables temporaires pour chaque session de base de données.

Chaque session alloue des mémoires tampons temporaires en fonction des besoins jusqu'à la limite que vous spécifiez. Lorsque la session se termine, le serveur efface le contenu des mémoires tampons.

Le paramètre `temp_buffers` définit le nombre maximal de mémoires tampons temporaires utilisées par chaque session, mesuré en mégaoctets. La valeur par défaut est de 8 Mo. Avant la première utilisation de tables temporaires au sein d'une session, vous pouvez modifier la valeur `temp_buffers`.

# Processus RDS for PostgreSQL
<a name="PostgreSQL.Tuning.concepts.processes"></a>

RDS for PostgreSQL utilise plusieurs processus.

**Topics**
+ [

## Processus postmaster
](#PostgreSQL.Tuning.concepts.postmaster)
+ [

## Processus backend
](#PostgreSQL.Tuning.concepts.backend)
+ [

## Processus d'arrière-plan
](#PostgreSQL.Tuning.concepts.vacuum)

## Processus postmaster
<a name="PostgreSQL.Tuning.concepts.postmaster"></a>

Le *processus postmaster* est le premier qui est lancé lorsque vous démarrez RDS for PostgreSQL. Les principales responsabilités du processus postmaster sont les suivantes :
+ Créer et surveiller les processus d'arrière-plan
+ Recevoir les requêtes d'authentification des processus clients, et les authentifier avant d'autoriser la base de données à traiter les requêtes

## Processus backend
<a name="PostgreSQL.Tuning.concepts.backend"></a>

Si le processus postmaster authentifie une requête client, il crée un nouveau processus backend, également appelé processus postgres. Un processus client se connecte à un seul processus backend. Le processus client et le processus backend communiquent directement sans intervention du processus postmaster.

## Processus d'arrière-plan
<a name="PostgreSQL.Tuning.concepts.vacuum"></a>

Le processus postmaster crée plusieurs processus qui effectuent différentes tâches backend. Les plus importants sont les suivants :
+ Dispositif d'écriture WAL

  RDS for PostgreSQL écrit les données contenues dans la mémoire tampon WAL (Write-Ahead Log) dans les fichiers journaux. Le principe de l'approche WAL est que la base de données ne peut pas écrire les modifications dans les fichiers de données tant que la base de données n'a pas écrit les enregistrements de journal décrivant ces modifications sur le disque. Le mécanisme WAL réduit les E/S disque et permet à RDS for PostgreSQL d'utiliser les journaux pour restaurer la base de données après une défaillance.
+ Dispositif d'écriture d'arrière-plan

  Ce processus écrit périodiquement les pages modifiées des mémoires tampons vers les fichiers de données. Une page est considérée comme modifiée lorsqu'un processus backend la modifie en mémoire.
+ Démon autovacuum

  Le démon est composé des éléments suivants :
  + Le lanceur autovacuum
  + Les processus employés autovacuum

  Lorsque la fonction autovacuum est activée, elle recherche les tables dans lesquelles un grand nombre de tuples ont été insérés, mis à jour ou supprimés. Les responsabilités du démon sont les suivantes :
  + Récupérer ou réutiliser l'espace disque occupé par les lignes mises à jour ou supprimées
  + Mettre à jour les statistiques utilisées par le planificateur
  + Protéger contre la perte d'anciennes données en raison du renvoi à la ligne de l'ID de transaction

  La fonction autovacuum automatise l'exécution des commandes `VACUUM` et `ANALYZE`. `VACUUM`présente les variantes suivantes : standard et complet. La variante standard s'exécute parallèlement à d'autres opérations de base de données. `VACUUM FULL` requiert un verrou exclusif sur la table sur laquelle il travaille. Il ne peut donc pas être exécuté en parallèle avec des opérations qui accèdent à la même table. `VACUUM`crée un I/O trafic important, ce qui peut nuire aux performances des autres sessions actives.

# Événements d'attente RDS for PostgreSQL
<a name="PostgreSQL.Tuning.concepts.summary"></a>

Le tableau suivant répertorie les événements d'attente liés à RDS for PostgreSQL, qui révèlent souvent des problèmes de performances, et résume leurs causes et les actions correctives les plus courantes.


| Événement d'attente | Définition | 
| --- | --- | 
|  [Cliente : ClientRead](wait-event.clientread.md)  |  Cet événement se produit quand RDS for PostgreSQL attend de recevoir des données du client.  | 
|  [Cliente : ClientWrite](wait-event.clientwrite.md)  |  Cet événement se produit quand RDS for PostgreSQL attend d'écrire des données sur le client.  | 
|  [CPU](wait-event.cpu.md)  | Cet événement se produit lorsqu'un thread est actif dans l'UC ou qu'il est en attente d'UC.  | 
|  [IO : BufFileRead et IO : BufFileWrite](wait-event.iobuffile.md)  |  Ces événements se produisent quand RDS for PostgreSQL crée des fichiers temporaires.  | 
|  [IO : DataFileRead](wait-event.iodatafileread.md)  |  Cet événement se produit lorsqu'une connexion attend qu'un processus backend lise une page requise à partir du stockage parce que la page n'est pas disponible dans la mémoire partagée.   | 
| [IO:WALWrite](wait-event.iowalwrite.md)  | Cet événement indique quand RDS for PostgreSQL est en attente de l'écriture des tampons de journal d'écriture anticipée (WAL) dans un fichier WAL.  | 
|  [Lock:advisory](wait-event.lockadvisory.md)  |  Cet événement se produit lorsqu'une application PostgreSQL utilise un verrou pour coordonner l'activité sur plusieurs sessions.  | 
|  [Lock:extend](wait-event.lockextend.md) |  Cet événement se produit lorsqu'un processus backend attend de verrouiller une relation pour l'étendre alors qu'un autre processus présente un verrou sur cette relation dans le même but.  | 
|  [Lock:Relation](wait-event.lockrelation.md)  |  Cet événement se produit lorsqu'une requête attend d'acquérir un verrou sur une table ou une vue actuellement verrouillée par une autre transaction.  | 
|  [Lock:transactionid](wait-event.locktransactionid.md)  | Cet événement se produit lorsqu'une transaction attend un verrou de niveau ligne. | 
|  [Lock:tuple](wait-event.locktuple.md)  |  Cet événement se produit lorsqu'un processus backend attend d'acquérir un verrou sur un tuple.  | 
|  [LWLock: BufferMapping (:buffer\$1mapping) LWLock](wait-event.lwl-buffer-mapping.md)  |  Cet événement se produit lorsqu'une session attend d'associer un bloc de données à une mémoire tampon dans le groupe de mémoires tampons partagées.  | 
|  [LWLock:BufferIO (IPC:BufferIO)](wait-event.lwlockbufferio.md)  |  Cet événement se produit lorsque RDS pour PostgreSQL attend que d'autres processus input/output terminent leurs opérations (E/S) lorsqu'ils tentent simultanément d'accéder à une page.  | 
|  [LWLock:buffer\$1content (BufferContent)](wait-event.lwlockbuffercontent.md)  |  Cet événement se produit lorsqu'une session attend de lire ou d'écrire une page de données en mémoire alors que celle-ci est verrouillée en écriture dans une autre session.  | 
|  [LWLock:lock\$1manager (:lockmanager) LWLock](wait-event.lw-lock-manager.md)  | Cet événement se produit lorsque le moteur RDS for PostgreSQL conserve la zone de mémoire du verrou partagé pour allouer, vérifier et libérer un verrou quand il est impossible d'utiliser un verrou à chemin d'accès rapide. | 
|  [LWLock:SubTransSLRU (:) LWLock SubtransControlLock](wait-event.lwlocksubtransslru.md)  |  Cet événement se produit lorsqu'un processus attend d'accéder au cache simple le moins récemment utilisé (SLRU) pour une sous-transaction.  | 
|  [Timeout:PgSleep](wait-event.timeoutpgsleep.md)  |  Cet événement se produit lorsqu'un processus serveur a appelé la fonction `pg_sleep` et attend l'expiration du délai de mise en veille.   | 
|  [Timeout:VacuumDelay](wait-event.timeoutvacuumdelay.md)  | Cet événement indique que le processus vacuum est en veille car la limite de coût estimée a été atteinte.  | 

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

L’événement `Client:ClientRead` se produit quand RDS pour PostgreSQL attend de recevoir des données du client.

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.clientread.context.supported)
+ [

## Contexte
](#wait-event.clientread.context)
+ [

## Causes probables de l’augmentation du nombre d’événements d’attente
](#wait-event.clientread.causes)
+ [

## Actions
](#wait-event.clientread.actions)

## Versions de moteur prises en charge
<a name="wait-event.clientread.context.supported"></a>

Ces informations sur les événements d’attente sont prises en charge pour RDS pour PostgreSQL versions 10 et ultérieures.

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

Une instance de base de données RDS pour PostgreSQL attend de recevoir des données du client. L’instance de base de données RDS pour PostgreSQL doit recevoir les données du client avant de pouvoir envoyer plus de données au client. La période pendant laquelle l'instance attend avant de recevoir les données du client est un événement `Client:ClientRead`.

## Causes probables de l’augmentation du nombre d’événements d’attente
<a name="wait-event.clientread.causes"></a>

Les principales causes de l’événement d’attente `Client:ClientRead` sont les suivantes : 

**Latence réseau accrue**  
La latence réseau peut être accrue entre l’instance de base de données RDS pour PostgreSQL et le client. Une latence réseau plus élevée augmente le temps de réception des données du client par l'instance de base de données.

**Charge accrue sur le client**  
Le client peut être soumis à une pression exercée sur l’UC ou à une saturation du réseau. Une augmentation de la charge sur le client peut retarder la transmission des données du client vers l’instance de base de données RDS pour PostgreSQL.

**Nombre excessif d’allers-retours réseau**  
Un grand nombre d’allers-retours réseau entre l’instance de base de données RDS pour PostgreSQL et le client peut retarder la transmission des données du client vers l’instance de base de données RDS pour PostgreSQL.

**Opération de copie importante**  
Lors d’une opération de copie, les données sont transférées du système de fichiers du client vers l’instance de base de données RDS pour PostgreSQL. L'envoi d'une grande quantité de données à l'instance de base de données peut retarder la transmission des données du client vers l'instance de base de données.

**Connexion client inactive**  
Quand un client se connecte à l’instance de base de données RDS pour PostgreSQL alors que son état est `idle in transaction`, l’instance de base de données peut attendre que le client envoie plus de données ou émette une commande. Une connexion dans ces conditions peut entraîner une augmentation des événements `Client:ClientRead`.

**PgBouncer utilisé pour le regroupement de connexions**  
PgBouncer possède un paramètre de configuration réseau de bas niveau appelé`pkt_buf`, qui est défini sur 4 096 par défaut. Si la charge de travail envoie des paquets de requêtes de plus de 4 096 octets PgBouncer, nous vous recommandons d'augmenter le `pkt_buf` paramètre à 8 192. Si le nouveau paramètre ne permet pas de réduire le nombre d’événements `Client:ClientRead`, nous vous recommandons d’augmenter le paramètre `pkt_buf` en le définissant sur des valeurs plus élevées, telles que 16 384 ou 32 768. Si le texte de la requête est volumineux, un paramètre plus élevé peut être particulièrement utile.

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d’attente.

**Topics**
+ [

### Placement des clients dans la même zone de disponibilité et le même sous-réseau VPC que l'instance
](#wait-event.clientread.actions.az-vpc-subnet)
+ [

### Procédez à la mise à l’échelle du client
](#wait-event.clientread.actions.scale-client)
+ [

### Utilisez des instances de la génération actuelle
](#wait-event.clientread.actions.db-instance-class)
+ [

### Augmentez la bande passante réseau
](#wait-event.clientread.actions.increase-network-bandwidth)
+ [

### Surveillez les valeurs maximales des métriques de performances réseau
](#wait-event.clientread.actions.monitor-network-performance)
+ [

### Surveillez les transactions dont l’état est « idle in transaction » (transaction inactive)
](#wait-event.clientread.actions.check-idle-in-transaction)

### Placement des clients dans la même zone de disponibilité et le même sous-réseau VPC que l'instance
<a name="wait-event.clientread.actions.az-vpc-subnet"></a>

Pour réduire la latence réseau et augmenter le débit, placez les clients dans la même zone de disponibilité et le même sous-réseau de cloud privé virtuel (VPC) que l’instance de base de données RDS pour PostgreSQL. Veillez à ce que les clients soient géographiquement aussi proches que possible de l'instance de base de données.

### Procédez à la mise à l’échelle du client
<a name="wait-event.clientread.actions.scale-client"></a>

À l'aide d'Amazon CloudWatch ou d'autres indicateurs de l'hôte, déterminez si votre client est actuellement limité par le processeur ou la bande passante du réseau, ou les deux. Si le client est soumis à des contraintes, mettez-le à l’échelle en conséquence.

### Utilisez des instances de la génération actuelle
<a name="wait-event.clientread.actions.db-instance-class"></a>

La classe d’instance de base de données que vous utilisez ne prend peut-être pas en charge les trames jumbo. Si vous exécutez votre application sur Amazon EC2, pensez à utiliser une instance de génération actuelle pour le client. Configurez également l’unité de transmission maximale (MTU) sur le système d’exploitation client. Cette technique peut réduire le nombre d’allers-retours réseau et augmenter le débit du réseau. Pour plus d’informations, consultez [Trames jumbo (MTU de 9001)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) dans le *Guide de l’utilisateur Amazon EC2*.

Pour plus d’informations sur les classes d’instance de base de données, consultez [Classes d'instances de base de données ](Concepts.DBInstanceClass.md). Pour déterminer quelle classe d’instance de base de données est l’équivalent d’un type d’instance Amazon EC2, placez `db.` avant le nom du type d’instance Amazon EC2. Par exemple, l’instance Amazon EC2 `r5.8xlarge` est l’équivalent de la classe d’instance de base de données `db.r5.8xlarge`.

### Augmentez la bande passante réseau
<a name="wait-event.clientread.actions.increase-network-bandwidth"></a>

Utilisez `NetworkReceiveThroughput` les CloudWatch métriques `NetworkTransmitThroughput` Amazon pour surveiller le trafic réseau entrant et sortant sur l'instance de base de données. Ces métriques peuvent vous aider à déterminer si la bande passante réseau est suffisante pour votre charge de travail. 

Si la bande passante réseau est insuffisante, augmentez-la. Si le AWS client ou votre instance de base de données atteint les limites de bande passante du réseau, le seul moyen d'augmenter la bande passante est d'augmenter la taille de votre instance de base de données. Pour de plus amples informations, veuillez consulter [Types de classes d’instance de base de données](Concepts.DBInstanceClass.Types.md).

Pour plus d'informations sur CloudWatch les métriques, consultez[CloudWatch Métriques Amazon pour Amazon RDS](rds-metrics.md). 

### Surveillez les valeurs maximales des métriques de performances réseau
<a name="wait-event.clientread.actions.monitor-network-performance"></a>

Si vous utilisez des clients Amazon EC2, Amazon EC2 fournit des valeurs maximales pour les métriques de performances réseau, y compris pour la bande passante réseau entrante et sortante agrégée. Il assure également le suivi des connexions pour garantir un retour optimal des paquets et un accès aux services locaux de liaison pour des services tels que le système de noms de domaine (DNS). Pour surveiller ces valeurs maximales, utilisez un pilote réseau amélioré à jour et surveillez les performances réseau de votre client. 

Pour plus d’informations, consultez [ Surveillance des performances réseau de votre instance Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html) dans le *Guide de l’utilisateur Amazon EC2* et [Surveillance des performances réseau de votre instance Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/monitoring-network-performance-ena.html) dans le *Guide de l’utilisateur Amazon EC2*.

### Surveillez les transactions dont l’état est « idle in transaction » (transaction inactive)
<a name="wait-event.clientread.actions.check-idle-in-transaction"></a>

Déterminez si le nombre de connexions `idle in transaction` est croissant. Pour ce faire, surveillez la colonne `state` de la table `pg_stat_activity`. Vous pouvez identifier la source des connexions en exécutant une requête semblable à la suivante.

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

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

L’événement `Client:ClientWrite` se produit quand RDS pour PostgreSQL attend d’écrire des données sur le client.

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.clientwrite.context.supported)
+ [

## Contexte
](#wait-event.clientwrite.context)
+ [

## Causes probables de l’augmentation du nombre d’événements d’attente
](#wait-event.clientwrite.causes)
+ [

## Actions
](#wait-event.clientwrite.actions)

## Versions de moteur prises en charge
<a name="wait-event.clientwrite.context.supported"></a>

Ces informations sur les événements d’attente sont prises en charge pour RDS pour PostgreSQL versions 10 et ultérieures.

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

Un processus client doit lire toutes les données reçues d’un cluster de bases de données RDS pour PostgreSQL avant que ce cluster puisse envoyer plus de données. La période pendant laquelle le cluster attend avant d’envoyer plus de données au client est un événement `Client:ClientWrite`.

Une diminution du débit réseau entre l’instance de base de données RDS pour PostgreSQL et le client peut provoquer cet événement. Cet événement peut également se produire lorsque le client est soumis à une pression exercée sur l’UC ou à une saturation du réseau.. On parle de *pression exercée sur l’UC* lorsque l’UC est entièrement utilisée et que des tâches attendent du temps UC. On parle de *saturation du réseau* lorsque le réseau situé entre la base de données et le client transporte plus de données qu’il ne peut en gérer. 

## Causes probables de l’augmentation du nombre d’événements d’attente
<a name="wait-event.clientwrite.causes"></a>

Les principales causes de l’événement d’attente `Client:ClientWrite` sont les suivantes : 

**Latence réseau accrue**  
La latence réseau peut être accrue entre l’instance de base de données RDS pour PostgreSQL et le client. Une latence réseau plus élevée augmente le temps nécessaire au client pour recevoir les données.

**Charge accrue sur le client**  
Le client peut être soumis à une pression exercée sur l’UC ou à une saturation du réseau. Une augmentation de la charge sur le client retarde la réception des données de l’instance de base de données RDS pour PostgreSQL.

**Gros volume de données envoyé au client**  
L’instance de base de données RDS pour PostgreSQL peut envoyer une grande quantité de données au client. Un client peut ne pas être en mesure de recevoir les données aussi rapidement que le cluster les envoie. Certaines activités comme la copie d’une table volumineuse peuvent entraîner une augmentation des événements `Client:ClientWrite`.

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d’attente.

**Topics**
+ [

### Placez les clients dans la même zone de disponibilité et le même sous-réseau VPC que le cluster
](#wait-event.clientwrite.actions.az-vpc-subnet)
+ [

### Utilisez des instances de la génération actuelle
](#wait-event.clientwrite.actions.db-instance-class)
+ [

### Réduisez la quantité de données envoyée au client
](#wait-event.clientwrite.actions.reduce-data)
+ [

### Procédez à la mise à l’échelle du client
](#wait-event.clientwrite.actions.scale-client)

### Placez les clients dans la même zone de disponibilité et le même sous-réseau VPC que le cluster
<a name="wait-event.clientwrite.actions.az-vpc-subnet"></a>

Pour réduire la latence réseau et augmenter le débit, placez les clients dans la même zone de disponibilité et le même sous-réseau de cloud privé virtuel (VPC) que l’instance de base de données RDS pour PostgreSQL.

### Utilisez des instances de la génération actuelle
<a name="wait-event.clientwrite.actions.db-instance-class"></a>

La classe d’instance de base de données que vous utilisez ne prend peut-être pas en charge les trames jumbo. Si vous exécutez votre application sur Amazon EC2, pensez à utiliser une instance de génération actuelle pour le client. Configurez également l’unité de transmission maximale (MTU) sur le système d’exploitation client. Cette technique peut réduire le nombre d’allers-retours réseau et augmenter le débit du réseau. Pour plus d’informations, consultez [Trames jumbo (MTU de 9001)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) dans le *Guide de l’utilisateur Amazon EC2*.

Pour plus d’informations sur les classes d’instance de base de données, consultez [Classes d'instances de base de données ](Concepts.DBInstanceClass.md). Pour déterminer quelle classe d’instance de base de données est l’équivalent d’un type d’instance Amazon EC2, placez `db.` avant le nom du type d’instance Amazon EC2. Par exemple, l’instance Amazon EC2 `r5.8xlarge` est l’équivalent de la classe d’instance de base de données `db.r5.8xlarge`.

### Réduisez la quantité de données envoyée au client
<a name="wait-event.clientwrite.actions.reduce-data"></a>

Lorsque cela est possible, ajustez votre application pour réduire la quantité de données que l’instance de base de données RDS pour PostgreSQL envoie au client. Ces ajustements permettent d’éviter les conflits liés à l’UC et au réseau sur le client.

### Procédez à la mise à l’échelle du client
<a name="wait-event.clientwrite.actions.scale-client"></a>

À l'aide d'Amazon CloudWatch ou d'autres indicateurs de l'hôte, déterminez si votre client est actuellement limité par le processeur ou la bande passante du réseau, ou les deux. Si le client est soumis à des contraintes, mettez-le à l’échelle en conséquence.

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

Cet événement se produit lorsqu'un thread est actif dans l'UC ou qu'il est en attente d'UC.

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.cpu.context.supported)
+ [

## Contexte
](#wait-event.cpu.context)
+ [

## Causes probables de l'augmentation du nombre d'événements d'attente
](#wait-event.cpu.causes)
+ [

## Actions
](#wait-event.cpu.actions)

## Versions de moteur prises en charge
<a name="wait-event.cpu.context.supported"></a>

Ces informations sur les événements d'attente s'appliquent à toutes les versions de RDS for PostgreSQL.

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

L'*unité centrale (UC)* est le composant d'un ordinateur qui exécute les instructions. Par exemple, les instructions de l'UC effectuent des opérations arithmétiques et échangent des données en mémoire. Si une requête augmente le nombre d'instructions qu'elle exécute par le biais du moteur de base de données, le temps passé à exécuter la requête augmente. La *planification du temps UC* consiste à accorder du temps UC à un processus. La planification est orchestrée par le noyau du système d'exploitation.

**Topics**
+ [

### Comment savoir quand cette attente se produit
](#wait-event.cpu.when-it-occurs)
+ [

### DBLoadMétrique du processeur
](#wait-event.cpu.context.dbloadcpu)
+ [

### Métriques os.cpuUtilization
](#wait-event.cpu.context.osmetrics)
+ [

### Cause probable de la planification du temps UC
](#wait-event.cpu.context.scheduling)

### Comment savoir quand cette attente se produit
<a name="wait-event.cpu.when-it-occurs"></a>

Cet événement d'attente `CPU` indique qu'un processus backend est actif dans l'UC ou qu'il est en attente d'UC. Cela se produit lorsqu'une requête contient les informations suivantes :
+ La colonne `pg_stat_activity.state` indique la valeur `active`.
+ Les colonnes `wait_event_type` et `wait_event` de `pg_stat_activity` indiquent toutes les deux `null`.

Pour voir les processus backend qui utilisent l'UC ou sont en attente de celle-ci, exécutez la requête suivante.

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

### DBLoadMétrique du processeur
<a name="wait-event.cpu.context.dbloadcpu"></a>

La métrique Performance Insights de l'UC est `DBLoadCPU`. La valeur de `DBLoadCPU` peut être différente de celle de la CloudWatch métrique Amazon`CPUUtilization`. Cette dernière métrique est collectée à partir de HyperVisor pour une instance de base de données.

### Métriques os.cpuUtilization
<a name="wait-event.cpu.context.osmetrics"></a>

Les métriques du système d'exploitation Performance Insights fournissent des informations détaillées sur l'utilisation de l'UC. Par exemple, vous pouvez afficher les métriques suivantes :
+ `os.cpuUtilization.nice.avg`
+ `os.cpuUtilization.total.avg`
+ `os.cpuUtilization.wait.avg`
+ `os.cpuUtilization.idle.avg`

Performance Insights présente l'utilisation du processeur par le moteur de base de données sous la forme `os.cpuUtilization.nice.avg`.

### Cause probable de la planification du temps UC
<a name="wait-event.cpu.context.scheduling"></a>

 Le noyau du système d'exploitation (SE) gère la planification pour le processeur. Quand le processeur est *actif*, il se peut qu'un processus doive attendre avant d'être planifié. Le processeur est actif pendant qu'il effectue des calculs. Il est également actif lorsqu'il possède un thread inactif qu'il n'exécute pas, c'est-à-dire qu'un thread inactif en attente de mémoire I/O. This type of I/O domine la charge de travail typique d'une base de données. 

Les processus sont susceptibles d'attendre d'être planifiés sur une UC lorsque les conditions suivantes sont réunies :
+ La CloudWatch `CPUUtilization` métrique est proche de 100 %.
+ La charge moyenne est supérieure au nombre de vCPUs, ce qui indique une charge lourde. Vous trouverez la métrique `loadAverageMinute` dans la section relative aux métriques du système d'exploitation de Performance Insights.

## Causes probables de l'augmentation du nombre d'événements d'attente
<a name="wait-event.cpu.causes"></a>

Un événement d'attente UC trop fréquent peut révéler un problème de performances dont les principales causes sont les suivantes.

**Topics**
+ [

### Causes probables des pics soudains
](#wait-event.cpu.causes.spikes)
+ [

### Causes probables d'une fréquence élevée sur le long terme
](#wait-event.cpu.causes.long-term)
+ [

### Cas particuliers
](#wait-event.cpu.causes.corner-cases)

### Causes probables des pics soudains
<a name="wait-event.cpu.causes.spikes"></a>

Les causes les plus probables des pics soudains sont les suivantes :
+ Votre application a ouvert un trop grand nombre de connexions simultanées à la base de données. Ce scénario est connu sous le nom de « connection storm » (tempête de connexions).
+ La charge de travail de votre application a connu l'un des changements suivants :
  + Nouvelles requêtes
  + Augmentation de la taille du jeu de données
  + Maintenance ou création d'index
  + Nouvelles fonctions
  + Nouveaux opérateurs
  + Augmentation des exécutions de requêtes parallèles
+ Vos plans d'exécution des requêtes ont changé. Dans certains cas, un changement peut entraîner une augmentation des mémoires tampons. Par exemple, la requête utilise désormais une analyse séquentielle alors qu'elle utilisait auparavant un index. Dans ce cas, les requêtes ont besoin de plus d'UC pour atteindre le même objectif.

### Causes probables d'une fréquence élevée sur le long terme
<a name="wait-event.cpu.causes.long-term"></a>

Causes les plus probables de la répétition des événements sur une longue période :
+ Un trop grand nombre de processus backend s'exécutent simultanément sur l'UC. Ces processus peuvent être des employés parallèles.
+ Les performances des requêtes ne sont pas optimales car elles nécessitent un grand nombre de mémoires tampons.

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

Si aucune des causes probables ne s'avère être la bonne, les situations suivantes peuvent se produire :
+ L'UC échange des processus en entrée et en sortie.
+ Le processeur est peut-être en train de gérer les entrées des tables de pages si la fonctionnalité *huge pages* (grandes pages) a été désactivée. Cette fonctionnalité de gestion de la mémoire est activée par défaut pour toutes les classes d'instances de base de données autres que les classes micro, petites et moyennes. Pour de plus amples informations, veuillez consulter [Grandes pages pour RDS pour PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.HugePages.md). 

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

Si l'événement d'attente `CPU` domine l'activité de la base de données, cela n'indique pas nécessairement un problème de performance. Ne réagissez à cet événement qu'en cas de dégradation des performances.

**Topics**
+ [

### Vérifiez que la base de données n'est pas à l'origine de l'augmentation du nombre d'événements d'attente UC
](#wait-event.cpu.actions.db-CPU)
+ [

### Déterminez si le nombre de connexions a augmenté
](#wait-event.cpu.actions.connections)
+ [

### Réagissez aux changements de charge de travail
](#wait-event.cpu.actions.workload)

### Vérifiez que la base de données n'est pas à l'origine de l'augmentation du nombre d'événements d'attente UC
<a name="wait-event.cpu.actions.db-CPU"></a>

Examinez la métrique `os.cpuUtilization.nice.avg` dans Performance Insights. Si cette valeur est bien inférieure à l'utilisation de l'UC, cela signifie que des processus non liés à la base de données contribuent majoritairement aux événements d'attente UC.

### Déterminez si le nombre de connexions a augmenté
<a name="wait-event.cpu.actions.connections"></a>

Examinez la `DatabaseConnections` métrique sur Amazon CloudWatch. L'action à entreprendre varie selon que ce nombre augmente ou diminue pendant la période d'augmentation des événements d'attente UC.

#### Les connexions ont augmenté
<a name="wait-event.cpu.actions.connections.increased"></a>

Si le nombre de connexions a augmenté, comparez le nombre de processus principaux consommant du processeur au nombre de v. CPUs Les scénarios suivants sont possibles :
+ Le nombre de processus principaux consommant le processeur est inférieur au nombre de v. CPUs

  Dans ce cas, le nombre de connexions n'est pas un problème. Cependant, vous pouvez toujours essayer de réduire l'utilisation de l'UC.
+ Le nombre de processus principaux consommant du processeur est supérieur au nombre de v. CPUs

  Dans ce cas, procédez comme suit :
  + Réduisez le nombre de processus backend connectés à votre base de données. Par exemple, implémentez une solution de regroupement des connexions telle que RDS Proxy. Pour en savoir plus, veuillez consulter la section [Proxy Amazon RDS ](rds-proxy.md).
  + Améliorez la taille de votre instance pour obtenir un nombre plus élevé de CPUs v.
  + Redirigez certaines charges de travail en lecture seule vers des nœuds de lecture, le cas échéant.

#### Les connexions n'ont pas augmenté
<a name="wait-event.cpu.actions.connections.decreased"></a>

Examinez les métriques `blks_hit` dans Performance Insights. Recherchez une corrélation entre une augmentation de `blks_hit` et l'utilisation de l'UC. Les scénarios possibles sont les suivants :
+ L'utilisation de l'UC et `blks_hit` sont corrélés.

  Dans ce cas, recherchez les principales instructions SQL liées à l'utilisation de l'UC ainsi que les modifications apportées au plan. Vous pouvez utiliser l'une des techniques suivantes :
  + Décrivez les plans manuellement et comparez-les au plan d'exécution attendu.
  + Recherchez une augmentation des accès en bloc par seconde et des accès en bloc locaux par seconde. Dans la section **Top SQL** (Principaux éléments SQL) du tableau de bord Performance Insights, choisissez **Preferences** (Préférences).
+ L'utilisation de l'UC et `blks_hit` ne sont pas corrélés.

  Dans ce cas, déterminez si l'une des situations suivantes se produit :
  + L'application se connecte et se déconnecte rapidement de la base de données. 

    Diagnostiquez ce comportement en activant `log_connections` et `log_disconnections`, puis en analysant les journaux PostgreSQL. Pensez à utiliser l'analyseur de journaux `pgbadger`. Pour de plus amples informations, veuillez consulter [https://github.com/darold/pgbadger](https://github.com/darold/pgbadger).
  + Le système d'exploitation est surchargé.

    Dans ce cas, Performance Insights montre que les processus backend utilisent l'UC plus longtemps que d'habitude. Recherchez des preuves dans les `os.cpuUtilization` métriques Performance Insights ou dans la CloudWatch `CPUUtilization` métrique. Si le système d'exploitation est surchargé, consultez les métriques de surveillance améliorée pour approfondir le diagnostic. Plus précisément, examinez la liste des processus et le pourcentage d'UC utilisé par chaque processus.
  + Les principales instructions SQL utilisent trop d'UC.

    Examinez les instructions liées à l'utilisation de l'UC pour voir si elles peuvent en utiliser moins. Exécutez une commande `EXPLAIN` et concentrez-vous sur les nœuds du plan qui ont le plus d'impact. Utilisez un visualiseur de plan d'exécution PostgreSQL. Pour essayer cet outil, consultez [http://explain.dalibo.com/](http://explain.dalibo.com/).

### Réagissez aux changements de charge de travail
<a name="wait-event.cpu.actions.workload"></a>

Si votre charge de travail a changé, recherchez les types de changements suivants :

Nouvelles requêtes  
Déterminez si les nouvelles requêtes sont attendues. Si oui, assurez-vous que leur plan d'exécution et le nombre d'exécutions par seconde sont attendus.

Augmentation de la taille du jeu de données  
Déterminez si un partitionnement, s'il n'est pas déjà implémenté, peut être utile. Cette stratégie peut réduire le nombre de pages qu'une requête doit récupérer.

Maintenance ou création d'index  
Vérifiez si le calendrier de maintenance est attendu. Une bonne pratique consiste à planifier des activités de maintenance en dehors des périodes de pointe.

Nouvelles fonctions  
Déterminez si ces fonctions s'exécutent comme prévu lors des tests. Plus précisément, déterminez si le nombre d'exécutions par seconde est attendu.

Nouveaux opérateurs  
Déterminez s'ils fonctionnent comme prévu lors des tests.

Augmentation du nombre de requêtes exécutées en parallèle  
Déterminez si l'une des situations suivantes s'est produite :  
+ Les relations ou index impliqués ont soudainement augmenté en termes de taille, de sorte qu'ils sont considérablement différents de `min_parallel_table_scan_size` ou `min_parallel_index_scan_size`.
+ Des modifications récentes ont été apportées à `parallel_setup_cost` ou `parallel_tuple_cost`.
+ Des modifications récentes ont été apportées à `max_parallel_workers` ou `max_parallel_workers_per_gather`.

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

Les événements `IO:BufFileRead` et `IO:BufFileWrite` se produisent quand RDS pour PostgreSQL crée des fichiers temporaires. Lorsque des opérations requièrent plus de mémoire que n'en confèrent les paramètres de mémoire de travail définis, elles écrivent des données temporaires sur un stockage permanent. Cette opération est parfois appelée *déversement sur le disque.* Pour plus d’informations sur les fichiers temporaires et leur utilisation, consultez [Gestion des fichiers temporaires avec PostgreSQL](PostgreSQL.ManagingTempFiles.md).

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.iobuffile.context.supported)
+ [

## Contexte
](#wait-event.iobuffile.context)
+ [

## Causes probables de l'augmentation du nombre d'événements d'attente
](#wait-event.iobuffile.causes)
+ [

## Actions
](#wait-event.iobuffile.actions)

## Versions de moteur prises en charge
<a name="wait-event.iobuffile.context.supported"></a>

Ces informations sur les événements d’attente sont prises en charge pour toutes les versions de RDS pour PostgreSQL.

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

`IO:BufFileRead` et `IO:BufFileWrite` se rapportent à la zone de mémoire de travail et à la zone de mémoire des travaux de maintenance. Pour plus d'informations sur ces zones de mémoire locale, consultez [Consommation des ressources](https://www.postgresql.org/docs/current/runtime-config-resource.html) dans la documentation PostgreSQL.

La valeur par défaut du paramètre `work_mem` est 4 Mo. Si une session effectue des opérations en parallèle, chaque application de travail gérant le parallélisme utilise 4 Mo de mémoire. Par conséquent, définissez `work_mem` prudemment. Si vous augmentez trop la valeur, une base de données exécutant plusieurs sessions peut utiliser trop de mémoire. Si vous définissez une valeur trop faible, RDS pour PostgreSQL crée des fichiers temporaires dans le stockage local. Le disque I/O contenant ces fichiers temporaires peut réduire les performances.

Si vous observez la séquence d'événements suivante, votre base de données génère peut-être des fichiers temporaires :

1. Diminution soudaine et brutale de la disponibilité

1. Récupération rapide de l'espace libre

Vous pouvez également observer un schéma en dents de scie. Ce schéma peut indiquer que votre base de données crée constamment de petits fichiers.

## Causes probables de l'augmentation du nombre d'événements d'attente
<a name="wait-event.iobuffile.causes"></a>

En général, ces événements d'attente sont provoqués par des opérations qui utilisent plus de mémoire que n'en allouent les paramètres `work_mem` ou `maintenance_work_mem`. Pour compenser, les opérations écrivent dans des fichiers temporaires. Les principales causes des événements `IO:BufFileRead` et `IO:BufFileWrite` sont les suivantes :

**Requêtes nécessitant plus de mémoire qu'il n'en existe dans la zone de mémoire de travail**  
Les requêtes présentant les caractéristiques suivantes utilisent la zone de mémoire de travail :  
+ Jointures par hachage
+ `ORDER BY`Clause 
+ `GROUP BY`Clause 
+ `DISTINCT`
+ Fonctions de fenêtrage
+ `CREATE TABLE AS SELECT`
+ Actualisation de la vue matérialisée

**Instructions nécessitant plus de mémoire qu'il n'en existe dans la zone de mémoire des travaux de maintenance**  
Les instructions suivantes utilisent la zone de mémoire des travaux de maintenance :  
+ `CREATE INDEX`
+ `CLUSTER`

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d’attente.

**Topics**
+ [

### Identifiez le problème
](#wait-event.iobuffile.actions.problem)
+ [

### Examinez vos requêtes de jointure
](#wait-event.iobuffile.actions.joins)
+ [

### Examinez vos requêtes ORDER BY et GROUP BY
](#wait-event.iobuffile.actions.order-by)
+ [

### Évitez d'utiliser l'opération DISTINCT
](#wait-event.iobuffile.actions.distinct)
+ [

### Envisagez d'utiliser des fonctions de fenêtrage à la place des fonctions GROUP BY
](#wait-event.iobuffile.actions.window)
+ [

### Examinez les vues matérialisées et les instructions CTAS
](#wait-event.iobuffile.actions.mv-refresh)
+ [

### Reconstruction des index à l'aide de pg\$1repack
](#wait-event.iobuffile.actions.pg_repack)
+ [

### Augmentez maintenance\$1work\$1mem lorsque vous mettez des tables en cluster
](#wait-event.iobuffile.actions.cluster)
+ [

### Réglez la mémoire pour empêcher les E/S : BufFileRead et E/S : BufFileWrite
](#wait-event.iobuffile.actions.tuning-memory)

### Identifiez le problème
<a name="wait-event.iobuffile.actions.problem"></a>

Vous pouvez consulter l'utilisation des fichiers temporaires directement dans Performance Insights. Pour de plus amples informations, veuillez consulter [Affichage de l’utilisation des fichiers temporaires avec Performance Insights](PostgreSQL.ManagingTempFiles.Example.md). Lorsque Performance Insights est désactivé, vous remarquerez peut-être une augmentation `IO:BufFileRead` des `IO:BufFileWrite` opérations.

Pour identifier la source du problème, vous pouvez définir le paramètre `log_temp_files` de manière à consigner toutes les requêtes qui génèrent un nombre de Ko de fichiers temporaires supérieur au seuil spécifié. Par défaut, `log_temp_files` est défini sur `-1`, ce qui désactive cette fonctionnalité de journalisation. Si vous définissez ce paramètre sur `0`, RDS pour PostgreSQL consigne tous les fichiers temporaires. Si vous définissez la valeur `1024`, RDS pour PostgreSQL consigne toutes les requêtes qui produisent des fichiers temporaires de plus de 1 Mo. Pour en savoir plus sur `log_temp_files`, consultez [Error Reporting and Logging](https://www.postgresql.org/docs/current/runtime-config-logging.html) dans la documentation PostgreSQL.

### Examinez vos requêtes de jointure
<a name="wait-event.iobuffile.actions.joins"></a>

Il est probable que votre requête utilise des jointures. Par exemple, la requête suivante joint quatre tables.

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

Les pics d'utilisation des fichiers temporaires peuvent être dus à un problème dans la requête proprement dite. Par exemple, une clause rompue peut ne pas filtrer correctement les jointures. Prenons la deuxième jointure interne de l'exemple suivant.

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

La requête précédente joint par erreur `customer.id` à `customer.id`, générant un produit cartésien entre chaque client et chaque commande. Ce type de jointure accidentelle génère des fichiers temporaires volumineux. Selon la taille des tables, une requête cartésienne peut même saturer le stockage. Votre application peut présenter des jointures cartésiennes lorsque les conditions suivantes sont réunies :
+ Vous observez des baisses importantes et brutales de la disponibilité du stockage, suivies d'une récupération rapide.
+ Aucun index n'est créé.
+ Aucune instruction `CREATE TABLE FROM SELECT` n'est émise.
+ Aucune vue matérialisée n'est actualisée.

Pour savoir si les tables sont jointes à l'aide des clés appropriées, examinez votre requête et les directives de mappage objet-relationnel. Gardez à l'esprit que certaines requêtes de votre application ne sont pas appelées en permanence, et que certaines requêtes sont générées dynamiquement.

### Examinez vos requêtes ORDER BY et GROUP BY
<a name="wait-event.iobuffile.actions.order-by"></a>

Dans certains cas, une clause `ORDER BY` peut entraîner un nombre excessif de fichiers temporaires. Considérez les directives suivantes :
+ N'incluez des colonnes dans une clause `ORDER BY` que lorsqu'elles doivent être classées. Cette directive est particulièrement importante pour les requêtes qui renvoient des milliers de lignes et spécifient de nombreuses colonnes dans la clause `ORDER BY`.
+ N'hésitez pas à créer des index pour accélérer les clauses `ORDER BY` lorsqu'elles correspondent à des colonnes qui présentent le même ordre croissant ou décroissant. Les index partiels sont préférables car ils sont plus petits. Les index de petite taille sont lus et parcourus plus rapidement.
+ Si vous créez des index pour des colonnes qui peuvent accepter des valeurs nulles, déterminez si vous souhaitez que les valeurs nulles soient stockées à la fin ou au début des index.

  Si possible, réduisez le nombre de lignes à classer en filtrant l'ensemble de résultats. Si vous utilisez des instructions ou des sous-requêtes liées à la clause `WITH`, n'oubliez pas qu'une requête interne génère un ensemble de résultats et le transmet à la requête externe. Plus le nombre de lignes qu'une requête peut filtrer est élevé, moins elle a de classement à effectuer.
+ Si vous n'avez pas besoin de l'ensemble de résultats complet, utilisez la clause `LIMIT`. Par exemple, si vous avez uniquement besoin des cinq premières lignes, une requête utilisant la clause `LIMIT` ne continue pas à générer des résultats. La requête a ainsi besoin de moins de mémoire et de moins de fichiers temporaires.

Une requête qui utilise une clause `GROUP BY` peut également avoir besoin de fichiers temporaires. Les requêtes `GROUP BY` résument les valeurs à l'aide de fonctions telles que les suivantes :
+ `COUNT`
+ `AVG`
+ `MIN`
+ `MAX`
+ `SUM`
+ `STDDEV`

Pour régler les requêtes `GROUP BY`, suivez les recommandations relatives aux requêtes `ORDER BY`.

### Évitez d'utiliser l'opération DISTINCT
<a name="wait-event.iobuffile.actions.distinct"></a>

Dans la mesure du possible, évitez d'utiliser l'opération `DISTINCT` pour supprimer les lignes en double. Plus votre requête renvoie de lignes inutiles et en double, plus l'opération `DISTINCT` devient coûteuse. Si possible, ajoutez des filtres dans la clause `WHERE`, même si vous utilisez les mêmes filtres pour différentes tables. Un filtrage de la requête et une jointure correctes vous permettent d'améliorer les performances et de réduire l'utilisation des ressources. Ils vous permettent également d'éviter les rapports et les résultats incorrects.

Si vous devez utiliser `DISTINCT` pour plusieurs lignes d'une même table, n'hésitez pas à créer un index composite. Le regroupement de plusieurs colonnes dans un index peut améliorer le temps nécessaire à l'évaluation des lignes distinctes. De plus, si vous utilisez RDS pour PostgreSQL version 10 ou ultérieure, vous pouvez corréler les statistiques entre plusieurs colonnes à l’aide de la commande `CREATE STATISTICS`.

### Envisagez d'utiliser des fonctions de fenêtrage à la place des fonctions GROUP BY
<a name="wait-event.iobuffile.actions.window"></a>

Avec `GROUP BY`, vous modifiez l'ensemble de résultats, puis récupérez le résultat agrégé. Avec les fonctions de fenêtrage, vous pouvez agréger les données sans modifier l'ensemble de résultats. Une fonction de fenêtrage utilise la clause `OVER` pour effectuer des calculs sur les ensembles définis par la requête, en corrélant une ligne avec une autre. Les fonctions de fenêtrage vous permettent d'utiliser toutes les fonctions `GROUP BY` ainsi que les fonctions suivantes :
+ `RANK`
+ `ARRAY_AGG`
+ `ROW_NUMBER`
+ `LAG`
+ `LEAD`

Pour réduire le nombre de fichiers temporaires générés par une fonction de fenêtrage, supprimez les doublons d'un même ensemble de résultats lorsque vous avez besoin de deux agrégations distinctes. Considérons la requête suivante :

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

Vous pouvez réécrire la requête en utilisant la clause `WINDOW` comme suit.

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

Par défaut, le planificateur d’exécution RDS pour PostgreSQL regroupe les nœuds similaires afin de ne pas dupliquer les opérations. Toutefois, en utilisant une déclaration explicite pour le bloc de fenêtres, vous pouvez gérer la requête plus facilement. Vous pouvez également améliorer les performances en empêchant la duplication.

### Examinez les vues matérialisées et les instructions CTAS
<a name="wait-event.iobuffile.actions.mv-refresh"></a>

Lorsqu'une vue matérialisée est actualisée, elle exécute une requête. Cette requête peut contenir une opération telle que `GROUP BY`, `ORDER BY` ou `DISTINCT`. Lors d'une actualisation, vous pouvez observer un grand nombre de fichiers temporaires et les événements d'attente `IO:BufFileWrite` et `IO:BufFileRead`. De même, lorsque vous créez une table basée sur une instruction `SELECT`, l'instruction `CREATE TABLE` exécute une requête. Pour réduire le nombre de fichiers temporaires nécessaires, optimisez la requête.

### Reconstruction des index à l'aide de pg\$1repack
<a name="wait-event.iobuffile.actions.pg_repack"></a>

Lorsque vous créez un index, le moteur classe l'ensemble de résultats. À mesure que la taille des tables augmente et que les valeurs de la colonne indexée se diversifient, les fichiers temporaires ont besoin de plus d'espace. Dans la plupart des cas, vous ne pouvez pas empêcher la création de fichiers temporaires pour les tables volumineuses sans modifier la zone de mémoire des travaux de maintenance. Pour plus d’informations sur `maintenance_work_mem`, consultez [https://www.postgresql.org/docs/current/runtime-config-resource.html](https://www.postgresql.org/docs/current/runtime-config-resource.html) dans la documentation PostgreSQL. 

Une solution de contournement possible lors de la recréation d'un index volumineux consiste à utiliser l'extension pg\$1repack. Pour en savoir plus, consultez [Reorganize tables in PostgreSQL databases with minimal locks](https://reorg.github.io/pg_repack/) dans la documentation pg\$1repack. Pour obtenir des informations sur la configuration de l’extension dans votre instance de base de données RDS pour PostgreSQL, consultez [Réduction du gonflement des tables et des index avec l’extension pg\$1repack](Appendix.PostgreSQL.CommonDBATasks.pg_repack.md). 

### Augmentez maintenance\$1work\$1mem lorsque vous mettez des tables en cluster
<a name="wait-event.iobuffile.actions.cluster"></a>

La commande `CLUSTER` met en cluster la table spécifiée par *table\$1name* à partir d'un index existant spécifié par *index\$1name*. RDS pour PostgreSQL recrée physiquement la table en suivant l’ordre d’un index donné.

Lorsque le stockage magnétique était prédominant, la mise en cluster était courante car le débit de stockage était limité. Maintenant que le stockage SSD est plus répandu, la mise en cluster est moins fréquente. Toutefois, en mettant des tables en cluster, vous pouvez encore bénéficier d'une légère amélioration des performances en fonction de la taille de la table, de l'index, de la requête, etc. 

Si vous exécutez la commande `CLUSTER` et observez les événements d'attente `IO:BufFileWrite` et `IO:BufFileRead`, réglez `maintenance_work_mem`. Augmentez la taille de la mémoire en la définissant sur une valeur relativement élevée. Une valeur élevée permettra au moteur d'utiliser davantage de mémoire pour l'opération de mise en cluster.

### Réglez la mémoire pour empêcher les E/S : BufFileRead et E/S : BufFileWrite
<a name="wait-event.iobuffile.actions.tuning-memory"></a>

Dans certaines situations, vous devez régler la mémoire. Votre objectif est d'équilibrer la mémoire entre les zones de consommation suivantes à l'aide des paramètres appropriés, comme suit.
+ La valeur `work_mem` 
+ La mémoire restant après déduction de la valeur `shared_buffers`
+ Nombre maximal de connexions ouvertes et en cours d'utilisation, qui est limité par `max_connections`

Pour plus d'informations sur le réglage de la mémoire, consultez [Consommation des ressources](https://www.postgresql.org/docs/current/runtime-config-resource.html) dans la documentation PostgreSQL. 

#### Augmentez la taille de la zone de mémoire de travail
<a name="wait-event.iobuffile.actions.tuning-memory.work-mem"></a>

Dans certains cas, votre seule option consiste à augmenter la mémoire utilisée par votre session. Si vos requêtes sont correctement écrites et utilisent les bonnes clés pour les jointures, augmentez la valeur `work_mem`. 

Pour savoir combien de fichiers temporaires une requête génère, définissez `log_temp_files` sur `0`. Si vous définissez la valeur `work_mem` sur la valeur maximale identifiée dans les journaux, vous empêchez la requête de générer des fichiers temporaires. Toutefois, `work_mem` définit le maximum par nœud du plan pour chaque connexion ou application de travail parallèle. Si la base de données compte 5 000 connexions, et si chacune d'entre elles utilise 256 Mio de mémoire, le moteur a besoin de 1,2 Tio de RAM. Votre instance risque donc de manquer de mémoire.

#### Réservez suffisamment de mémoire pour le groupe de mémoires tampons partagées
<a name="wait-event.iobuffile.actions.tuning-memory.shared-pool"></a>

Votre base de données utilise des zones de mémoire telles que le groupe de mémoires tampons partagées, et pas seulement la zone de mémoire de travail. Prenez en compte les besoins de ces zones de mémoire supplémentaires avant d'augmenter `work_mem`.

Par exemple, supposons que votre classe d’instances RDS pour PostgreSQL est db.r5.2xlarge. Cette classe dispose de 64 Gio de mémoire. Par défaut, 25 % de la mémoire est réservée pour le groupe de mémoires tampons partagées. Après avoir soustrait la quantité allouée à la zone de mémoire partagée, il reste 16 384 Mo. Évitez d'allouer la mémoire restante exclusivement à la zone de mémoire de travail, car le système d'exploitation et le moteur ont également besoin de mémoire.

La mémoire que vous pouvez allouer à `work_mem` dépend de la classe d'instance. Si vous utilisez une classe d'instance plus importante, vous disposerez de plus de mémoire. Toutefois, dans l'exemple précédent, vous ne pouvez pas utiliser plus de 16 Gio. Sinon votre instance devient indisponible lorsqu'elle est à court de mémoire. Pour récupérer l’instance en cas d’indisponibilité, les services d’automatisation de RDS pour PostgreSQL redémarrent automatiquement.

#### Gérez le nombre de connexions
<a name="wait-event.iobuffile.actions.tuning-memory.connections"></a>

Supposons que votre instance de base de données compte 5 000 connexions simultanées. Chaque connexion utilise au moins 4 Mio de `work_mem`. La forte consommation de mémoire des connexions est susceptible de dégrader les performances. En réponse, vous disposez des options suivantes :
+ Passez à une classe d'instance supérieure.
+ Réduisez le nombre de connexions simultanées à la base de données à l'aide d'un proxy ou d'un regroupement de connexions.

Pour les proxies, utilisez Amazon RDS Proxy, PgBouncer ou un regroupement de connexions basé sur votre application. Cette solution réduit la charge de l'UC. Elle réduit également le risque lorsque toutes les connexions ont besoin de la zone de mémoire de travail. Lorsque les connexions à la base de données sont moins nombreuses, vous pouvez augmenter la valeur de `work_mem`. De cette façon, vous réduisez l'occurrence des événements d'attente `IO:BufFileRead` et `IO:BufFileWrite`. De plus, les requêtes en attente d'accès à la zone de mémoire de travail s'accélèrent de manière significative.

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

L'événement `IO:DataFileRead` se produit lorsqu'une connexion attend qu'un processus backend lise une page requise à partir du stockage parce que la page n'est pas disponible dans la mémoire partagée.

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.iodatafileread.context.supported)
+ [

## Contexte
](#wait-event.iodatafileread.context)
+ [

## Causes probables de l’augmentation du nombre d’événements d’attente
](#wait-event.iodatafileread.causes)
+ [

## Actions
](#wait-event.iodatafileread.actions)

## Versions de moteur prises en charge
<a name="wait-event.iodatafileread.context.supported"></a>

Ces informations sur les événements d’attente sont prises en charge pour toutes les versions de RDS pour PostgreSQL.

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

Toutes les requêtes et opérations en langage de manipulation de données (DML) accèdent aux pages du groupe de mémoires tampons. Les instructions qui peuvent induire des lectures sont : `SELECT`, `UPDATE` et `DELETE`. Par exemple, une instruction `UPDATE` peut lire des pages à partir de tables ou d'index. Si la page demandée ou mise à jour ne se trouve pas dans le groupe de mémoires tampons partagées, cette lecture peut provoquer l'événement `IO:DataFileRead`.

Comme le groupe de mémoires tampons partagées est limité, il peut être saturé. Dans ce cas, les requêtes de pages qui ne sont pas en mémoire forcent la base de données à lire des blocs sur le disque. Si l'événement `IO:DataFileRead` se produit fréquemment, votre groupe de mémoires tampons partagées est peut-être trop petit pour prendre en charge votre charge de travail. Ce problème se pose avec acuité pour les requêtes `SELECT` qui lisent un grand nombre de lignes qui ne rentrent pas dans le groupe de mémoires tampons. Pour plus d'informations sur le groupe de mémoires tampons, consultez [Consommation des ressources](https://www.postgresql.org/docs/current/runtime-config-resource.html) dans la documentation PostgreSQL.

## Causes probables de l’augmentation du nombre d’événements d’attente
<a name="wait-event.iodatafileread.causes"></a>

Les principales causes de l'événement `IO:DataFileRead` sont les suivantes :

**Pics de connexion**  
Il se peut que plusieurs connexions génèrent le même nombre d'événements IO : DataFileRead wait. Dans ce cas, un pic (augmentation soudaine et importante) d'événements `IO:DataFileRead` peut se produire. 

**Instructions SELECT et DML effectuant des analyses séquentielles**  
Votre application est peut-être en train d'effectuer une nouvelle opération. Ou une opération existante peut changer suite à un nouveau plan d'exécution. Dans ce cas, recherchez les tables (en particulier les tables volumineuses) qui présentent une valeur `seq_scan` plus élevée. Pour les trouver, interrogez `pg_stat_user_tables`. Pour suivre les requêtes qui génèrent plus d'opérations de lecture, utilisez l'extension `pg_stat_statements`.

**CTAS et CREATE INDEX pour les jeux de données volumineux**  
Un *CTAS* est une instruction `CREATE TABLE AS SELECT`. Si vous exécutez un CTAS en utilisant un jeu de données volumineux comme source, ou si vous créez un index sur une table volumineuse, l'événement `IO:DataFileRead` peut se produire. Lorsque vous créez un index, la base de données peut avoir besoin de lire l'objet entier à l'aide d'une analyse séquentielle. Un CTAS génère des lectures `IO:DataFile` lorsque les pages ne sont pas en mémoire.

**Exécution simultanée de plusieurs processus employés vacuum**  
Les processus employés vacuum peuvent être déclenchés manuellement ou automatiquement. Nous vous recommandons d'adopter une stratégie vacuum agressive. Toutefois, lorsqu'une table comporte de nombreuses lignes mises à jour ou supprimées, le nombre d'attentes `IO:DataFileRead` augmente. Une fois l'espace récupéré, le temps vacuum passé sur `IO:DataFileRead` diminue.

**Ingestion de grandes quantités de données**  
Lorsque votre application ingère de grandes quantités de données, les opérations `ANALYZE` peuvent être plus fréquentes. Le processus `ANALYZE` peut être déclenché par un lanceur autovacuum, ou être appelé manuellement.  
L'opération `ANALYZE` lit un sous-ensemble de la table. Le nombre de pages à analyser est calculé en multipliant 30 par la valeur `default_statistics_target`. Pour plus d’informations, consultez la [documentation sur PostgreSQL](https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET). Le paramètre `default_statistics_target` accepte des valeurs comprises entre 1 et 10 000, la valeur par défaut étant 100.

**Pénurie de ressources**  
Si l'UC ou la bande passante réseau de l'instance sont entièrement utilisés, l'événement `IO:DataFileRead` peut se produire plus fréquemment.

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d’attente.

**Topics**
+ [

### Vérifiez les filtres de prédicat pour détecter les requêtes qui génèrent des attentes
](#wait-event.iodatafileread.actions.filters)
+ [

### Minimisez l'effet des opérations de maintenance
](#wait-event.iodatafileread.actions.maintenance)
+ [

### Réagissez à un nombre élevé de connexions
](#wait-event.iodatafileread.actions.connections)

### Vérifiez les filtres de prédicat pour détecter les requêtes qui génèrent des attentes
<a name="wait-event.iodatafileread.actions.filters"></a>

Supposons que vous identifiez des requêtes spécifiques qui génèrent des événements d'attente `IO:DataFileRead`. Vous pouvez les identifier à l'aide des techniques suivantes :
+ Performance Insights
+ Vues catalogue telles que celles fournies par l'extension `pg_stat_statements`
+ Vue catalogue `pg_stat_all_tables`, si elle affiche périodiquement un nombre accru de lectures physiques
+ Vue `pg_statio_all_tables`, si elle montre que les compteurs `_read` sont en augmentation

Nous vous recommandons de déterminer quels filtres sont utilisés dans le prédicat (clause `WHERE`) de ces requêtes. Suivez ces instructions :
+ Exécutez la commande `EXPLAIN`. Dans la sortie, identifiez les types d'analyses utilisés. Une analyse séquentielle n'indique pas nécessairement un problème. Les requêtes qui utilisent des analyses séquentielles produisent naturellement plus d'événements `IO:DataFileRead` par rapport aux requêtes qui utilisent des filtres.

  Vérifiez que la colonne répertoriée dans la clause `WHERE` est indexée. Si ce n'est pas le cas, envisagez de créer un index pour cette colonne. Cette approche évite les analyses séquentielles et réduit le nombre d'événements `IO:DataFileRead`. Si une requête comporte des filtres restrictifs et continue à produire des analyses séquentielles, assurez-vous que les index appropriés sont utilisés.
+ Déterminez si la requête accède à une table très volumineuse. Dans certains cas, le partitionnement d'une table peut améliorer les performances, en permettant à la requête de ne lire que les partitions nécessaires.
+ Examinez la cardinalité (nombre total de lignes) de vos opérations de jointure. Notez le caractère restrictif des valeurs que vous transmettez dans les filtres de la clause `WHERE`. Si possible, ajustez votre requête pour réduire le nombre de lignes transmises à chaque étape du plan.

### Minimisez l'effet des opérations de maintenance
<a name="wait-event.iodatafileread.actions.maintenance"></a>

Les opérations de maintenance telles que `VACUUM` et `ANALYZE` sont importantes. Nous vous recommandons de ne pas les désactiver parce que vous trouvez des événements d’attente `IO:DataFileRead` liés à ces opérations de maintenance. Les approches suivantes peuvent minimiser l’effet de ces opérations :
+ Exécutez les opérations de maintenance manuellement pendant les heures creuses. Cette technique empêche la base de données d'atteindre le seuil des opérations automatiques.
+ Pour les tables très volumineuses, partitionnez la table. Cette technique permet de réduire les frais liés aux opérations de maintenance. La base de données accède uniquement aux partitions qui nécessitent une maintenance.
+ Lorsque vous intégrez de grandes quantités de données, pensez à désactiver la fonction d'analyse automatique.

La fonction autovacuum est automatiquement déclenchée pour une table lorsque la formule suivante est vraie.

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

La vue `pg_stat_user_tables` et le catalogue `pg_class` comportent plusieurs lignes. Une ligne peut correspondre à une ligne de votre table. Cette formule suppose que les `reltuples` sont destinés à une table spécifique. Les paramètres `autovacuum_vacuum_scale_factor` (0,20 par défaut) et `autovacuum_vacuum_threshold` (50 tuples par défaut) sont généralement définis globalement pour l'ensemble de l'instance. Vous pouvez toutefois définir des valeurs différentes pour une table spécifique.

**Topics**
+ [

#### Recherche des tables qui consomment de l'espace inutilement
](#wait-event.iodatafileread.actions.maintenance.tables)
+ [

#### Recherche des index qui consomment de l'espace inutilement
](#wait-event.iodatafileread.actions.maintenance.indexes)
+ [

#### Recherchez les tables éligibles au processus autovacuum
](#wait-event.iodatafileread.actions.maintenance.autovacuumed)

#### Recherche des tables qui consomment de l'espace inutilement
<a name="wait-event.iodatafileread.actions.maintenance.tables"></a>

Pour rechercher les tables qui consomment inutilement de l'espace, vous pouvez utiliser les fonctions issues de l'extension PostgreSQL `pgstattuple`. Cette extension (module) est disponible par défaut sur toutes les instances de base de données RDS for PostgreSQL et peut être instanciée sur l'instance à l'aide de la commande suivante.

```
CREATE EXTENSION pgstattuple;
```

Pour plus d'informations sur cette extension, consultez [pgstattuple](https://www.postgresql.org/docs/current/pgstattuple.html) dans la documentation PostgreSQL.

Vous pouvez vérifier qu'il n'existe pas de gonflement de tables et d'index dans votre application. Pour en savoir plus, consultez [Diagnostic du gonflement de la table et de l'index](https://docs.aws.amazon.com//AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html).

#### Recherche des index qui consomment de l'espace inutilement
<a name="wait-event.iodatafileread.actions.maintenance.indexes"></a>

Pour rechercher les index gonflés et estimer la quantité d'espace inutilement consommée sur les tables pour lesquelles vous disposez de privilèges de lecture, vous pouvez exécuter la requête suivante.

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

#### Recherchez les tables éligibles au processus autovacuum
<a name="wait-event.iodatafileread.actions.maintenance.autovacuumed"></a>

Pour rechercher les tables éligibles au processus autovacuum, exécutez la requête suivante.

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

### Réagissez à un nombre élevé de connexions
<a name="wait-event.iodatafileread.actions.connections"></a>

Lorsque vous surveillez Amazon CloudWatch, vous constaterez peut-être que les `DatabaseConnections` statistiques augmentent. Cette augmentation indique un nombre accru de connexions à votre base de données. Nous vous recommandons l'approche suivante :
+ Limitez le nombre de connexions que l'application peut ouvrir avec chaque instance. Si votre application dispose d'une fonction intégrée de regroupement des connexions, définissez-la sur un nombre raisonnable de connexions. Basez le nombre sur ce que le v CPUs de votre instance peut paralléliser efficacement.

  Si votre application n'utilise pas de fonction de regroupement des connexions, envisagez d'utiliser un proxy Amazon RDS ou une autre solution. Cette approche permet à votre application d'ouvrir plusieurs connexions à l'aide de l'équilibreur de charge. L'équilibreur peut alors ouvrir un nombre restreint de connexions avec la base de données. Comme le nombre de connexions exécutées en parallèle est moindre, votre instance de base de données effectue moins de changements de contexte dans le noyau. Les requêtes progressent plus rapidement, ce qui entraîne une diminution des événements d'attente. Pour de plus amples informations, veuillez consulter [Proxy Amazon RDS ](rds-proxy.md).
+ Dans la mesure du possible, tirez parti des réplicas en lecture pour RDS for PostgreSQL. Lorsque votre application exécute une opération en lecture seule, envoyez ces demandes aux réplicas en lecture. Cette technique réduit la I/O pression sur le nœud principal (écrivain).
+ Envisagez une augmentation d'échelle de votre instance de base de données. Une classe d'instances de plus grande capacité offre davantage de mémoire, ce qui permet à RDS for PostgreSQL de disposer d'un groupe de mémoires tampons partagées plus important pour stocker les pages. La plus grande taille donne également à l'instance de base de données plus CPUs de v pour gérer les connexions. More v CPUs est particulièrement utile lorsque les opérations qui génèrent des événements d'`IO:DataFileRead`attente sont des écritures.

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



**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.iowalwrite.context.supported)
+ [

## Contexte
](#wait-event.iowalwrite.context)
+ [

## Causes probables de l’augmentation du nombre d’événements d’attente
](#wait-event.iowalwrite.causes)
+ [

## Actions
](#wait-event.iowalwrite.actions)

## Versions de moteur prises en charge
<a name="wait-event.iowalwrite.context.supported"></a>

Ces informations sur les événements d’attente sont prises en charge pour RDS pour PostgreSQL versions 10 et ultérieures.

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

L'activité de la base de données qui génère les données WAL remplit d'abord les tampons WAL, puis écrit sur le disque de manière asynchrone. L'événement d'attente `IO:WALWrite` est généré quand la session SQL attend la fin de l'écriture des données WAL sur le disque afin de pouvoir libérer l'appel COMMIT de la transaction. 

## Causes probables de l’augmentation du nombre d’événements d’attente
<a name="wait-event.iowalwrite.causes"></a>

Si cet événement d'attente se produit souvent, vous devez examiner votre charge de travail, le type des mises à jour effectuées par votre charge de travail et leur fréquence. En particulier, recherchez les types d'activités suivants.

**Activité DML intense**  
La modification des données dans les tables de base de données ne se produit pas instantanément. Une insertion dans une table peut nécessiter l'attente d'une insertion ou d'une mise à jour dans la même table par un autre client. Les instructions du langage de manipulation de données (DML) permettant de modifier les valeurs des données (INSERT, UPDATE, DELETE, COMMIT, ROLLBACK TRANSACTION) peuvent provoquer des conflits qui obligent le fichier WAL à attendre que les tampons soient vidés. Cette situation est capturée dans les métriques Analyse des performances d'Amazon RDS suivantes, qui indiquent une activité DML intense.  
+  `tup_inserted`
+ `tup_updated`
+ `tup_deleted`
+ `xact_rollback`
+ `xact_commit`
Pour plus d’informations sur ces métriques, consultez [Compteurs Performance Insights pour Amazon RDS pour PostgreSQL](USER_PerfInsights_Counters.md#USER_PerfInsights_Counters.PostgreSQL).

**Activité des points de vérification fréquents**  
Les points de contrôle fréquents contribuent à augmenter le nombre de fichiers WAL. Dans RDS pour PostgreSQL, les écritures de pages complètes sont toujours « activées ». Les écritures de pages complètes favorisent la protection contre les pertes de données. Toutefois, lorsque les points de vérification sont trop fréquents, le système peut rencontrer des problèmes de performances globales. Cela est particulièrement vrai sur les systèmes à activité DML intense. Dans certains cas, vous pouvez trouver des messages d'erreur dans votre fichier `postgresql.log` indiquant que « les points de vérification se produisent trop fréquemment ».   
Lors du réglage des points de vérification, nous vous recommandons de bien équilibrer les performances par rapport au temps nécessaire prévu pour récupérer en cas d'arrêt anormal. 

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

Nous recommandons les actions suivantes pour réduire le nombre de cet événement d'attente.

**Topics**
+ [

### Réduisez le nombre de validations
](#wait-event.iowalwrite.actions.problem)
+ [

### Surveillance de vos points de vérification
](#wait-event.iowalwrite.actions.monitor)
+ [

### Augmenter les E/S
](#wait-event.iowalwrite.actions.scale-io)
+ [

### Volume dédié aux journaux (DLV)
](#wait-event.iowalwrite.actions.dlv)

### Réduisez le nombre de validations
<a name="wait-event.iowalwrite.actions.problem"></a>

Pour réduire le nombre de validations, vous pouvez combiner les instructions en blocs de transactions. Utilisez Analyse des performances d'Amazon RDS pour examiner le type des requêtes en cours d'exécution. Vous pouvez également déplacer les opérations de maintenance importantes à des heures creuses. Par exemple, créez des index ou utilisez les opérations `pg_repack` en dehors des heures de production.

### Surveillance de vos points de vérification
<a name="wait-event.iowalwrite.actions.monitor"></a>

Vous pouvez surveiller deux paramètres pour voir à quelle fréquence votre instance de base de données RDS pour PostgreSQL écrit dans le fichier WAL pour les points de vérification. 
+ `log_checkpoints` – Ce paramètre est « activé » par défaut. Il provoque l'envoi d'un message au journal PostgreSQL pour chaque point de vérification. Ces messages de journal incluent le nombre de tampons écrits, le temps passé à les écrire et le nombre de fichiers WAL ajoutés, supprimés ou recyclés pour le point de vérification donné. 

  Pour plus d'informations sur ce paramètre, consultez [Error Reporting and Logging](https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-CHECKPOINTS) (Signalisation et journalisation des erreurs) dans la documentation PostgreSQL. 
+ `checkpoint_warning` – Ce paramètre définit une valeur seuil (en secondes) pour la fréquence des points de vérification, au-dessus de laquelle un avertissement est généré. Par défaut, ce paramètre n’est pas défini dans RDS pour PostgreSQL. Vous pouvez définir la valeur de ce paramètre pour recevoir un avertissement lorsque les modifications de base de données dans votre instance de base de données RDS pour PostgreSQL sont écrites à une vitesse que les fichiers WAL ne sont pas dimensionnés pour gérer. Par exemple, supposons que vous définissiez ce paramètre sur 30. Si votre instance RDS pour PostgreSQL doit écrire des modifications plus souvent que toutes les 30 secondes, l’avertissement indiquant que « les points de vérification se produisent trop fréquemment » est envoyé dans le journal PostgreSQL. Cela peut indiquer que votre valeur `max_wal_size` doit être augmentée. 

  Pour plus d'informations, consultez [Write Ahead Log](https://www.postgresql.org/docs/current/runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS) dans la documentation PostgreSQL. 

### Augmenter les E/S
<a name="wait-event.iowalwrite.actions.scale-io"></a>

Ce type d'événement d'attente d'entrée/sortie (E/S) peut être corrigé en mettant à l'échelle les opérations d'entrée/sortie par seconde (IOPS) afin de fournir plus rapidement les E/S. La mise à l'échelle des E/S est préférable à la mise à l'échelle du processeur, car la mise à l'échelle du processeur peut entraîner encore plus de conflits d'E/S en gérant plus de travail et aggraver ainsi le goulot d'étranglement d'E/S. En règle générale, nous recommandons d'envisager le réglage de votre charge de travail avant d'exécuter des opérations de mise à l'échelle.

### Volume dédié aux journaux (DLV)
<a name="wait-event.iowalwrite.actions.dlv"></a>

Vous pouvez utiliser un volume dédié aux journaux (DLV) pour une instance de base de données qui utilise le stockage IOPS provisionnés (PIOPS) en utilisant la console Amazon RDS, l’AWS CLI ou l’API Amazon RDS. Un DLV déplace les journaux de transactions de base de données vers un volume de stockage distinct du volume contenant les tables de base de données. Pour plus d’informations, consultez [Volume dédié aux journaux (DLV)](CHAP_Storage.md#CHAP_Storage.dlv).

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

Les événements `IPC:parallel wait events` suivants indiquent qu’une session est en attente d’une communication interprocessus liée aux opérations d’exécution de requêtes parallèles.
+ `IPC:BgWorkerStartup` : un processus attend qu’un processus de travail parallèle termine sa séquence de démarrage. Cela se produit lors de l’initialisation des applications de travail pour l’exécution de requêtes parallèles.
+ `IPC:BgWorkerShutdown` : un processus attend la fin de la séquence d’arrêt d’un processus de travail parallèle. Cela se produit pendant la phase de nettoyage de l’exécution de requêtes parallèles.
+ `IPC:ExecuteGather` : un processus attend de recevoir des données de processus de travail en parallèle pendant l’exécution de la requête. Cela se produit lorsque le processus principal doit recueillir des résultats auprès de ses applications de travail.
+ `IPC:ParallelFinish` : un processus attend que les applications de travail en parallèle terminent leur exécution et publient leurs résultats finaux. Cela se produit pendant la phase de finalisation de l’exécution des requêtes parallèles.

**Topics**
+ [

## Versions de moteur prises en charge
](#rpg-ipc-parallel-context-supported)
+ [

## Contexte
](#rpg-ipc-parallel-context)
+ [

## Causes probables de l’augmentation du nombre d’événements d’attente
](#rpg-ipc-parallel-causes)
+ [

## Actions
](#rpg-ipc-parallel-actions)

## Versions de moteur prises en charge
<a name="rpg-ipc-parallel-context-supported"></a>

Ces informations sur les événements d’attente s’appliquent à toutes les versions d’Aurora PostgreSQL.

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

L’exécution de requêtes parallèles dans PostgreSQL implique la collaboration de plusieurs processus pour le traitement d’une seule requête. Lorsqu’une requête est jugée appropriée pour la parallélisation, un processus principal est coordonné avec un ou plusieurs processus de travail en parallèle en fonction du réglage du paramètre `max_parallel_workers_per_gather`. Le processus principal répartit le travail entre les applications de travail, chaque application de travail traite sa partie des données de manière indépendante et les résultats sont renvoyés au processus principal.

**Note**  
Chaque application de travail en parallèle fonctionne comme un processus distinct dont les besoins en ressources sont similaires à ceux d’une session utilisateur complète. Cela signifie qu'une requête parallèle avec 4 travailleurs peut consommer jusqu'à 5 fois plus de ressources (processeur, mémoire, I/O bande passante) par rapport à une requête non parallèle, car le processus principal et chaque processus de travail conservent leurs propres allocations de ressources. Par exemple, des paramètres tels que `work_mem` sont appliqués individuellement à chaque application de travail, multipliant potentiellement l’utilisation totale de la mémoire entre tous les processus.

L’architecture des requêtes parallèles comprend trois composants principaux :
+ Processus principal : processus clé qui initie l’opération en parallèle, répartit la charge de travail et assure la coordination avec les processus de travail.
+ Processus de travail : processus d’arrière-plan qui exécutent des parties de la requête parallèle.
+ Fusion Gather/Gather : opérations qui combinent les résultats de plusieurs processus de travail pour les renvoyer au processus principal.

Lors d’une exécution en parallèle, les processus doivent communiquer entre eux par le biais de mécanismes de communication interprocessus (IPC). Ces événements d’attente IPC se produisent au cours de différentes phases :
+ Démarrage des applications de travail : lorsque des applications de travail en parallèle sont initialisées
+ Échange de données : lorsque les applications de travail traitent les données et envoient les résultats au processus principal
+ Arrêt des applications de travail : lorsque l’exécution en parallèle est terminée et que les applications de travail sont arrêtées
+ Points de synchronisation : lorsque les processus doivent se coordonner ou attendre que d’autres processus terminent leurs tâches

Il est essentiel de comprendre ces événements d’attente pour pouvoir résoudre les problèmes de performances liés à l’exécution de requêtes parallèles, en particulier dans les environnements à forte concurrence dans lesquels plusieurs requêtes parallèles peuvent s’exécuter simultanément.

## Causes probables de l’augmentation du nombre d’événements d’attente
<a name="rpg-ipc-parallel-causes"></a>

Plusieurs facteurs peuvent contribuer à augmenter le nombre d’événements d’attente IPC liés à l’exécution de requêtes parallèles :

**Forte concurrence des requêtes parallèles**  
Lorsque de nombreuses requêtes parallèles sont exécutées simultanément, cela peut entraîner une contention des ressources et une augmentation des temps d’attente pour les opérations IPC. Cela est particulièrement courant dans les systèmes impliquant des volumes de transactions ou des charges de travail analytiques élevés.

**Plans de requêtes parallèles sous-optimaux**  
Si le planificateur de requêtes choisit des plans de requêtes parallèles inefficaces, cela peut entraîner une parallélisation inutile ou une mauvaise répartition du travail entre les applications de travail. Cela peut entraîner une augmentation des temps d’attente IPC, en particulier pour les événements `IPC:ExecuteGather` et `IPC:ParallelFinish`. Ces problèmes de planification sont souvent dus à des statistiques périmées et table/index à des excès.

**Démarrage et arrêt fréquents des applications de travail en parallèle**  
Les requêtes de courte durée qui déclenchent et interrompent fréquemment des applications de travail en parallèle peuvent entraîner une augmentation du nombre d’événements `IPC:BgWorkerStartup` et `IPC:BgWorkerShutdown`. Cela se produit souvent dans les charges de travail OLTP, qui impliquent beaucoup de petites requêtes pouvant être exécutées en parallèle.

**Contraintes liées aux ressources**  
Un processeur, une mémoire ou une I/O capacité limités peuvent entraîner des blocages lors de l'exécution en parallèle, ce qui augmente les temps d'attente pour tous les événements IPC. Par exemple, si le processeur est saturé, les processus de travail peuvent mettre plus de temps à démarrer ou à traiter leur part du travail.

**Structures de requête complexes**  
Les requêtes comportant plusieurs niveaux de parallélisme (jointures en parallèle suivies d’agrégations parallèles, par exemple) peuvent entraîner des modèles IPC plus complexes et des temps d’attente potentiellement accrus, en particulier pour les événements `IPC:ExecuteGather`.

**Ensembles de résultats volumineux**  
Les requêtes qui génèrent des ensembles de résultats volumineux peuvent entraîner une augmentation des temps d’attente `IPC:ExecuteGather`, car le processus principal passe plus de temps à collecter et à traiter les résultats des processus de travail.

La compréhension de ces facteurs peut aider à diagnostiquer et à résoudre les problèmes de performances liés à l’exécution de requêtes parallèles dans Aurora PostgreSQL.

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

Lorsque vous voyez des temps d’attente liés à une requête parallèle, cela signifie généralement qu’un processus dorsal coordonne ou attend des processus de travail parallèles. Ces temps d’attente sont courants lors de l’exécution de plans en parallèle. Vous pouvez étudier et atténuer l’impact de ces temps d’attente en surveillant l’utilisation des applications de travail en parallèle, en vérifiant les paramètres et en ajustant l’exécution des requêtes et l’allocation des ressources.

**Topics**
+ [

### Analyse des plans de requêtes pour détecter un parallélisme inefficace
](#rpg-ipc-parallel-analyze-plans)
+ [

### Surveillance de l’utilisation des requêtes parallèles
](#rpg-ipc-parallel-monitor)
+ [

### Vérification et ajustement des paramètres des requêtes parallèles
](#rpg-ipc-parallel-adjust-settings)
+ [

### Optimisation de l’allocation des ressources
](#rpg-ipc-parallel-optimize-resources)
+ [

### Vérification de la gestion des connexions
](#rpg-ipc-parallel-connection-management)
+ [

### Vérification et optimisation des opérations de maintenance
](#rpg-ipc-parallel-maintenance)

### Analyse des plans de requêtes pour détecter un parallélisme inefficace
<a name="rpg-ipc-parallel-analyze-plans"></a>

L’exécution de requêtes parallèles peut souvent entraîner une instabilité du système, des pics de processeur et des variations imprévisibles des performances des requêtes. Il est essentiel d’analyser de manière approfondie si le parallélisme améliore réellement votre charge de travail spécifique. Utilisez EXPLAIN ANALYZE pour passer en revue les plans d’exécution de requêtes parallèles.

Désactivez temporairement le parallélisme au niveau de la session pour comparer l’efficacité du plan :

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

Réactivez le parallélisme et comparez :

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

Si la désactivation du parallélisme donne des résultats meilleurs ou plus cohérents, envisagez de le désactiver pour des requêtes spécifiques au niveau de la session à l’aide des commandes SET. Pour un impact plus large, vous pouvez désactiver le parallélisme au niveau de l’instance en ajustant les paramètres pertinents dans le groupe de paramètres de votre base de données. Pour plus d’informations, consultez [Modification de paramètres dans un groupe de paramètres de base de données dans Amazon RDS](USER_WorkingWithParamGroups.Modifying.md).

### Surveillance de l’utilisation des requêtes parallèles
<a name="rpg-ipc-parallel-monitor"></a>

Utilisez les requêtes suivantes pour avoir une meilleure visibilité sur l’activité et la capacité des requêtes parallèles :

Vérifiez les processus de travail en parallèle actifs :

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

Cette requête indique le nombre de processus de travail en parallèle actifs. Une valeur élevée peut indiquer que le paramètre max\$1parallel\$1workers est configuré avec une valeur élevée, ce que vous pouvez choisir de réduire.

Vérifiez les requêtes parallèles simultanées :

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

Cette requête renvoie le nombre de processus principaux distincts qui ont lancé des requêtes parallèles. Un nombre élevé indique que plusieurs sessions exécutent des requêtes parallèles simultanément, ce qui peut augmenter la demande en termes de processeur et de mémoire.

### Vérification et ajustement des paramètres des requêtes parallèles
<a name="rpg-ipc-parallel-adjust-settings"></a>

Passez en revue les paramètres suivants pour vous assurer qu’ils correspondent à votre charge de travail :
+ `max_parallel_workers` : nombre total d’applications de travail en parallèle entre toutes les sessions.
+ `max_parallel_workers_per_gather` : nombre maximum d’applications de travail par requête.

Pour les charges de travail OLAP, l’augmentation de ces valeurs peut améliorer les performances. Pour les charges de travail OLTP, des valeurs plus faibles sont généralement préférées.

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

### Optimisation de l’allocation des ressources
<a name="rpg-ipc-parallel-optimize-resources"></a>

Surveillez l'utilisation du processeur et envisagez d'ajuster le nombre de v CPUs s'il est constamment élevé et si votre application bénéficie de requêtes parallèles. Assurez-vous que la mémoire disponible est suffisante pour les opérations en parallèle.
+ Utilisez les métriques Performance Insights pour déterminer si le système est lié au processeur.
+ Chaque application de travail en parallèle utilise sa propre `work_mem`. Assurez-vous que l’utilisation totale de la mémoire respecte les limites de l’instance.

Les requêtes parallèles peuvent consommer beaucoup plus de ressources que les requêtes qui ne sont pas exécutées en parallèle, car chaque processus de travail est un processus complètement distinct qui a à peu près le même impact sur le système qu’une session utilisateur supplémentaire. Cela doit être pris en compte lors du choix d’une valeur pour ce paramètre, ainsi que lors de la configuration des autres paramètres contrôlant l’utilisation des ressources, tels que `work_mem`. Pour plus d’informations, consultez la [documentation sur PostgreSQL](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM). Les limites de ressources telles que `work_mem` sont appliquées individuellement à chaque application de travail, ce qui signifie que l’utilisation totale peut être beaucoup plus élevée entre tous les processus qu’elle ne le serait normalement pour un seul processus.

Envisagez d'augmenter v CPUs ou de régler les paramètres de mémoire si votre charge de travail est fortement parallélisée.

### Vérification de la gestion des connexions
<a name="rpg-ipc-parallel-connection-management"></a>

En cas de saturation des connexions, passez en revue les stratégies de regroupement des connexions des applications. Envisagez d’implémenter le regroupement de connexions au niveau de l’application s’il n’est pas déjà utilisé.

### Vérification et optimisation des opérations de maintenance
<a name="rpg-ipc-parallel-maintenance"></a>

Coordonnez la création d’index et les autres tâches de maintenance pour éviter les conflits de ressources. Pensez à planifier ces opérations pendant les heures creuses. Évitez de planifier de lourdes opérations de maintenance (par exemple, des constructions d’index en parallèle) pendant les périodes de forte charge des requêtes utilisateur. Ces opérations peuvent consommer des applications de travail en parallèle et avoir un impact sur les performances des requêtes régulières.

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

L'`IPC:ProcArrayGroupUpdate`événement se produit lorsqu'une session attend que le chef de groupe mette à jour le statut de la transaction à la fin de cette opération. Alors que PostgreSQL associe généralement les événements d'attente de type IPC aux opérations de requêtes parallèles, cet événement d'attente particulier n'est pas spécifique aux requêtes parallèles.

**Topics**
+ [

## Versions de moteur prises en charge
](#apg-rpg-ipcprocarraygroup.supported)
+ [

## Contexte
](#apg-rpg-ipcprocarraygroup.context)
+ [

## Causes probables de l’augmentation du nombre d’événements d’attente
](#apg-rpg-ipcprocarraygroup.causes)
+ [

## Actions
](#apg-rpg-ipcprocarraygroup.actions)

## Versions de moteur prises en charge
<a name="apg-rpg-ipcprocarraygroup.supported"></a>

Ces informations sur les événements d’attente sont prises en charge pour toutes les versions de RDS pour PostgreSQL.

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

**Comprendre le tableau de processus** — Le tableau de processus (proc) est une structure de mémoire partagée dans PostgreSQL. Il contient des informations sur tous les processus en cours, y compris les détails des transactions. Au cours de la fin de la transaction (`COMMIT`ou`ROLLBACK`), il ProcArray doit être mis à jour pour refléter le changement et effacer le TransactionID du tableau. La session qui tente de terminer sa transaction doit acquérir un verrou exclusif sur le ProcArray. Cela empêche d'autres processus d'obtenir des verrous partagés ou exclusifs sur celui-ci.

**Mécanisme de mise à jour de groupe** — Lors de l'exécution d'un COMMIT ou d'un ROLLBACK, si un processus principal ne parvient pas à obtenir un ProcArrayLock code en mode exclusif, il met à jour un champ spécial appelé. ProcArrayGroupMember Cela ajoute la transaction à la liste des sessions qui ont l'intention de se terminer. Ce processus principal est ensuite mis en veille et le temps qu'il passe en veille est instrumenté comme événement d' ProcArrayGroupUpdate attente. Le premier processus du ProcArray with procArrayGroup Member, appelé processus leader, acquiert ProcArrayLock le mode exclusif. Il efface ensuite la liste des processus en attente d'effacement de l'identifiant de transaction du groupe. Une fois cette opération terminée, le leader libère ProcArrayLock puis réveille tous les processus de cette liste, les informant que leur transaction est terminée.

## Causes probables de l’augmentation du nombre d’événements d’attente
<a name="apg-rpg-ipcprocarraygroup.causes"></a>

Plus le nombre de processus en cours d'exécution est élevé, plus un leader conservera longtemps un procArrayLock mode exclusif. Par conséquent, plus le nombre de transactions d'écriture aboutit à un scénario de mise à jour de groupe, ce qui entraîne une accumulation potentielle de processus en attente de l'événement d'`ProcArrayGroupUpdate`attente. Dans la vue SQL principale de Database Insights, vous verrez que COMMIT est l'instruction présentant la majeure partie de cet événement d'attente. Cela est normal, mais cela nécessitera une étude plus approfondie du code SQL d'écriture spécifique en cours d'exécution afin de déterminer les mesures appropriées à prendre.

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d’attente. Identifiez les `IPC:ProcArrayGroupUpdate` événements à l'aide d'Amazon RDS Performance Insights ou en interrogeant la vue système de PostgreSQL. `pg_stat_activity`

**Topics**
+ [

### Surveillance des opérations de validation et d'annulation des transactions
](#apg-rpg-ipcprocarraygroup.actions.monitor)
+ [

### Réduire la simultanéité
](#apg-rpg-ipcprocarraygroup.actions.concurrency)
+ [

### Mise en œuvre du regroupement de connexions
](#apg-rpg-ipcprocarraygroup.actions.pooling)
+ [

### Utilisation d'un stockage plus rapide
](#apg-rpg-ipcprocarraygroup.actions.storage)

### Surveillance des opérations de validation et d'annulation des transactions
<a name="apg-rpg-ipcprocarraygroup.actions.monitor"></a>

**Surveillez les validations et les annulations** — L'augmentation du nombre de validations et de annulations peut entraîner une pression accrue sur le. ProcArray Par exemple, si une instruction SQL commence à échouer en raison d'une augmentation du nombre de violations de clés dupliquées, vous pouvez assister à une augmentation des annulations, ce qui peut accroître les ProcArray contentions et le surpeuplement des tables.

Amazon RDS Database Insights fournit les `xact_commit` métriques PostgreSQL et indique le nombre de validations `xact_rollback` et de rollbacks par seconde.

### Réduire la simultanéité
<a name="apg-rpg-ipcprocarraygroup.actions.concurrency"></a>

**Transactions par lots** — Dans la mesure du possible, opérations groupées en transactions uniques afin de réduire les commit/rollback opérations.

**Limiter la simultanéité** — Réduisez le nombre de transactions actives simultanément afin d'atténuer les conflits liés au verrouillage sur le. ProcArray Bien que cela nécessite quelques tests, la réduction du nombre total de connexions simultanées peut réduire les conflits et maintenir le débit.

### Mise en œuvre du regroupement de connexions
<a name="apg-rpg-ipcprocarraygroup.actions.pooling"></a>

**Solutions de regroupement de connexions** : utilisez le regroupement de connexions pour gérer efficacement les connexions aux bases de données, en réduisant le nombre total de backends et donc la charge de travail sur le ProcArray. Bien que cela nécessite quelques tests, la réduction du nombre total de connexions simultanées peut réduire les conflits et maintenir le débit.

**Réduisez les tempêtes de connexion** — De même, une tendance à créer et à terminer fréquemment des connexions entraîne une pression supplémentaire sur le ProcArray. En réduisant ce schéma, la contention globale est réduite.

### Utilisation d'un stockage plus rapide
<a name="apg-rpg-ipcprocarraygroup.actions.storage"></a>

**Volume de journal dédié** — Si l'événement d'`IPC:ProcArrayGroupUpdate`attente s'accompagne d'événements d'`IO:WALWrite`attente élevés, la configuration d'un volume de journal dédié peut réduire le goulot d'étranglement lors de l'écriture sur WAL. Cela améliore à son tour les performances des validations.

Pour plus d'informations, consultez la section [Volume de journal dédié](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PIOPS.dlv.html).

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

L'événement `Lock:advisory` se produit lorsqu'une application PostgreSQL utilise un verrou pour coordonner l'activité sur plusieurs sessions.

**Topics**
+ [

## Versions de moteur pertinentes
](#wait-event.lockadvisory.context.supported)
+ [

## Contexte
](#wait-event.lockadvisory.context)
+ [

## Causes
](#wait-event.lockadvisory.causes)
+ [

## Actions
](#wait-event.lockadvisory.actions)

## Versions de moteur pertinentes
<a name="wait-event.lockadvisory.context.supported"></a>

Ces informations sur les événements d'attente s'appliquent à RDS for PostgreSQL 9.6 et versions ultérieures.

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

Les verrous consultatifs PostgreSQL sont des verrous coopératifs de niveau application explicitement verrouillés et déverrouillés par le code d'application de l'utilisateur. Une application peut utiliser des verrous consultatifs PostgreSQL pour coordonner l'activité sur plusieurs sessions. Contrairement aux verrous standard, de niveau objet ou ligne, l'application dispose d'un contrôle total sur la durée de vie du verrou. Pour en savoir plus, consultez [Advisory Locks](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) dans la documentation PostgreSQL.

Les verrous consultatifs peuvent être libérés avant la fin d'une transaction ou être maintenus par une session sur plusieurs transactions. Cela ne s'applique pas aux verrous implicites appliqués par le système, comme un verrou exclusif d'accès à une table acquis par une instruction `CREATE INDEX`.

Pour accéder à la description des fonctions utilisées pour acquérir (verrouiller) et libérer (déverrouiller) les verrous consultatifs, consultez [Advisory Lock Functions](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS) dans la documentation PostgreSQL.

Les verrous consultatifs sont implémentés au-dessus du système de verrouillage PostgreSQL standard et sont visibles dans la vue système `pg_locks`.

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

Ce type de verrou est exclusivement contrôlé par une application qui l'utilise explicitement. Les verrous consultatifs qui sont acquis pour chaque ligne dans le cadre d'une requête peuvent provoquer un pic de verrous ou une accumulation à long terme.

Ces effets se produisent lorsque la requête est exécutée d'une manière qui acquiert des verrous sur plus de lignes que celles renvoyées par la requête. L'application doit finir par libérer chaque verrou, mais si des verrous sont acquis sur des lignes qui ne sont pas renvoyées, l'application ne peut pas tous les trouver.

L'exemple suivant est extrait de la section [Advisory Locks](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) de la documentation PostgreSQL.

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

Dans cet exemple, la clause `LIMIT` ne peut arrêter la sortie de la requête que lorsque les lignes ont déjà été sélectionnées en interne et que leurs valeurs d'ID ont été verrouillées. Cela peut se produire soudainement lorsqu'un volume de données croissant amène le planificateur à choisir un plan d'exécution différent qui n'a pas été testé lors de la phase de développement. Dans ce cas, l'accumulation se produit parce que l'application appelle explicitement `pg_advisory_unlock` pour chaque valeur d'ID verrouillée. Mais elle ne trouve pas l'ensemble de verrous acquis sur les lignes qui n'ont pas été renvoyées. Comme les verrous sont acquis au niveau de la session, ils ne sont pas libérés automatiquement à la fin de la transaction.

Les pics de tentatives de verrouillage bloquées peuvent également être liés à des conflits involontaires. Lors de ces conflits, des parties non liées de l'application partagent par erreur le même espace d'ID de verrou.

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

Examinez la façon dont les verrous consultatifs sont utilisés par l'application et indiquez où et quand, dans le flux d'application, chaque type de verrou consultatif est acquis et libéré.

Déterminez si une session acquiert trop de verrous ou si une session longue ne libère pas les verrous suffisamment tôt, ce qui entraîne une accumulation lente des verrous. Vous pouvez corriger une accumulation lente de verrous au niveau de la session en mettant fin à la session à l'aide de `pg_terminate_backend(pid)`. 

Un client en attente d'un verrou consultatif apparaît dans `pg_stat_activity` avec `wait_event_type=Lock` et `wait_event=advisory`. Vous pouvez obtenir des valeurs de verrouillage spécifiques en interrogeant la vue système `pg_locks` sur le même `pid`, à la recherche de `locktype=advisory` et `granted=f`.

Vous pouvez ensuite identifier la session de blocage en interrogeant `pg_locks` sur le même verrou consultatif doté de `granted=t`, comme illustré dans l'exemple suivant.

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

Toutes les fonctions d'API des verrous consultatifs comportent deux ensembles d'arguments, soit un argument `bigint`, soit deux arguments `integer` :
+ Pour les fonctions d'API comportant un argument `bigint`, les 32 bits supérieurs figurent dans `pg_locks.classid` et les 32 bits inférieurs se trouvent dans `pg_locks.objid`.
+ Pour les fonctions d'API comportant deux arguments `integer`, le premier argument est `pg_locks.classid` et le deuxième est `pg_locks.objid`.

La valeur `pg_locks.objsubid` indique quelle forme d'API a été utilisée : `1` pour un argument `bigint` et `2` pour deux arguments `integer`.

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

L'événement `Lock:extend` se produit lorsqu'un processus backend attend de verrouiller une relation pour l'étendre alors qu'un autre processus présente un verrou sur cette relation dans le même but.

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.lockextend.context.supported)
+ [

## Contexte
](#wait-event.lockextend.context)
+ [

## Causes probables de l'augmentation du nombre d'événements d'attente
](#wait-event.lockextend.causes)
+ [

## Actions
](#wait-event.lockextend.actions)

## Versions de moteur prises en charge
<a name="wait-event.lockextend.context.supported"></a>

Ces informations sur les événements d'attente sont prises en charge pour toutes les versions de RDS for PostgreSQL.

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

L'événement `Lock:extend` indique qu'un processus backend attend d'étendre une relation sur laquelle un autre processus backend détient un verrou pendant qu'il étend cette relation. Comme un seul processus à la fois peut étendre une relation, le système génère un événement d'attente `Lock:extend`. Les opérations `INSERT`, `COPY` et `UPDATE` peuvent générer cet événement.

## Causes probables de l'augmentation du nombre d'événements d'attente
<a name="wait-event.lockextend.causes"></a>

Un événement `Lock:extend` trop fréquent peut révéler un problème de performances dont les causes sont généralement les suivantes :

**Augmentation du nombre d'insertions ou de mises à jour simultanées dans la même table **  
Le nombre de sessions simultanées associées à des requêtes d'insertion ou de mise à jour peut augmenter.

**Bande passante réseau insuffisante**  
La bande passante réseau de l'instance de base de données peut être insuffisante pour répondre aux besoins de communication de stockage de la charge de travail actuelle. Cela peut contribuer à une latence de stockage qui entraîne une augmentation des événements `Lock:extend`.

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d'attente.

**Topics**
+ [

### Réduisez les insertions et les mises à jour simultanées dans la même relation
](#wait-event.lockextend.actions.action1)
+ [

### Augmentez la bande passante réseau
](#wait-event.lockextend.actions.increase-network-bandwidth)

### Réduisez les insertions et les mises à jour simultanées dans la même relation
<a name="wait-event.lockextend.actions.action1"></a>

Tout d'abord, déterminez s'il y a une augmentation des métriques `tup_inserted` et `tup_updated`, et une augmentation concomitante de cet événement d'attente. Si tel est le cas, déterminez quelles relations sont en conflit pour les opérations d'insertion et de mise à jour. Pour ce faire, interrogez la vue `pg_stat_all_tables` afin de connaître les valeurs des champs `n_tup_ins` et `n_tup_upd`. Pour en savoir plus sur la vue `pg_stat_all_tables`, consultez [pg\$1stat\$1all\$1tables](https://www.postgresql.org/docs/13/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW) dans la documentation PostgreSQL. 

Pour en savoir plus sur les requêtes de blocage et les requêtes bloquées, interrogez `pg_stat_activity` comme dans l'exemple suivant :

```
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
```

Après avoir identifié les relations qui contribuent à l'augmentation des événements `Lock:extend`, utilisez les techniques suivantes pour réduire les conflits :
+ Déterminez si vous pouvez utiliser le partitionnement pour réduire les conflits relatifs à la même table. La séparation des tuples insérés ou mis à jour dans différentes partitions peut réduire les conflits. Pour plus d'informations sur le partitionnement, voir [Gestion des partitions PostgreSQL avec l’extension pg\$1partman](PostgreSQL_Partitions.md).
+ Si l'événement d'attente est principalement dû à une activité de mise à jour, vous pouvez réduire la valeur du facteur de remplissage de la relation. Cela peut réduire les requêtes de nouveaux blocs lors de la mise à jour. Le facteur de remplissage est un paramètre de stockage relatif à une table qui détermine la quantité maximale d'espace requise pour remplir une page de la table. Il est exprimé en pourcentage de l'espace total d'une page. Pour en savoir plus sur le facteur de remplissage, consultez [CREATE TABLE](https://www.postgresql.org/docs/13/sql-createtable.html) dans la documentation PostgreSQL. 
**Important**  
Si vous modifiez le facteur de remplissage, nous vous recommandons vivement de tester votre système, car en fonction de votre charge de travail, la modification de cette valeur peut nuire aux performances.

### Augmentez la bande passante réseau
<a name="wait-event.lockextend.actions.increase-network-bandwidth"></a>

Pour déterminer si la latence d'écriture a augmenté, consultez la métrique `WriteLatency` dans CloudWatch. Le cas échéant, utilisez les métriques Amazon CloudWatch `WriteThroughput` et `ReadThroughput` pour surveiller le trafic lié au stockage sur l'instance de base de données. Ces métriques peuvent vous aider à déterminer si la bande passante réseau est suffisante pour l'activité de stockage de votre charge de travail.

Si la bande passante réseau est insuffisante, augmentez-la. Si votre instance de base de données atteint les limites de sa bande passante réseau, le seul moyen d'augmenter la bande passante est d'augmenter la taille de l'instance de base de données.

Pour plus d’informations sur les métriques CloudWatch, consultez [Mesures au CloudWatch niveau de l'instance Amazon pour Amazon RDS](rds-metrics.md#rds-cw-metrics-instance). Pour en savoir plus sur les performances réseau de chaque classe d'instance de base de données, consultez [Mesures au CloudWatch niveau de l'instance Amazon pour Amazon RDS](rds-metrics.md#rds-cw-metrics-instance). 

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

L’événement `Lock:Relation` se produit lorsqu’une requête attend d’acquérir un verrou sur une table ou une vue (relation) actuellement verrouillée par une autre transaction.

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.lockrelation.context.supported)
+ [

## Contexte
](#wait-event.lockrelation.context)
+ [

## Causes probables de l’augmentation du nombre d’événements d’attente
](#wait-event.lockrelation.causes)
+ [

## Actions
](#wait-event.lockrelation.actions)

## Versions de moteur prises en charge
<a name="wait-event.lockrelation.context.supported"></a>

Ces informations sur les événements d’attente sont prises en charge pour toutes les versions de RDS pour PostgreSQL.

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

La plupart des commandes PostgreSQL utilisent implicitement des verrous pour contrôler les accès simultanés aux données des tables. Vous pouvez également utiliser ces verrous explicitement dans le code de votre application grâce à la commande `LOCK`. De nombreux modes de verrouillage ne sont pas compatibles entre eux et peuvent bloquer des transactions lorsqu’ils tentent d’accéder au même objet. Dans ce cas, RDS for PostgreSQL génère un événement `Lock:Relation`. Voici quelques exemples courants :
+ Des verrous exclusifs tels que `ACCESS EXCLUSIVE` peuvent bloquer tous les accès simultanés. Les opérations en langage de définition de données (DDL) telles que `DROP TABLE`, `TRUNCATE`, `VACUUM FULL` et `CLUSTER` acquièrent implicitement des verrous `ACCESS EXCLUSIVE`. `ACCESS EXCLUSIVE` est également le mode de verrouillage par défaut pour les instructions `LOCK TABLE` qui ne spécifient pas explicitement de mode.
+ L’utilisation de `CREATE INDEX (without CONCURRENT)` sur une table entre en conflit avec les instructions du langage de manipulation de données (DML) `UPDATE`, `DELETE` et `INSERT`, qui acquièrent des verrous `ROW EXCLUSIVE`.

Pour en savoir plus sur les verrous de niveau table et les modes de verrouillage conflictuels, consultez [Explicit Locking](https://www.postgresql.org/docs/13/explicit-locking.html) dans la documentation PostgreSQL.

Le déblocage lié aux requêtes et transactions de blocage s’effectue généralement de l’une des manières suivantes :
+ Requête de blocage : l’application peut annuler la requête ou l’utilisateur peut mettre fin au processus. Le moteur peut également forcer la requête à se terminer en raison de l’expiration du délai d’attente d’une instruction de la session ou d’un mécanisme de détection de blocage.
+ Transaction de blocage : une transaction met fin à son blocage lorsqu’elle exécute une instruction `ROLLBACK` ou `COMMIT`. Les restaurations sont également automatiques lorsque les sessions sont déconnectées par un client ou suite à des problèmes de réseau, ou lorsqu’elles sont interrompues. Les sessions peuvent être interrompues lorsque le moteur de base de données est arrêté, lorsque le système est à court de mémoire, etc.

## Causes probables de l’augmentation du nombre d’événements d’attente
<a name="wait-event.lockrelation.causes"></a>

Lorsque l’événement `Lock:Relation` se produit plus fréquemment que la normale, il peut indiquer un problème de performances. Les causes sont généralement les suivantes :

**Augmentation du nombre de sessions simultanées avec des verrous de table conflictuels**  
Le nombre de sessions simultanées peut augmenter lorsque des requêtes verrouillent la même table avec des modes de verrouillage conflictuels.

**Opérations de maintenance**  
Les opérations de maintenance liées à l’état comme `VACUUM` et `ANALYZE` peuvent considérablement augmenter le nombre de verrous en conflit. `VACUUM FULL` acquiert un verrou `ACCESS EXCLUSIVE`, et `ANALYSE` acquiert un verrou `SHARE UPDATE EXCLUSIVE`. Ces deux types de verrous peuvent provoquer un événement d’attente `Lock:Relation`. Les opérations de maintenance des données d’application telles que l’actualisation d’une vue matérialisée peuvent également augmenter le nombre de requêtes et de transactions bloquées.

**Verrous sur les instances de lecture**  
Il peut y avoir un conflit entre les verrous relationnels des volumes en écriture et des volumes en lecture. Actuellement, seuls les verrous relationnels `ACCESS EXCLUSIVE` sont répliqués vers les instances de lecture. Cependant, le verrou relationnel `ACCESS EXCLUSIVE` entrera en conflit avec tout verrou relationnel `ACCESS SHARE` détenu par le volume en lecture. Cela peut entraîner une augmentation des événements d’attente de relation de verrouillage sur le volume en lecture. 

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d’attente.

**Topics**
+ [

### Réduisez l’impact des instructions SQL de blocage
](#wait-event.lockrelation.actions.reduce-blocks)
+ [

### Minimisez l’effet des opérations de maintenance
](#wait-event.lockrelation.actions.maintenance)

### Réduisez l’impact des instructions SQL de blocage
<a name="wait-event.lockrelation.actions.reduce-blocks"></a>

Pour réduire l’impact des instructions SQL de blocage, si possible, modifiez le code de votre application. Voici deux techniques courantes pour réduire les blocages :
+ Utilisez l’option `NOWAIT` : certaines commandes SQL, telles que les instructions `SELECT` et `LOCK` prennent en charge cette option. La directive `NOWAIT` annule la requête liée à la demande de verrou si le verrou ne peut pas être acquis immédiatement. Cette technique permet d’éviter qu’une session de blocage ne provoque un empilement de sessions bloquées derrière elle.

  Par exemple, supposons que la transaction A attende un verrou détenu par la transaction B. Si B demande un verrou sur une table qui est verrouillée par la transaction C, la transaction A peut être bloquée jusqu’à ce que la transaction C se termine. Mais si la transaction B utilise `NOWAIT` lorsqu’elle demande le verrou sur C, elle peut échouer rapidement et faire en sorte que la transaction A n’ait pas à attendre indéfiniment.
+ Utilisez `SET lock_timeout` – Définissez une valeur `lock_timeout` afin de limiter le délai d'attente d'une instruction SQL pour acquérir un verrou sur une relation. Si le verrou n'est pas acquis dans le délai spécifié, la transaction qui a demandé celui-ci est annulée. Définissez cette valeur au niveau de la session.

### Minimisez l’effet des opérations de maintenance
<a name="wait-event.lockrelation.actions.maintenance"></a>

Les opérations de maintenance telles que `VACUUM` et `ANALYZE` sont importantes. Nous vous recommandons de ne pas les désactiver parce que vous trouvez des événements d’attente `Lock:Relation` liés à ces opérations de maintenance. Les approches suivantes peuvent minimiser l’effet de ces opérations :
+ Exécutez les opérations de maintenance manuellement pendant les heures creuses.
+ Pour réduire les attentes `Lock:Relation` causées par les tâches autovacuum, procédez aux réglages nécessaires de la fonction autovacuum. Pour en savoir plus sur le réglage de la fonction autovacuum, consultez [ Utilisation de la fonction autovacuum de PostgreSQL sur Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html) dans le *Guide de l’utilisateur Amazon RDS*.

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

L'événement `Lock:transactionid` se produit lorsqu'une transaction attend un verrou au niveau ligne.

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.locktransactionid.context.supported)
+ [

## Contexte
](#wait-event.locktransactionid.context)
+ [

## Causes probables de l'augmentation du nombre d'événements d'attente
](#wait-event.locktransactionid.causes)
+ [

## Actions
](#wait-event.locktransactionid.actions)

## Versions de moteur prises en charge
<a name="wait-event.locktransactionid.context.supported"></a>

Ces informations sur les événements d’attente sont prises en charge pour toutes les versions de RDS pour PostgreSQL.

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

L'événement `Lock:transactionid` se produit lorsqu'une transaction tente d'acquérir un verrou de niveau ligne qui a déjà été accordé à une transaction exécutée en même temps. La session qui présente l'événement d'attente `Lock:transactionid` est bloquée à cause de ce verrou. Une fois la transaction de blocage terminée dans une instruction `COMMIT` ou `ROLLBACK`, la transaction bloquée peut se poursuivre.

La sémantique de contrôle de simultanéité multiversion de RDS for PostgreSQL garantit l'absence de blocage des processus de lecture par les processus d'écriture, et vice versa. Pour que des conflits se produisent au niveau ligne, les transactions de blocage et les transactions bloquées doivent émettre des instructions conflictuelles des types suivants :
+ `UPDATE`
+ `SELECT … FOR UPDATE`
+ `SELECT … FOR KEY SHARE`

L'instruction `SELECT … FOR KEY SHARE` est un cas particulier. La base de données utilise la clause `FOR KEY SHARE` pour optimiser les performances de l'intégrité référentielle. La présence d'un verrou de niveau ligne sur une ligne peut bloquer les commandes `INSERT`, `UPDATE` et `DELETE` sur d'autres tables qui font référence à la ligne.

## Causes probables de l'augmentation du nombre d'événements d'attente
<a name="wait-event.locktransactionid.causes"></a>

Un événement trop fréquent est généralement dû à des instructions `UPDATE`, `SELECT … FOR UPDATE` ou `SELECT … FOR KEY SHARE` combinées aux conditions suivantes.

**Topics**
+ [

### Forte simultanéité
](#wait-event.locktransactionid.concurrency)
+ [

### État Idle in transaction (Transaction inactive)
](#wait-event.locktransactionid.idle)
+ [

### Transactions de longue durée
](#wait-event.locktransactionid.long-running)

### Forte simultanéité
<a name="wait-event.locktransactionid.concurrency"></a>

RDS for PostgreSQL peut utiliser une sémantique de verrouillage détaillée de niveau ligne. La probabilité de conflits au niveau ligne augmente lorsque les conditions suivantes sont réunies :
+ Une charge de travail à forte simultanéité se dispute les mêmes lignes.
+ La simultanéité augmente.

### État Idle in transaction (Transaction inactive)
<a name="wait-event.locktransactionid.idle"></a>

Parfois, la colonne `pg_stat_activity.state` affiche la valeur `idle in transaction`. Cette valeur apparaît pour les sessions qui ont entamé une transaction, mais qui n'ont pas encore émis de commande `COMMIT` ou `ROLLBACK`. Si la valeur `pg_stat_activity.state` n'est pas `active`, la requête affichée dans `pg_stat_activity` est la plus récente à avoir été exécutée. La session de blocage ne traite pas activement une requête, car une transaction ouverte comporte un verrou.

Si une transaction inactive a acquis un verrou au niveau ligne, cela peut empêcher d'autres sessions de l'acquérir. Cette condition entraîne l'apparition fréquente de l'événement d'attente `Lock:transactionid`. Pour diagnostiquer le problème, examinez la sortie de `pg_stat_activity` et `pg_locks`.

### Transactions de longue durée
<a name="wait-event.locktransactionid.long-running"></a>

Les transactions qui s'exécutent depuis longtemps comportent des verrous pendant longtemps. Ces verrous de longue durée peuvent bloquer l'exécution d'autres transactions.

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

Le verrouillage de ligne correspond à un conflit entre les instructions `UPDATE`, `SELECT … FOR UPDATE` ou `SELECT … FOR KEY SHARE`. Avant de rechercher une solution, déterminez quand ces instructions sont exécutées sur la même ligne. Utilisez ces informations pour choisir une des stratégies décrites dans les sections suivantes.

**Topics**
+ [

### Réagissez à une forte simultanéité
](#wait-event.locktransactionid.actions.problem)
+ [

### Réagissez aux transactions inactives
](#wait-event.locktransactionid.actions.find-blocker)
+ [

### Réagissez aux transactions de longue durée
](#wait-event.locktransactionid.actions.concurrency)

### Réagissez à une forte simultanéité
<a name="wait-event.locktransactionid.actions.problem"></a>

En cas de problème lié à la simultanéité, essayez l'une des techniques suivantes :
+ Réduisez la simultanéité dans l'application. Par exemple, réduisez le nombre de sessions actives.
+ Implémentez un groupe de connexions. Pour savoir comment regrouper des connexions à l'aide de RDS Proxy, consultez [Proxy Amazon RDS ](rds-proxy.md).
+ Concevez l'application ou le modèle de données de manière à éviter les instructions `UPDATE` et `SELECT … FOR UPDATE` conflictuelles. Vous pouvez également réduire le nombre de clés étrangères accessibles par les instructions `SELECT … FOR KEY SHARE`.

### Réagissez aux transactions inactives
<a name="wait-event.locktransactionid.actions.find-blocker"></a>

Si `pg_stat_activity.state` indique `idle in transaction`, utilisez les stratégies suivantes :
+ Si possible, activez la validation automatique. Cette approche empêche les transactions de bloquer d'autres transactions en attendant une instruction `COMMIT` ou `ROLLBACK`.
+ Recherchez les chemins de code qui ne contiennent pas d'instruction `COMMIT`, `ROLLBACK` ou `END`.
+ Assurez-vous que la logique de gestion des exceptions de votre application comporte toujours un chemin vers une `end of transaction` valide.
+ Assurez-vous que votre application traite les résultats des requêtes après avoir mis fin à la transaction avec `COMMIT` ou `ROLLBACK`.

### Réagissez aux transactions de longue durée
<a name="wait-event.locktransactionid.actions.concurrency"></a>

Si des transactions de longue durée sont à l'origine de l'apparition fréquente de `Lock:transactionid`, essayez les stratégies suivantes :
+ N'utilisez pas de verrous de ligne dans les transactions de longue durée.
+ Limitez la longueur des requêtes en implémentant la validation automatique chaque fois que possible.

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

L'événement `Lock:tuple` se produit lorsqu'un processus backend attend d'acquérir un verrou sur un tuple.

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.locktuple.context.supported)
+ [

## Contexte
](#wait-event.locktuple.context)
+ [

## Causes probables de l'augmentation du nombre d'événements d'attente
](#wait-event.locktuple.causes)
+ [

## Actions
](#wait-event.locktuple.actions)

## Versions de moteur prises en charge
<a name="wait-event.locktuple.context.supported"></a>

Ces informations sur les événements d'attente sont prises en charge pour toutes les versions de RDS for PostgreSQL.

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

L'événement `Lock:tuple` indique qu'un backend attend d'acquérir un verrou sur un tuple alors qu'un autre moteur détient un verrou conflictuel sur le même tuple. Le tableau suivant illustre un scénario dans lequel les sessions génèrent l'événement `Lock:tuple`.


|  Heure  |  Session 1  |  Session 2  |  Session 3  | 
| --- | --- | --- | --- | 
|  t1  |  Démarre une transaction.  |    |    | 
|  t2  |  Met à jour la ligne 1.  |    |    | 
|  t3  |    |  Met à jour la ligne 1. La session acquiert un verrou exclusif sur le tuple, puis attend que la session 1 libère le verrou par le biais d'une validation ou d'une restauration.  |    | 
|  t4  |    |    |  Met à jour la ligne 1. La session attend que la session 2 libère le verrou exclusif sur le tuple.  | 

Vous pouvez également simuler cet événement d'attente à l'aide de l'outil de définition de points de référence `pgbench`. Configurez un nombre élevé de sessions simultanées pour mettre à jour la même ligne au sein d'une table avec un fichier SQL personnalisé.

Pour en savoir plus sur les modes de verrouillage conflictuels, consultez [Explicit Locking](https://www.postgresql.org/docs/current/explicit-locking.html) dans la documentation PostgreSQL. Pour en savoir plus sur `pgbench`, consultez [pgbench](https://www.postgresql.org/docs/current/pgbench.html) dans la documentation PostgreSQL.

## Causes probables de l'augmentation du nombre d'événements d'attente
<a name="wait-event.locktuple.causes"></a>

Un événement de ce type trop fréquent peut révéler un problème de performances dont les causes sont généralement les suivantes :
+ Un grand nombre de sessions simultanées tentent d'acquérir un verrou conflictuel pour le même tuple en exécutant des instructions `UPDATE` ou `DELETE`.
+ Les sessions à forte simultanéité exécutent une instruction `SELECT` en utilisant les modes de verrouillage `FOR UPDATE` ou `FOR NO KEY UPDATE`.
+ Divers facteurs poussent les groupes d'applications ou de connexions à ouvrir davantage de sessions pour exécuter les mêmes opérations. Comme de nouvelles sessions tentent de modifier les mêmes lignes, la charge de base de données peut augmenter et un événement `Lock:tuple` peut apparaître.

Pour en savoir plus, consultez [Row-Level Locks](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS) dans la documentation PostgreSQL.

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d'attente.

**Topics**
+ [

### Examinez la logique de votre application
](#wait-event.locktuple.actions.problem)
+ [

### Recherchez la session de blocage
](#wait-event.locktuple.actions.find-blocker)
+ [

### Réduisez la simultanéité lorsqu'elle est forte
](#wait-event.locktuple.actions.concurrency)
+ [

### Résolvez les problèmes liés aux goulots d'étranglement
](#wait-event.locktuple.actions.bottlenecks)

### Examinez la logique de votre application
<a name="wait-event.locktuple.actions.problem"></a>

Déterminez si une session de blocage est restée longtemps dans l'état `idle in transaction`. Si tel est le cas, la solution à court terme peut consister à mettre fin à la session de blocage. Vous pouvez utiliser la fonction `pg_terminate_backend`. Pour en savoir plus sur cette fonction, consultez [Server Signaling Functions](https://www.postgresql.org/docs/13/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL) dans la documentation PostgreSQL.

Pour une solution à long terme, procédez comme suit :
+ Modifiez la logique de l'application.
+ Utilisez le paramètre `idle_in_transaction_session_timeout`. Ce paramètre met fin à toute session associée à une transaction ouverte qui est restée inactive plus longtemps que la durée spécifiée. Pour en savoir plus, consultez [Client Connection Defaults](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT) dans la documentation PostgreSQL.
+ Chaque fois que possible, utilisez la validation automatique. Pour en savoir plus, consultez [SET AUTOCOMMIT](https://www.postgresql.org/docs/current/ecpg-sql-set-autocommit.html) dans la documentation PostgreSQL.

### Recherchez la session de blocage
<a name="wait-event.locktuple.actions.find-blocker"></a>

Pendant l'événement d'attente `Lock:tuple`, identifiez le blocage et la session bloquée en déterminant quels verrous dépendent les uns des autres. Pour en savoir plus, consultez [Lock dependency information](https://wiki.postgresql.org/wiki/Lock_dependency_information) dans le wiki PostgreSQL. 

L'exemple suivant interroge toutes les sessions, en y appliquant le filtre `tuple` et en les classant par `wait_time`.

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

### Réduisez la simultanéité lorsqu'elle est forte
<a name="wait-event.locktuple.actions.concurrency"></a>

L'événement `Lock:tuple` peut se produire constamment, en particulier lorsque la charge de travail est élevée. Dans ce cas, réduisez la simultanéité pour les lignes très occupées. Souvent, quelques lignes seulement contrôlent une file d'attente ou la logique booléenne, ce qui explique pourquoi ces lignes sont très occupées.

Vous pouvez réduire la simultanéité en utilisant différentes approches basées sur les besoins métier, la logique de l'application et le type de charge de travail. Par exemple, vous pouvez effectuer les opérations suivantes :
+ Redéfinissez la logique de votre table et de vos données pour réduire la simultanéité.
+ Modifiez la logique de l'application pour réduire la simultanéité au niveau ligne.
+ Exploitez et redéfinissez les requêtes avec des verrous de niveau ligne.
+ Utilisez la clause `NOWAIT` lors des nouvelles tentatives.
+ Envisagez d'utiliser un contrôle de simultanéité logique optimiste et à verrouillage hybride.
+ Envisagez de modifier le niveau d'isolement de la base de données.

### Résolvez les problèmes liés aux goulots d'étranglement
<a name="wait-event.locktuple.actions.bottlenecks"></a>

L'événement `Lock:tuple` peut se produire avec des goulots d'étranglement tels qu'une pénurie d'UC ou une saturation de la bande passante d'Amazon EBS. Pour réduire les goulots d'étranglement, adoptez les approches suivantes :
+ Procédez à une augmentation d'échelle de votre type de classe d'instance.
+ Optimisez les requêtes gourmandes en ressources.
+ Modifiez la logique de l'application.
+ Archivez les données rarement consultées.

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

Cet événement se produit lorsqu'une session attend d'associer un bloc de données à une mémoire tampon dans le groupe de mémoires tampons partagées.

**Note**  
Cet événement est nommé `LWLock:BufferMapping` pour RDS for PostgreSQL 13 et versions ultérieures. Pour RDS for PostgreSQL version 12 et versions antérieures, cet événement est nommé `LWLock:buffer_mapping`. 

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.lwl-buffer-mapping.context.supported)
+ [

## Contexte
](#wait-event.lwl-buffer-mapping.context)
+ [

## Causes
](#wait-event.lwl-buffer-mapping.causes)
+ [

## Actions
](#wait-event.lwl-buffer-mapping.actions)

## Versions de moteur prises en charge
<a name="wait-event.lwl-buffer-mapping.context.supported"></a>

Ces informations sur les événements d'attente s'appliquent à RDS for PostgreSQL 9.6 et versions ultérieures.

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

Le *groupe de mémoires tampons partagées* est une zone de mémoire PostgreSQL qui contient toutes les pages actuellement ou précédemment utilisées par les processus. Lorsqu'un processus a besoin d'une page, il la lit dans le groupe de mémoires tampons partagées. Le paramètre `shared_buffers` définit la taille de la mémoire tampon partagée et réserve une zone de mémoire pour stocker la table et les pages d'index. Si vous modifiez ce paramètre, veillez à redémarrer la base de données.

L'événement d'attente `LWLock:buffer_mapping` se produit dans les scénarios suivants :
+ Un processus recherche une page dans la table des mémoires tampons et acquiert un verrou de mappage de mémoire tampon partagée.
+ Un processus charge une page dans le groupe de mémoires tampons et acquiert un verrou exclusif de mappage de mémoire tampon.
+ Un processus supprime une page du groupe et acquiert un verrou exclusif de mappage de mémoire tampon.

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

Lorsque cet événement se produit plus souvent qu'à l'accoutumée, indiquant un possible problème de performances, la base de données effectue une pagination dans et hors du groupe de mémoires tampons partagées. Les causes sont généralement les suivantes :
+ Requêtes volumineuses
+ Index et tables gonflés
+ Analyses de tables complètes
+ Taille de groupe partagé inférieure à celle de l'ensemble de travail

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d’attente.

**Topics**
+ [

### Surveillez les métriques liées à la mémoire tampon
](#wait-event.lwl-buffer-mapping.actions.monitor-metrics)
+ [

### Évaluez votre stratégie d'indexation
](#wait-event.lwl-buffer-mapping.actions.indexes)
+ [

### Réduisez le nombre de mémoires tampons qui doivent être allouées rapidement
](#wait-event.lwl-buffer-mapping.actions.buffers)

### Surveillez les métriques liées à la mémoire tampon
<a name="wait-event.lwl-buffer-mapping.actions.monitor-metrics"></a>

Lorsque les événements d'attente `LWLock:buffer_mapping` atteignent un pic, examinez le taux d'accès à la mémoire tampon. Vous pouvez utiliser ces métriques pour mieux comprendre ce qui se passe dans le cache de mémoire tampon. Examinez les métriques suivantes :

`blks_hit`  
Cette métrique de compteur Performance Insights indique le nombre de blocs qui ont été récupérés à partir du groupe de mémoires tampons partagées. Après l'apparition de l'événement d'attente `LWLock:buffer_mapping`, vous pouvez observer un pic dans `blks_hit`.

`blks_read`  
Ce compteur Performance Insights indique le nombre de blocs devant I/O être lus dans le pool de mémoire tampon partagé. Vous observerez peut-être un pic de `blks_read` dans la période précédant l'événement d'attente `LWLock:buffer_mapping`.

### Évaluez votre stratégie d'indexation
<a name="wait-event.lwl-buffer-mapping.actions.indexes"></a>

Pour vous assurer que votre stratégie d'indexation ne nuit pas aux performances, vérifiez les éléments suivants :

Gonflement des index  
Assurez-vous que le gonflement des index et des tables n'entraîne pas la lecture de pages inutiles dans la mémoire tampon partagée. Si vos tables contiennent des lignes inutilisées, archivez les données et supprimez les lignes des tables. Vous pouvez ensuite reconstruire les index des tables redimensionnées.

Index pour les requêtes fréquemment utilisées  
Pour déterminer si vos index sont optimaux, surveillez les métriques du moteur de base de données dans Performance Insights. La métrique `tup_returned` indique le nombre de lignes lues. La métrique `tup_fetched` indique le nombre de lignes renvoyées au client. Si la métrique `tup_returned` est nettement supérieure à la métrique `tup_fetched`, les données risquent de ne pas être correctement indexées. De plus, les statistiques de votre table ne sont peut-être pas à jour.

### Réduisez le nombre de mémoires tampons qui doivent être allouées rapidement
<a name="wait-event.lwl-buffer-mapping.actions.buffers"></a>

Pour réduire le nombre d'événements d'attente `LWLock:buffer_mapping`, essayez de réduire le nombre de mémoires tampons qui doivent être allouées rapidement. Une stratégie consiste à effectuer des opérations par lots de plus petite taille. Vous pouvez obtenir des lots plus petits en partitionnant vos tables.

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

L'événement `LWLock:BufferIO` se produit quand RDS for PostgreSQL attend que d'autres processus terminent leurs opérations d'entrée/sortie (E/S) en cas de tentative simultanée d'accès à une page. Le but est que la même page soit lue dans la mémoire tampon partagée.

**Topics**
+ [

## Versions de moteur pertinentes
](#wait-event.lwlockbufferio.context.supported)
+ [

## Contexte
](#wait-event.lwlockbufferio.context)
+ [

## Causes
](#wait-event.lwlockbufferio.causes)
+ [

## Actions
](#wait-event.lwlockbufferio.actions)

## Versions de moteur pertinentes
<a name="wait-event.lwlockbufferio.context.supported"></a>

Ces informations sur les événements d'attente s'appliquent à toutes les versions de RDS for PostgreSQL. Pour RDS for PostgreSQL 12 et versions antérieures, cet événement d'attente est nommé lwlock:buffer\$1io, tandis qu'il est nommé lwlock:bufferio dans la version RDS for PostgreSQL 13. Depuis la version RDS for PostgreSQL 14, l'événement d'attente BufferIO est passé du type d'événement d'attente (IPC:Bufferio) `LWLock` à `IPC`. 

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

Chaque mémoire tampon partagée possède un verrou I/O qui est associé à l'événement d'attente `LWLock:BufferIO`, chaque fois qu'un bloc (ou une page) doit être récupéré en dehors du groupe de mémoires tampons partagées.

Ce verrou est utilisé pour gérer plusieurs sessions qui ont toutes besoin d'accéder au même bloc. Ce bloc doit être lu en dehors du groupe de mémoires tampons partagées, défini par le paramètre `shared_buffers`.

Dès que la page est lue dans le groupe de mémoires tampons partagées, le verrou `LWLock:BufferIO` est libéré.

**Note**  
L'événement d'attente `LWLock:BufferIO` précède l'événement d'attente [IO : DataFileRead](wait-event.iodatafileread.md). L'événement d'attente `IO:DataFileRead` se produit lorsque les données sont lues à partir du stockage.

Pour en savoir plus sur les verrous légers, consultez [Présentation du verrouillage](https://github.com/postgres/postgres/blob/65dc30ced64cd17f3800ff1b73ab1d358e92efd8/src/backend/storage/lmgr/README#L20).

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

Les principales causes de l'événement d'attente `LWLock:BufferIO` sont les suivantes :
+ Plusieurs backends ou connexions tentant d'accéder à la même page qui est également en attente d'une opération I/O
+ Rapport entre la taille du groupe de mémoires tampons partagées (défini par le paramètre `shared_buffers`) et le nombre de mémoires tampons nécessaires à la charge de travail actuelle
+ La taille du groupe de mémoires tampons partagées n'est pas bien équilibrée par rapport au nombre de pages expulsées par d'autres opérations
+ Index volumineux ou gonflés qui obligent le moteur à lire plus de pages que nécessaire dans le groupe de mémoires tampons partagées
+ Absence d'index qui oblige le moteur de base de données à lire plus de pages que nécessaire dans les tables
+ Points de contrôle trop fréquents ou nécessité de vider un trop grand nombre de pages modifiées
+ Pics soudains de connexions à la base de données tentant d'effectuer des opérations sur la même page

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

Nous vous recommandons différentes actions en fonction de l'origine de votre événement d'attente :
+ Réglez `max_wal_size` et `checkpoint_timeout` en fonction de l'heure de pointe de votre charge de travail si vous constatez que `LWLock:BufferIO` coïncide avec des baisses de la métrique `BufferCacheHitRatio`. Identifiez ensuite la requête qui pourrait en être la cause.
+ Recherchez les index inutilisés et supprimez-les.
+ Utilisez des tables partitionnées (qui comportent également des index partitionnés). Cela permet de limiter la réorganisation des index et de réduire son impact.
+ Évitez d'indexer inutilement des colonnes.
+ Empêchez les pics soudains de connexions à la base de données en utilisant un groupe de connexions.
+ En guise de bonne pratique, limitez le nombre maximal de connexions à la base de données.

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

L'événement `LWLock:buffer_content` se produit lorsqu'une session attend de lire ou d'écrire une page de données en mémoire alors que celle-ci est verrouillée en écriture dans une autre session. Dans RDS for PostgreSQL 13 et versions ultérieures, cet événement d'attente est appelé `BufferContent`.

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.lwlockbuffercontent.context.supported)
+ [

## Contexte
](#wait-event.lwlockbuffercontent.context)
+ [

## Causes probables de l'augmentation du nombre d'événements d'attente
](#wait-event.lwlockbuffercontent.causes)
+ [

## Actions
](#wait-event.lwlockbuffercontent.actions)

## Versions de moteur prises en charge
<a name="wait-event.lwlockbuffercontent.context.supported"></a>

Ces informations sur les événements d'attente sont prises en charge pour toutes les versions de RDS for PostgreSQL.

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

Pour lire ou manipuler des données, PostgreSQL y accède via des mémoires tampons partagées. Pour lire à partir de la mémoire tampon, un processus obtient un verrou léger (LWLock) sur le contenu de la mémoire tampon en mode partagé. Pour écrire dans la mémoire tampon, il obtient ce verrou en mode exclusif. Les verrous partagés permettent à d'autres processus d'acquérir simultanément des verrous partagés sur ce contenu. Les verrous exclusifs empêchent les autres processus d'obtenir tout type de verrou sur ce contenu.

L'événement `LWLock:buffer_content` (`BufferContent`) indique que plusieurs processus tentent d'obtenir un verrou sur le contenu d'une mémoire tampon spécifique.

## Causes probables de l'augmentation du nombre d'événements d'attente
<a name="wait-event.lwlockbuffercontent.causes"></a>

Un événement `LWLock:buffer_content` (`BufferContent`) trop fréquent peut révéler un problème de performances dont les causes sont généralement les suivantes :

**Augmentation des mises à jour simultanées des mêmes données**  
Le nombre de sessions simultanées associées à des requêtes de mise à jour du même contenu de mémoire tampon peut augmenter. Ce conflit peut être plus marqué sur les tables contenant beaucoup d'index.

**Les données de la charge de travail ne sont pas en mémoire**  
Lorsque les données traitées par la charge de travail active ne sont pas en mémoire, la fréquence de ces événements d'attente peut augmenter. Cet effet est dû au fait que les processus détenant des verrous peuvent les conserver plus longtemps pendant qu'ils effectuent des opérations d'I/O disque.

**Utilisation excessive de contraintes de clé étrangère**  
Les contraintes de clé étrangère peuvent augmenter la durée pendant laquelle un processus conserve un verrou de contenu de mémoire tampon. Cet effet est dû au fait que les opérations de lecture ont besoin d'un verrou de contenu de mémoire tampon partagée sur la clé référencée pendant la mise à jour de cette clé.

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d'attente. Vous pouvez identifier les événements `LWLock:buffer_content` (`BufferContent`) en utilisant Amazon RDS Performance Insights ou en interrogeant la vue `pg_stat_activity`.

**Topics**
+ [

### Améliorez l'efficacité en mémoire
](#wait-event.lwlockbuffercontent.actions.in-memory)
+ [

### Réduisez l'utilisation des contraintes de clé étrangère
](#wait-event.lwlockbuffercontent.actions.foreignkey)
+ [

### Supprimez les index inutilisés
](#wait-event.lwlockbuffercontent.actions.indexes)
+ [

### Augmentation de la taille du cache lors de l'utilisation de séquences
](#wait-event.lwlockbuffercontent.actions.sequences)

### Améliorez l'efficacité en mémoire
<a name="wait-event.lwlockbuffercontent.actions.in-memory"></a>

Pour que les données de la charge de travail active aient plus de chances d'être mises en mémoire, partitionnez les tables ou procédez à une augmentation d'échelle de votre classe d'instance. Pour plus d'informations sur les classes d'instances de base de données, consultez [Classes d'instances de base de données ](Concepts.DBInstanceClass.md).

### Réduisez l'utilisation des contraintes de clé étrangère
<a name="wait-event.lwlockbuffercontent.actions.foreignkey"></a>

Examinez les charges de travail qui présentent un nombre élevé d'événements d'attente `LWLock:buffer_content` (`BufferContent`) pour déterminer si des contraintes de clé étrangère sont utilisées. Supprimez les contraintes de clé étrangère inutiles.

### Supprimez les index inutilisés
<a name="wait-event.lwlockbuffercontent.actions.indexes"></a>

Pour les charges de travail qui présentent un nombre élevé d'événements d'attente `LWLock:buffer_content` (`BufferContent`), identifiez les index inutilisés et supprimez-les.

### Augmentation de la taille du cache lors de l'utilisation de séquences
<a name="wait-event.lwlockbuffercontent.actions.sequences"></a>

Si vos tables utilisent des séquences, augmentez la taille du cache pour éliminer les conflits sur les pages des séquences et les pages d'index. Chaque séquence correspond à une page unique en mémoire partagée. Le cache prédéfini s'applique à chaque connexion. Cela peut ne pas être suffisant pour gérer la charge de travail lorsque de nombreuses sessions simultanées obtiennent une valeur de séquence. 

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

Cet événement se produit lorsque le moteur RDS pour PostgreSQL conserve la zone de mémoire du verrou partagé pour allouer, vérifier et libérer un verrou quand il est impossible d’utiliser un verrou à chemin d’accès rapide.

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.lw-lock-manager.context.supported)
+ [

## Contexte
](#wait-event.lw-lock-manager.context)
+ [

## Causes probables de l'augmentation du nombre d'événements d'attente
](#wait-event.lw-lock-manager.causes)
+ [

## Actions
](#wait-event.lw-lock-manager.actions)

## Versions de moteur prises en charge
<a name="wait-event.lw-lock-manager.context.supported"></a>

Ces informations sur les événements d’attente s’appliquent à RDS pour PostgreSQL 9.6 et versions ultérieures. Pour les versions de RDS pour PostgreSQL antérieures à la version 13, le nom de cet événement d’attente est `LWLock:lock_manager`. Pour RDS pour PostgreSQL 13 et versions ultérieures, le nom de cet événement d’attente est `LWLock:lockmanager`. 

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

Lorsque vous émettez une instruction SQL, RDS pour PostgreSQL enregistre des verrous pour protéger la structure, les données et l’intégrité de votre base de données pendant les opérations simultanées. Le moteur peut atteindre cet objectif en utilisant un verrou à chemin d'accès rapide ou non rapide. Un verrou à chemin d'accès non rapide est plus coûteux et génère plus de frais qu'un verrou à chemin d'accès rapide.

### Verrouillage à chemin d'accès rapide
<a name="wait-event.lw-lock-manager.context.fast-path"></a>

Pour réduire les frais liés aux verrous qui sont fréquemment acquis et libérés, mais qui entrent rarement en conflit, les processus dorsaux peuvent utiliser le verrouillage à chemin d’accès rapide. La base de données utilise ce mécanisme pour les verrous qui répondent aux critères suivants :
+ Ils utilisent la méthode de verrouillage DEFAULT.
+ Ils représentent un verrou sur une relation de base de données plutôt qu'une relation partagée.
+ Il s'agit de verrous faibles qui sont peu susceptibles d'entrer en conflit.
+ Le moteur peut rapidement vérifier qu'aucun verrou conflictuel ne peut exister.

Le moteur ne peut pas utiliser de verrouillage à chemin d'accès rapide lorsque l'une des conditions suivantes est vraie :
+ Le verrou ne répond pas aux critères précédents.
+ Il n’y a plus d’emplacements disponibles pour le processus dorsal.

Pour ajuster vos requêtes pour le verrouillage à chemin d’accès rapide, vous pouvez utiliser la requête suivante.

```
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
```

La requête suivante affiche uniquement le total sur la base de données.

```
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)
```

Pour en savoir plus sur le verrouillage à chemin d'accès rapide, consultez [fast path](https://github.com/postgres/postgres/blob/master/src/backend/storage/lmgr/README#L70-L76) dans le fichier README du gestionnaire de verrous PostgreSQL et [pg-locks](https://www.postgresql.org/docs/9.3/view-pg-locks.html#AEN98195) dans la documentation PostgreSQL. 

### Exemple de problème de mise à l'échelle pour le gestionnaire de verrous
<a name="wait-event.lw-lock-manager.context.lock-manager"></a>

Dans cet exemple, une table nommée `purchases` stocke cinq ans de données, partitionnées par jour. Chaque partition possède deux index. La séquence d'événements suivante se produit :

1. Vous interrogez des données réparties sur différents jours, ce qui oblige la base de données à lire de nombreuses partitions.

1. La base de données crée une entrée de verrou pour chaque partition. Si les index de partition font partie du chemin d'accès de l'optimiseur, la base de données crée également une entrée de verrou pour eux.

1. Lorsque le nombre d’entrées de verrou demandées pour le même processus dorsal est supérieur à 16, ce qui correspond à la valeur de `FP_LOCK_SLOTS_PER_BACKEND`, le gestionnaire de verrous utilise la méthode de verrouillage à chemin d’accès non rapide.

Les applications modernes peuvent comporter des centaines de sessions. Si des sessions simultanées interrogent le parent sans élaguer correctement les partitions, la base de données peut créer des centaines, voire des milliers, de verrous à chemin d'accès non rapide. Généralement, lorsque cette simultanéité est supérieure au nombre de vCPUs, l'événement d'`LWLock:lock_manager`attente apparaît.

**Note**  
L'événement d'attente `LWLock:lock_manager` n'est pas lié au nombre de partitions ou d'index contenus dans un schéma de base de données. Il est plutôt lié au nombre de verrous à chemin d'accès non rapide que la base de données doit contrôler.

## Causes probables de l'augmentation du nombre d'événements d'attente
<a name="wait-event.lw-lock-manager.causes"></a>

Lorsque l'événement d'attente `LWLock:lock_manager` se produit plus souvent qu'à l'accoutumée, indiquant un possible problème de performances, les causes les plus probables des pics soudains sont les suivantes :
+ Les sessions actives simultanées exécutent des requêtes qui n'utilisent pas de verrous à chemin d'accès rapide. Ces sessions dépassent également le nombre maximum de vCPU.
+ Un grand nombre de sessions actives simultanées accèdent à une table fortement partitionnée. Chaque partition possède plusieurs index.
+ La base de données subit une tempête de connexions. Par défaut, certaines applications et certains logiciels de regroupement de connexions créent davantage de connexions lorsque la base de données est lente. Cette pratique aggrave le problème. Réglez le logiciel de regroupement de connexions de manière à éviter les tempêtes de connexions.
+ Un grand nombre de sessions interrogent une table parente sans élaguer les partitions.
+ Un langage de définition de données (DDL), un langage de manipulation de données (DML) ou une commande de maintenance verrouille exclusivement une relation occupée ou des tuples fréquemment consultés ou modifiés.

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

L'événement d'attente `CPU` n'est pas nécessairement lié à un problème de performances. Ne réagissez à cet événement que lorsque les performances se dégradent et que cet événement d'attente domine la charge de la base de données.

**Topics**
+ [

### Élaguez les partitions
](#wait-event.lw-lock-manager.actions.pruning)
+ [

### Supprimez les index inutiles
](#wait-event.lw-lock-manager.actions.indexes)
+ [

### Réglez vos requêtes pour qu'elles utilisent le verrouillage à chemin d'accès rapide
](#wait-event.lw-lock-manager.actions.tuning)
+ [

### Procédez au réglage d'autres événements d'attente
](#wait-event.lw-lock-manager.actions.other-waits)
+ [

### Réduisez les goulots d'étranglement matériels
](#wait-event.lw-lock-manager.actions.hw-bottlenecks)
+ [

### Utilisez une fonction de regroupement de connexions
](#wait-event.lw-lock-manager.actions.pooler)
+ [

### Mise à niveau de votre version de RDS pour PostgreSQL
](#wait-event.lw-lock-manager.actions.pg-version)

### Élaguez les partitions
<a name="wait-event.lw-lock-manager.actions.pruning"></a>

L'*élagage des partitions* est une stratégie d'optimisation des requêtes pour tables partitionnées de manière déclarative, qui exclut les partitions inutiles des analyses de tables, améliorant ainsi les performances. L'élagage des partitions est activé par défaut. S'il est désactivé, activez-le comme suit.

```
SET enable_partition_pruning = on;
```

Les requêtes peuvent tirer parti de l'élagage des partitions lorsque leur clause `WHERE` contient la colonne utilisée pour le partitionnement. Pour en savoir plus, consultez [Partition Pruning](https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITION-PRUNING) dans la documentation PostgreSQL.

### Supprimez les index inutiles
<a name="wait-event.lw-lock-manager.actions.indexes"></a>

Votre base de données peut contenir des index inutilisés ou rarement utilisés. Si tel est le cas, pensez à les supprimer. Effectuez l’une des actions suivantes :
+ Pour en savoir plus sur la recherche des index inutiles, consultez [Unused Indexes](https://wiki.postgresql.org/wiki/Index_Maintenance#Unused_Indexes) dans le wiki PostgreSQL.
+ Exécutez PG Collector. Ce script SQL rassemble les informations de la base de données et les présente sous forme de rapport HTML. Consultez la section « Unused indexes » (Index inutilisés). Pour plus d'informations, consultez [pg-collector](https://github.com/awslabs/pg-collector) dans le référentiel AWS Labs GitHub .

### Réglez vos requêtes pour qu'elles utilisent le verrouillage à chemin d'accès rapide
<a name="wait-event.lw-lock-manager.actions.tuning"></a>

Pour savoir si vos requêtes utilisent le verrouillage à chemin d'accès rapide, interrogez la colonne `fastpath` de la table `pg_locks`. Si vos requêtes n'utilisent pas le verrouillage à chemin d'accès rapide, essayez de réduire le nombre de relations par requête à moins de 16.

### Procédez au réglage d'autres événements d'attente
<a name="wait-event.lw-lock-manager.actions.other-waits"></a>

Si `LWLock:lock_manager` est premier ou deuxième dans la liste des attentes les plus fréquentes, vérifiez si les événements d'attente suivants apparaissent également dans la liste :
+ `Lock:Relation`
+ `Lock:transactionid`
+ `Lock:tuple`

S'ils figurent parmi les premiers de la liste, commencez par régler ces événements d'attente. Ces événements peuvent être un moteur pour `LWLock:lock_manager`.

### Réduisez les goulots d'étranglement matériels
<a name="wait-event.lw-lock-manager.actions.hw-bottlenecks"></a>

Un goulot d'étranglement matériel peut se produire, comme une pénurie d'UC ou une saturation de votre bande passante Amazon EBS. Envisagez alors de réduire les goulots d'étranglement matériels. Procédez comme suit :
+ Procédez à une augmentation d'échelle de votre classe d'instance.
+ Optimisez les requêtes qui sollicitent énormément l'UC et la mémoire.
+ Modifiez la logique de votre application.
+ Archivez vos données.

Pour en savoir plus sur l’UC, la mémoire et la bande passante réseau EBS, consultez [Types d’instance Amazon RDS](https://aws.amazon.com/rds/instance-types/).

### Utilisez une fonction de regroupement de connexions
<a name="wait-event.lw-lock-manager.actions.pooler"></a>

Si le nombre total de connexions actives dépasse le nombre maximal de vCPU, cela signifie que l'UC requise par les processus du système d'exploitation est supérieure à ce que votre type d'instance peut prendre en charge. Dans ce cas, vous pouvez utiliser ou régler un groupe de connexions. Pour plus d'informations sur le v correspondant CPUs à votre type d'instance, consultez [Amazon RDS Instance Types](https://aws.amazon.com/rds/instance-types/).

Pour en savoir plus sur les groupes de connexions, consultez les ressources suivantes :
+ [Proxy Amazon RDS ](rds-proxy.md)
+ [pgbouncer](http://www.pgbouncer.org/usage.html)
+ [Connection Pools and Data Sources](https://www.postgresql.org/docs/7.4/jdbc-datasource.html) dans la *documentation PostgreSQL*

### Mise à niveau de votre version de RDS pour PostgreSQL
<a name="wait-event.lw-lock-manager.actions.pg-version"></a>

Si votre version actuelle de RDS pour PostgreSQL est inférieure à 12, procédez à une mise à niveau vers la version 12 ou ultérieure. PostgreSQL versions 12 et ultérieures disposent d'un mécanisme de partition amélioré. Pour en savoir plus la version 12, consultez [Notes de mise à jour de PostgreSQL 12.0]( https://www.postgresql.org/docs/release/12.0/). Pour plus d’informations sur la mise à niveau de RDS pour PostgreSQL, consultez [Mises à niveau du moteur de base de données RDS pour PostgreSQL](USER_UpgradeDBInstance.PostgreSQL.md).

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

L'événement d' LWLockattente :pg\$1stat\$1statements se produit lorsque l'extension verrouille de manière exclusive la `pg_stat_statements` table de hachage qui suit les instructions SQL. Cela se produit dans les scénarios suivants :
+ Lorsque le nombre d’instructions suivies atteint la valeur de paramètre `pg_stat_statements.max` configurée et qu’il est nécessaire de faire de la place à d’autres entrées, l’extension effectue un tri sur le nombre d’appels, supprime les 5 % des instructions les moins exécutées et remplit à nouveau le hachage avec les entrées restantes.
+ Lorsque `pg_stat_statements` effectue une opération `garbage collection` sur le fichier `pgss_query_texts.stat` sur le disque et réécrit le fichier.

**Topics**
+ [

## Versions de moteur prises en charge
](#apg-rpg-lwlockpgstat.supported)
+ [

## Contexte
](#apg-rpg-lwlockpgstat.context)
+ [

## Causes probables de l’augmentation du nombre d’événements d’attente
](#apg-rpg-lwlockpgstat.causes)
+ [

## Actions
](#apg-rpg-lwlockpgstat.actions)

## Versions de moteur prises en charge
<a name="apg-rpg-lwlockpgstat.supported"></a>

 Ces informations sur les événements d’attente sont prises en charge pour toutes les versions de RDS pour PostgreSQL. 

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

**Comprendre l’extension pg\$1stat\$1statements** : l’extension pg\$1stat\$1statements suit les statistiques d’exécution des instructions SQL dans une table de hachage. L’extension suit les instructions SQL jusqu’à la limite définie par le paramètre `pg_stat_statements.max`. Ce paramètre détermine le nombre maximum d’instructions pouvant être suivies, ce qui correspond au nombre maximum de lignes dans la vue pg\$1stat\$1statements.

**Persistance des statistiques des instructions** : l’extension conserve les statistiques des instructions lors des redémarrages de l’instance en :
+ Écrivant des données dans un fichier nommé pg\$1stat\$1statements.stat
+ Utilisant le paramètre pg\$1stat\$1statements.save pour contrôler le comportement de persistance

Lorsque pg\$1stat\$1statements.save est :
+ activé (par défaut) : les statistiques sont enregistrées à l’arrêt et rechargées au démarrage du serveur
+ désactivé : les statistiques ne sont ni enregistrées à l’arrêt, ni rechargées au démarrage du serveur

**Stockage du texte des requêtes** : l’extension stocke le texte des requêtes suivies dans un fichier nommé `pgss_query_texts.stat`. Ce fichier peut atteindre le double de la taille moyenne de toutes les instructions SQL suivies avant le récupérateur de mémoire. L’extension nécessite un verrouillage exclusif de la table de hachage pendant les opérations de nettoyage et de réécriture du fichier `pgss_query_texts.stat`.

**Processus d’annulation de l’allocation des instructions** : lorsque le nombre d’instructions suivies atteint la limite `pg_stat_statements.max` et que de nouvelles instructions doivent être suivies, l’extension :
+ Prend un verrou exclusif (:pg\$1stat\$1statementsLWLock) sur la table de hachage.
+ Charge les données existantes dans la mémoire locale.
+ Effectue un tri rapide en fonction du nombre d’appels.
+ Supprime les instructions les moins appelées (les 5 % inférieures).
+ Reremplit la table de hachage avec les entrées restantes.

**Surveillance de l’annulation de l’allocation des instructions** : dans PostgreSQL 14 et versions ultérieures, vous pouvez surveiller l’annulation de l’allocation des instructions à l’aide de la vue pg\$1stat\$1statements\$1info. Cette vue inclut une colonne dealloc qui indique le nombre de fois où l’allocation des instructions a été annulée pour faire de la place à de nouvelles.

Si l’annulation de l’allocation des instructions se produit fréquemment, cela accroît la fréquence du récupérateur de mémoire au niveau du fichier `pgss_query_texts.stat` sur le disque.

## Causes probables de l’augmentation du nombre d’événements d’attente
<a name="apg-rpg-lwlockpgstat.causes"></a>

Les causes typiques de l’allongement des temps d’attente de `LWLock:pg_stat_statements` sont les suivantes :
+ Augmentation du nombre de requêtes uniques utilisées par l’application.
+ La valeur du paramètre `pg_stat_statements.max` est faible par rapport au nombre de requêtes uniques utilisées.

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d’attente. Vous pouvez identifier les événements `LWLock:pg_stat_statements` en utilisant Analyse des performances d’Amazon RDS ou en interrogeant la vue `pg_stat_activity`.

Ajustez les `pg_stat_statements` paramètres suivants pour contrôler le comportement de suivi et réduire:les instructions LWLock pg\$1stat\$1 attendent les événements.

**Topics**
+ [

### Désactivation du paramètre pg\$1stat\$1statements.track
](#apg-rpg-lwlockpgstat.actions.disabletrack)
+ [

### Augmentation de la valeur du paramètre pg\$1stat\$1statements.max
](#apg-rpg-lwlockpgstat.actions.increasemax)
+ [

### Désactivation du paramètre pg\$1stat\$1statements.track\$1utility
](#apg-rpg-lwlockpgstat.actions.disableutility)

### Désactivation du paramètre pg\$1stat\$1statements.track
<a name="apg-rpg-lwlockpgstat.actions.disabletrack"></a>

Si l'événement:pg\$1stat\$1statements LWLock wait a un impact négatif sur les performances de la base de données et qu'une solution rapide est requise avant de poursuivre l'analyse de la vue `pg_stat_statements` afin d'identifier la cause première, le paramètre `pg_stat_statements.track` peut être désactivé en le définissant sur. `none` Cela désactive la collecte des statistiques des instructions.

### Augmentation de la valeur du paramètre pg\$1stat\$1statements.max
<a name="apg-rpg-lwlockpgstat.actions.increasemax"></a>

Pour réduire les annulations d’allocation d’instructions et minimiser le récupérateur de mémoire du fichier `pgss_query_texts.stat` sur le disque, augmentez la valeur du paramètre `pg_stat_statements.max`. La valeur par défaut est `5,000`.

**Note**  
Le paramètre `pg_stat_statements.max` est statique. Vous devez redémarrer votre instance de base de données pour appliquer les éventuelles modifications apportées à ce paramètre. 

### Désactivation du paramètre pg\$1stat\$1statements.track\$1utility
<a name="apg-rpg-lwlockpgstat.actions.disableutility"></a>

Vous pouvez analyser la vue pg\$1stat\$1statements pour déterminer les commandes utilitaires consommant le plus de ressources suivies par `pg_stat_statements`.

Le paramètre `pg_stat_statements.track_utility` contrôle si le module suit les commandes utilitaires, qui incluent toutes les commandes sauf SELECT, INSERT, UPDATE, DELETE et MERGE. Par défaut, ce paramètre est défini sur `on`.

Par exemple, lorsque votre application utilise de nombreuses requêtes de point de sauvegarde, qui sont intrinsèquement uniques, cela peut augmenter l’annulation de l’allocation des instructions. Pour résoudre ce problème, vous pouvez désactiver le paramètre `pg_stat_statements.track_utility` pour empêcher `pg_stat_statements` de suivre les requêtes de point de sauvegarde.

**Note**  
Le paramètre `pg_stat_statements.track_utility` est un paramètre dynamique. Vous pouvez modifier sa valeur sans redémarrer votre instance de base de données.

**Example Exemple de requêtes de point de sauvegarde uniques dans 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 inclut plusieurs améliorations pour le suivi des commandes utilitaires :
+ Les noms des points de sauvegarde sont désormais affichés sous forme de constantes.
+ La transaction globale IDs (GIDs) des commandes de validation en deux phases est désormais affichée sous forme de constantes.
+ Les noms des instructions DEALLOCATE sont affichés sous forme de constantes.
+ Les paramètres CALL sont désormais affichés sous forme de constantes.

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

Les événements `LWLock:SubtransSLRU` and `LWLock:SubtransBuffer` wait indiquent qu'une session attend d'accéder au cache simple le moins récemment utilisé (SLRU) pour les informations relatives aux sous-transactions. Cela se produit lors de la détermination de la visibilité des transactions et des relations parent-enfant.
+ `LWLock:SubtransSLRU`: un processus attend d'accéder au cache simple le moins récemment utilisé (SLRU) pour une sous-transaction. Dans RDS pour PostgreSQL avant la version 13, cet événement d'attente est appelé. `SubtransControlLock`
+ `LWLock:SubtransBuffer`: Un processus attend I/O une sous-transaction dans une mémoire tampon simple la moins récemment utilisée (SLRU). Dans RDS pour PostgreSQL avant la version 13, cet événement d'attente est appelé. `subtrans`

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.lwlocksubtransslru.supported)
+ [

## Contexte
](#wait-event.lwlocksubtransslru.context)
+ [

## Causes probables de l’augmentation du nombre d’événements d’attente
](#wait-event.lwlocksubtransslru.causes)
+ [

## Actions
](#wait-event.lwlocksubtransslru.actions)

## Versions de moteur prises en charge
<a name="wait-event.lwlocksubtransslru.supported"></a>

Ces informations sur les événements d’attente sont prises en charge pour toutes les versions de RDS pour PostgreSQL.

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

**Comprendre les sous-transactions** — Une sous-transaction est une transaction au sein d'une transaction dans PostgreSQL. Elle est également connue sous le nom de transaction imbriquée.

Les sous-transactions sont généralement créées lorsque vous utilisez :
+ Commandes de l’`SAVEPOINT`
+ Blocs d'exception (`BEGIN/EXCEPTION/END`)

Les sous-transactions vous permettent d'annuler certaines parties d'une transaction sans affecter l'ensemble de la transaction. Cela vous donne un contrôle précis sur la gestion des transactions.

**Détails de mise en œuvre** — PostgreSQL implémente les sous-transactions sous forme de structures imbriquées dans les transactions principales. Chaque sous-transaction reçoit son propre identifiant de transaction.

Principaux aspects de la mise en œuvre :
+  IDs Les transactions sont suivies dans `pg_xact`
+ Les relations parent-enfant sont stockées dans `pg_subtrans` le sous-répertoire sous `PGDATA`
+ Chaque session de base de données peut gérer jusqu'à des `64` sous-transactions actives
+ Le dépassement de cette limite entraîne un débordement des sous-transactions, ce qui nécessite d'accéder au cache simple utilisé le moins récemment (SLRU) pour les informations relatives aux sous-transactions

## Causes probables de l’augmentation du nombre d’événements d’attente
<a name="wait-event.lwlocksubtransslru.causes"></a>

Les causes courantes de contention du SLRU lié aux sous-transactions sont les suivantes :
+ **Utilisation excessive de SAVEPOINT et de gestion des EXCEPTIONS** : PL/pgSQL les procédures dotées de `EXCEPTION` gestionnaires créent automatiquement des points de sauvegarde implicites, que des exceptions se produisent ou non. Chacune `SAVEPOINT` initie une nouvelle sous-transaction. Lorsqu'une seule transaction cumule plus de 64 sous-transactions, elle déclenche un dépassement du SLRU des sous-transactions.
+ **Configurations du pilote et de l'ORM** : `SAVEPOINT` l'utilisation peut être explicite dans le code de l'application ou implicite dans les configurations du pilote. De nombreux outils ORM et frameworks d'applications couramment utilisés prennent en charge les transactions imbriquées de manière native. Voici quelques exemples courants :
  + Le paramètre du pilote JDBC`autosave`, s'il est défini sur `always` ou`conservative`, génère des points de sauvegarde avant chaque requête.
  + Définitions de transactions Spring Framework lorsqu'elles sont définies sur`propagation_nested`.
  + Rails quand `requires_new: true` c'est réglé.
  + SQLAlchemy quand `session.begin_nested` est utilisé.
  + Django lorsque des `atomic()` blocs imbriqués sont utilisés.
  + GORM lorsqu'il `Savepoint` est utilisé.
  + PSQLodBC lorsque le paramètre de niveau d'annulation est défini sur Annulation au niveau de l'instruction (par exemple,). `PROTOCOL=7.4-2`
+ **Charges de travail simultanées élevées associées à des transactions et sous-transactions de longue durée : lorsque le nombre de sous-transactions** SLRU déborde lors de charges de travail simultanées élevées et de transactions et sous-transactions de longue durée, PostgreSQL est confronté à une augmentation des contentions. Cela se traduit par des temps d'attente élevés `LWLock:SubtransBuffer` et des `LWLock:SubtransSLRU` blocages.

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

Nous vous recommandons différentes actions en fonction des causes de votre événement d’attente. Certaines actions apportent un soulagement immédiat, tandis que d'autres nécessitent une enquête et une correction à long terme.

**Topics**
+ [

### Surveillance de l'utilisation des sous-transactions
](#wait-event.lwlocksubtransslru.actions.monitor)
+ [

### Configuration des paramètres de mémoire
](#wait-event.lwlocksubtransslru.actions.memory)
+ [

### Actions à long terme
](#wait-event.lwlocksubtransslru.actions.longterm)

### Surveillance de l'utilisation des sous-transactions
<a name="wait-event.lwlocksubtransslru.actions.monitor"></a>

Pour les versions 16.1 et ultérieures de PostgreSQL, utilisez la requête suivante pour surveiller le nombre de sous-transactions et l'état des dépassements par backend. Cette requête associe les statistiques du backend aux informations d'activité pour indiquer quels processus utilisent des sous-transactions :

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

Pour les versions 13.3 et ultérieures de PostgreSQL, surveillez la vue pour détecter la pression `pg_stat_slru` du cache des sous-transactions. La requête SQL suivante extrait les statistiques du cache SLRU pour le composant Subtrans :

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

Une `blks_read` valeur en augmentation constante indique un accès fréquent au disque pour les sous-transactions non mises en cache, ce qui indique une pression potentielle sur le cache du SLRU.

### Configuration des paramètres de mémoire
<a name="wait-event.lwlocksubtransslru.actions.memory"></a>

Pour PostgreSQL 17.1 et versions ultérieures, vous pouvez configurer la taille du cache SLRU des sous-transactions à l'aide du paramètre. `subtransaction_buffers` L'exemple de configuration suivant montre comment définir le paramètre du tampon de sous-transactions :

```
subtransaction_buffers = 128
```

Ce paramètre indique la quantité de mémoire partagée utilisée pour mettre en cache le contenu des sous-transactions (`pg_subtrans`). Lorsqu'elle est spécifiée sans unités, la valeur représente des blocs d'`BLCKSZ`octets, généralement de 8 Ko chacun. Par exemple, définir la valeur sur 128 alloue 1 Mo (128 x 8 Ko) de mémoire au cache de sous-transactions.

**Note**  
Vous pouvez définir ce paramètre au niveau du cluster afin que toutes les instances restent cohérentes. Testez et ajustez la valeur en fonction de vos exigences spécifiques en matière de charge de travail et de classe d'instance. Vous devez redémarrer l'instance du rédacteur pour que les modifications des paramètres soient prises en compte.

### Actions à long terme
<a name="wait-event.lwlocksubtransslru.actions.longterm"></a>
+ **Examinez le code et les configurations de l'**application : passez en revue les configurations du code de votre application et du pilote de base de données pour en déterminer `SAVEPOINT` l'utilisation explicite et implicite et l'utilisation des sous-transactions en général. Identifiez les transactions susceptibles de générer plus de 64 sous-transactions.
+ **Réduisez l'utilisation des points de sauvegarde** — Minimisez l'utilisation de points de sauvegarde dans vos transactions :
  + Passez en revue PL/pgSQL les procédures et les fonctions à l'aide de blocs EXCEPTION. Les blocs EXCEPTION créent automatiquement des points de sauvegarde implicites, ce qui peut contribuer au dépassement des sous-transactions. Chaque clause EXCEPTION crée une sous-transaction, qu'une exception se produise ou non pendant l'exécution.  
**Example**  

    Exemple 1 : utilisation problématique du bloc EXCEPTION

    L'exemple de code suivant montre l'utilisation problématique du bloc EXCEPTION qui crée plusieurs sous-transactions :

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

    L'exemple de code amélioré suivant réduit l'utilisation des sous-transactions en utilisant UPSERT au lieu de la gestion des exceptions :

    ```
    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**  

    Exemple 2 : gestionnaire d'exceptions STRICT

    L'exemple de code suivant montre la gestion problématique des EXCEPTIONS avec 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;
    ```

    L'exemple de code amélioré suivant permet d'éviter les sous-transactions en utilisant IF NOT FOUND au lieu de la gestion des exceptions :

    ```
    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;
    ```
  + Pilote JDBC — Le `autosave` paramètre, s'il est défini sur `always` ou`conservative`, génère des points de sauvegarde avant chaque requête. Évaluez si le `never` paramètre est acceptable pour votre application.
  + Pilote ODBC PostgreSQL (PSQLodBC) : le paramètre du niveau de restauration (pour la restauration au niveau des instructions) crée des points de sauvegarde implicites pour activer la fonctionnalité de restauration des instructions. Déterminez si une annulation au niveau de la transaction est acceptable ou non pour votre application. 
  + Examiner les configurations de transactions ORM
  + Envisagez d'autres stratégies de gestion des erreurs qui ne nécessitent pas de points de sauvegarde
+ **Optimisez la conception** des transactions : restructurez les transactions pour éviter une imbrication excessive et réduire le risque de débordement des sous-transactions.
+ **Réduction des transactions de longue durée — Les transactions** de longue durée peuvent exacerber les problèmes de sous-transactions en conservant plus longtemps les informations relatives aux sous-transactions. Surveillez les métriques Performance Insights et configurez le `idle_in_transaction_session_timeout` paramètre pour mettre fin automatiquement aux transactions inactives.
+ Surveillez les indicateurs de Performance Insights : suivez des indicateurs tels que `idle_in_transaction_count` (nombre de sessions inactives dans l'état de transaction) et `idle_in_transaction_max_time` (durée de la transaction inactive la plus longue) pour détecter les transactions de longue durée.
+ Configurer `idle_in_transaction_session_timeout` : définissez ce paramètre dans votre groupe de paramètres pour mettre fin automatiquement aux transactions inactives après une durée spécifiée.
+ Surveillance proactive : surveillez les occurrences élevées d'événements `LWLock:SubtransBuffer` et `LWLock:SubtransSLRU` attendez afin de détecter les litiges liés aux sous-transactions avant qu'ils ne deviennent critiques.

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

L'événement `Timeout:PgSleep` se produit lorsqu'un processus serveur a appelé la fonction `pg_sleep` et attend l'expiration du délai de mise en veille.

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.timeoutpgsleep.context.supported)
+ [

## Causes probables de l'allongement des temps d'attente
](#wait-event.timeoutpgsleep.causes)
+ [

## Actions
](#wait-event.timeoutpgsleep.actions)

## Versions de moteur prises en charge
<a name="wait-event.timeoutpgsleep.context.supported"></a>

Ces informations sur les événements d'attente sont prises en charge pour toutes les versions de RDS for PostgreSQL.

## Causes probables de l'allongement des temps d'attente
<a name="wait-event.timeoutpgsleep.causes"></a>

Cet événement d'attente se produit lorsqu'une application, une fonction stockée ou un utilisateur émet une instruction SQL qui appelle l'une des fonctions suivantes :
+ `pg_sleep`
+ `pg_sleep_for`
+ `pg_sleep_until`

Les fonctions précédentes retardent l'exécution jusqu'à ce que le nombre de secondes spécifié se soit écoulé. Par exemple, `SELECT pg_sleep(1)` marque une pause d'une seconde. Pour en savoir plus, consultez [Delaying Execution](https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-DELAY) dans la documentation PostgreSQL.

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

Identifiez l'instruction qui exécutait la fonction `pg_sleep`. Déterminez si l'utilisation de la fonction est appropriée.

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

L'événement `Timeout:VacuumDelay` indique que la limite de coût des E/S du processus vacuum a été dépassée et que le processus vacuum a été mis en veille. Les opérations vacuum s'arrêtent pendant la durée spécifiée dans le paramètre de délai de coût correspondant, puis le processus reprend. Pour la commande vacuum manuelle, le délai est spécifié dans le paramètre `vacuum_cost_delay`. Pour le démon autovacuum, le délai est spécifié dans `autovacuum_vacuum_cost_delay parameter.` 

**Topics**
+ [

## Versions de moteur prises en charge
](#wait-event.timeoutvacuumdelay.context.supported)
+ [

## Contexte
](#wait-event.timeoutvacuumdelay.context)
+ [

## Causes probables de l'allongement des temps d'attente
](#wait-event.timeoutvacuumdelay.causes)
+ [

## Actions
](#wait-event.timeoutvacuumdelay.actions)

## Versions de moteur prises en charge
<a name="wait-event.timeoutvacuumdelay.context.supported"></a>

Ces informations sur les événements d'attente sont prises en charge pour toutes les versions de RDS for PostgreSQL.

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

PostgreSQL possède à la fois un démon autovacuum et une commande vacuum manuelle. Le processus autovacuum est « activé » par défaut pour les instances de base de données RDS for PostgreSQL. La commande vacuum manuelle est utilisée selon les besoins, par exemple pour purger les tables des tuples morts ou générer de nouvelles statistiques.

Lorsque le processus vacuum est en cours, PostgreSQL utilise un compteur interne pour suivre les coûts estimés au fur et à mesure que le système effectue les diverses opérations d'E/S. Quand le compteur atteint la valeur spécifiée par le paramètre de limite de coût, le processus exécutant l'opération est en veille pendant la brève durée spécifiée dans le paramètre de délai de coût. Il réinitialise ensuite le compteur et poursuit les opérations. 

Le processus vacuum comporte des paramètres qui peuvent être utilisés pour réguler la consommation de ressources. Le processus autovacuum et la commande vacuum manuelle ont leurs propres paramètres pour définir la valeur limite de coût. Ils ont également leurs propres paramètres pour spécifier un délai de coût, c'est-à-dire le temps alloué pour mettre en veille le processus vacuum quand la limite est atteinte. De cette manière, le paramètre de délai de coût fonctionne comme un mécanisme de limitation de la consommation de ressources. Les listes suivantes contiennent les descriptions de ces paramètres. 

**Paramètres affectant la limitation du démon autovacuum**
+ `[autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)` – Spécifie la valeur limite de coût à utiliser dans les opérations vacuum automatiques. L'augmentation de la valeur de ce paramètre permet au processus vacuum d'utiliser davantage de ressources et réduit l'événement d'attente `Timeout:VacuumDelay`. 
+ `[autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)` – Spécifie la valeur de délai de coût à utiliser dans les opérations vacuum automatiques. La valeur par défaut est de 2 millisecondes. La définition du paramètre de délai sur 0 désactive le mécanisme de limitation, si bien que l'événement d'attente `Timeout:VacuumDelay` n'apparaîtra pas. 

Pour plus d'informations, veuillez consulter [Action Vacuum automatique](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY) dans la documentation PostgreSQL.

**Paramètres affectant la limitation du processus vacuum manuel**
+ `vacuum_cost_limit` – Le seuil à partir duquel le processus vacuum est mis en veille. Par défaut, cette limite est de 200. Ce nombre représente les estimations des coûts cumulés pour les E/S supplémentaires requises par les diverses ressources. L'augmentation de cette valeur réduit le nombre d'événements d'attente `Timeout:VacuumDelay`. 
+ `vacuum_cost_delay` – La durée pendant laquelle le processus vacuum est en veille quand la limite de coût du processus vacuum est atteinte. La valeur par défaut est 0, ce qui signifie que cette fonctionnalité est désactivée. Vous pouvez définir une valeur entière pour spécifier le nombre de millisecondes nécessaires à l'activation de cette fonctionnalité, mais nous vous recommandons de conserver la valeur par défaut.

Pour plus d'informations sur le paramètre `vacuum_cost_delay`, consultez [Consommation des ressources](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST) dans la documentation PostgreSQL. 

Pour en savoir plus sur la configuration et l'utilisation d'autovacuum avec RDS for PostgreSQL, consultez [Utilisation de la fonction autovacuum de PostgreSQL sur Amazon RDS pour PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md). 

## Causes probables de l'allongement des temps d'attente
<a name="wait-event.timeoutvacuumdelay.causes"></a>

Le paramètre `Timeout:VacuumDelay` est affecté par l'équilibre entre les valeurs des paramètres de limite de coût (`vacuum_cost_limit`, `autovacuum_vacuum_cost_limit`) et les paramètres de délai de coût (`vacuum_cost_delay`, `autovacuum_vacuum_cost_delay`) qui contrôlent la durée de veille du processus vacuum. L'augmentation d'une valeur de paramètre de limite de coût permet d'utiliser davantage de ressources pour le processus vacuum avant qu'il soit mis en veille. Cela se traduit par une diminution des événements d'attente `Timeout:VacuumDelay`. L'augmentation de l'un ou l'autre des paramètres de délai entraîne une hausse de la fréquence et de la durée de l'événement d'attente `Timeout:VacuumDelay`. 

Le réglage du paramètre `autovacuum_max_workers` peut également augmenter les nombres de `Timeout:VacuumDelay`. Chaque processus de travail autovacuum supplémentaire contribue au contre-mécanisme interne, de sorte que la limite peut être atteinte plus rapidement qu'avec un seul processus de travail autovacuum. Comme la limite de coût est atteinte plus rapidement, le délai de coût entre en vigueur plus fréquemment, ce qui se traduit par un plus grand nombre d'événements d'attente `Timeout:VacuumDelay`. Pour plus d'informations, consultez [autovacuum\$1max\$1workers](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS) dans la documentation PostgreSQL.

Les objets volumineux, de 500 Go ou plus, déclenchent également cet événement d'attente, car le traitement des objets volumineux par le processus vacuum peut prendre un certain temps.

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

Si les opérations vacuum se terminent comme prévu, aucune correction n'est requise. En d'autres termes, cet événement d'attente n'indique pas nécessairement un problème. Il indique que le processus vacuum est mis en veille pendant la période spécifiée dans le paramètre de délai, afin que les ressources puissent être affectées à d'autres processus qui doivent être achevés. 

Si vous souhaitez terminer plus rapidement les opérations vacuum, vous pouvez réduire les paramètres de délai. Cela raccourcit le temps de veille du processus vacuum. 