

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

El evento `Lock:Relation` ocurre cuando una consulta espera adquirir un bloqueo en una tabla o vista (relación) que se encuentra bloqueada por otra transacción.

**Topics**
+ [Versiones del motor admitidas](#wait-event.lockrelation.context.supported)
+ [Contexto](#wait-event.lockrelation.context)
+ [Causas probables del aumento de las esperas](#wait-event.lockrelation.causes)
+ [Acciones](#wait-event.lockrelation.actions)

## Versiones del motor admitidas
<a name="wait-event.lockrelation.context.supported"></a>

Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.

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

La mayoría de los comandos de PostgreSQL utilizan implícitamente bloqueos para controlar el acceso concurrente a los datos de las tablas. También puede utilizar estos bloqueos explícitamente en su código de aplicación con el comando `LOCK`. Muchos modos de bloqueo no son compatibles entre sí, y pueden bloquear las transacciones cuando intentan acceder al mismo objeto. Cuando esto sucede, RDS para PostgreSQL genera un evento `Lock:Relation`. Algunos ejemplos comunes son los siguientes:
+ Los bloqueos exclusivos como `ACCESS EXCLUSIVE` pueden bloquear todos los accesos concurrentes. Las operaciones del lenguaje de definición de datos (DDL) como `DROP TABLE`, `TRUNCATE`, `VACUUM FULL` y `CLUSTER` adquieren bloqueos `ACCESS EXCLUSIVE` implícitamente. `ACCESS EXCLUSIVE` es también el modo de bloqueo por defecto para las instrucciones `LOCK TABLE` que no especifican un modo explícitamente.
+ El uso de `CREATE INDEX (without CONCURRENT)` en una tabla entra en conflicto con las instrucciones de lenguaje de manipulación de datos (DML) `UPDATE`, `DELETE` e `INSERT`, que adquieren bloqueos `ROW EXCLUSIVE`.

Para más información sobre los bloqueos a nivel de tabla y los modos de bloqueo conflictivos, consulte [Explicit Locking](https://www.postgresql.org/docs/13/explicit-locking.html) en la documentación de PostgreSQL.

Las consultas y transacciones que se bloquean normalmente se desbloquean de una de las siguientes maneras:
+ Consulta de bloqueo: la aplicación puede cancelar la consulta o el usuario puede terminar el proceso. El motor también puede forzar la finalización de la consulta debido al tiempo de espera de una sesión o a un mecanismo de detección de bloqueos.
+ Transacción bloqueada: una transacción deja de bloquearse cuando se ejecuta una instrucción `ROLLBACK` o `COMMIT`. Las restauraciones también ocurren de forma automática cuando las sesiones se desconectan por un cliente o por problemas de red, o se terminan. Las sesiones se pueden terminar cuando el motor de base de datos se apaga, cuando el sistema se queda sin memoria, etc.

## Causas probables del aumento de las esperas
<a name="wait-event.lockrelation.causes"></a>

Cuando el evento `Lock:Relation` se produce con más frecuencia de lo normal, puede indicar un problema de rendimiento. Las causas típicas son las siguientes:

**Aumento de las sesiones concurrentes con bloqueos de tablas en conflicto**  
Puede haber un aumento en el número de sesiones concurrentes con consultas que bloquean la misma tabla con modos de bloqueo conflictivos.

**Operaciones de mantenimiento**  
Las operaciones de mantenimiento de estado como `VACUUM` y `ANALYZE` pueden aumentar significativamente el número de bloqueos conflictivos. `VACUUM FULL` adquiere un bloqueo `ACCESS EXCLUSIVE`, y `ANALYSE` adquiere un bloqueo `SHARE UPDATE EXCLUSIVE`. Ambos tipos de bloqueos pueden causar un evento de espera `Lock:Relation`. Las operaciones de mantenimiento de datos de la aplicación, como la actualización de una vista materializada, también pueden aumentar las consultas y transacciones bloqueadas.

**Bloqueos en instancias de lectura**  
Puede haber un conflicto entre los bloqueos de relaciones que mantienen el escritor y los lectores. En la actualidad, solo los bloqueos de relaciones de `ACCESS EXCLUSIVE` se replican en instancias de lector. Sin embargo, el bloqueo de relaciones `ACCESS EXCLUSIVE` entrará en conflicto con cualquier bloqueo de relaciones `ACCESS SHARE` que mantenga el lector. Esto puede provocar un aumento de los eventos de espera de las relaciones de bloqueo en el lector. 

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

Recomendamos diferentes acciones en función de las causas del evento de espera.

**Topics**
+ [Reducir el impacto de las instrucciones SQL que se bloquean](#wait-event.lockrelation.actions.reduce-blocks)
+ [Minimizar el efecto de las operaciones de mantenimiento](#wait-event.lockrelation.actions.maintenance)

### Reducir el impacto de las instrucciones SQL que se bloquean
<a name="wait-event.lockrelation.actions.reduce-blocks"></a>

Para reducir el impacto de las instrucciones SQL que se bloquean, modifique el código de su aplicación cuando sea posible. A continuación se presentan dos técnicas comunes para reducir los bloqueos:
+ Utilizar la opción `NOWAIT`: algunos comandos SQL, como las instrucciones `SELECT` y `LOCK`, admiten esta opción. La directiva `NOWAIT` cancela la consulta que solicita el bloqueo si éste no puede adquirirse inmediatamente. Esta técnica puede ayudar a evitar que una sesión bloqueada provoque una acumulación de sesiones bloqueadas detrás de ella.

  Por ejemplo: Supongamos que la transacción A espera un bloqueo que tiene la transacción B. Ahora, si B solicita un bloqueo en una tabla que está bloqueada por la transacción C, la transacción A podría quedar bloqueada hasta que la transacción C finalice. Pero si la transacción B utiliza un `NOWAIT` cuando solicita el bloqueo en C, puede fallar rápido y asegurar que la transacción A no tenga que esperar de forma indefinida.
+ Utilice `SET lock_timeout`: establezca un valor de `lock_timeout` para limitar el tiempo que una sentencia SQL espera para adquirir un bloqueo en una relación. Si el bloqueo no se adquiere dentro del tiempo de espera especificado, la transacción que solicita el bloqueo se cancela. Establezca este valor en la sesión.

### Minimizar el efecto de las operaciones de mantenimiento
<a name="wait-event.lockrelation.actions.maintenance"></a>

Las operaciones de mantenimiento como `VACUUM` y `ANALYZE` son importantes. Le recomendamos que no las desactive ya que encontrará eventos de espera `Lock:Relation` relacionados con estas operaciones de mantenimiento. Los siguientes enfoques pueden minimizar el efecto de estas operaciones:
+ Ejecute las operaciones de mantenimiento de forma manual durante las horas de menor actividad.
+ Para reducir las esperas de `Lock:Relation` causadas por las tareas de autovacuum, realice los ajustes de autovacuum necesarios. Para obtener información sobre el ajuste de autovacuum, consulte [Trabajo con Autovacuum de PostgreSQL en Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html) en la *Guía del usuario de Amazon RDS*.