

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.

# Lock:tuple
<a name="apg-waits.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](#apg-waits.locktuple.context.supported)
+ [Contexte](#apg-waits.locktuple.context)
+ [Causes probables de l'augmentation du nombre d'événements d'attente](#apg-waits.locktuple.causes)
+ [Actions](#apg-waits.locktuple.actions)

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

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

## Contexte
<a name="apg-waits.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="apg-waits.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="apg-waits.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](#apg-waits.locktuple.actions.problem)
+ [Recherchez la session de blocage](#apg-waits.locktuple.actions.find-blocker)
+ [Réduisez la simultanéité lorsqu'elle est forte](#apg-waits.locktuple.actions.concurrency)
+ [Résolvez les problèmes liés aux goulots d'étranglement](#apg-waits.locktuple.actions.bottlenecks)

### Examinez la logique de votre application
<a name="apg-waits.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="apg-waits.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. Pour analyser les événements `Lock:tuple` passés, utilisez la fonction Aurora `aurora_stat_backend_waits`. 

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

```
--AURORA_STAT_BACKEND_WAITS
      SELECT a.pid, 
             a.usename, 
             a.app_name, 
             a.current_query,
             a.current_wait_type, 
             a.current_wait_event, 
             a.current_state, 
             wt.type_name AS wait_type, 
             we.event_name AS wait_event, 
             a.waits, 
             a.wait_time
        FROM (SELECT pid, 
                     usename, 
                     left(application_name,16) AS app_name,
                     coalesce(wait_event_type,'CPU') AS current_wait_type,
                     coalesce(wait_event,'CPU') AS current_wait_event, 
                     state AS current_state,
                     left(query,80) as current_query,
                     (aurora_stat_backend_waits(pid)).* 
                FROM pg_stat_activity 
               WHERE pid <> pg_backend_pid()
                 AND usename<>'rdsadmin') a
NATURAL JOIN aurora_stat_wait_type() wt 
NATURAL JOIN aurora_stat_wait_event() we
WHERE we.event_name = 'tuple'
    ORDER BY a.wait_time;

  pid  | usename | app_name |                 current_query                  | current_wait_type | current_wait_event | current_state | wait_type | wait_event | waits | wait_time
-------+---------+----------+------------------------------------------------+-------------------+--------------------+---------------+-----------+------------+-------+-----------
 32136 | sys     | psql     | /*session3*/ update tab set col=1 where col=1; | Lock              | tuple              | active        | Lock      | tuple      |     1 |   1000018
 11999 | sys     | psql     | /*session4*/ update tab set col=1 where col=1; | Lock              | tuple              | active        | Lock      | tuple      |     1 |   1000024
```

### Réduisez la simultanéité lorsqu'elle est forte
<a name="apg-waits.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="apg-waits.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.