Lock:Relation
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.
Versiones del motor admitidas
Esta información de eventos de espera es compatible con todas las versiones de Aurora PostgreSQL.
Context
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, Aurora 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) comoDROP TABLE
,TRUNCATE
,VACUUM FULL
yCLUSTER
adquieren bloqueosACCESS EXCLUSIVE
implícitamente.ACCESS EXCLUSIVE
es también el modo de bloqueo por defecto para las instruccionesLOCK 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
eINSERT
, que adquieren bloqueosROW EXCLUSIVE
.
Para más información sobre los bloqueos a nivel de tabla y los modos de bloqueo conflictivos, consulte Explicit Locking
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
oCOMMIT
. 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 del tiempo de espera
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
yANALYZE
pueden aumentar significativamente el número de bloqueos conflictivos.VACUUM FULL
adquiere un bloqueoACCESS EXCLUSIVE
, yANALYZE
adquiere un bloqueoSHARE UPDATE EXCLUSIVE
. Ambos tipos de bloqueos pueden causar un evento de esperaLock: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 relacionesACCESS EXCLUSIVE
entrará en conflicto con cualquier bloqueo de relacionesACCESS SHARE
que mantenga el lector. Esto puede provocar un aumento de los eventos de espera de las relaciones de bloqueo en el lector.
Acciones
Recomendamos diferentes acciones en función de las causas del evento de espera.
Temas
Reducir el impacto de las instrucciones SQL que se bloquean
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 instruccionesSELECT
yLOCK
, admiten esta opción. La directivaNOWAIT
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 delock_timeout
para limitar el tiempo que una sentencia SQL espera para adquirir un bloqueo en una relación. Si el bloqueo no se adquiere en el intervalo de tiempo de espera especificado, se cancelará la transacción que solicita el bloqueo. Establezca este valor en la sesión.
Minimizar el efecto de las operaciones de mantenimiento
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 en la Guía del usuario de Amazon RDS.
Verificar los bloqueos de los lectores
Puede ver cómo las sesiones concurrentes en un escritor y los lectores se pueden bloquear mutuamente. Una forma de hacer esto consiste en ejecutar consultas que devuelvan el tipo de bloqueo y la relación. En la tabla encontrará una secuencia de consultas en dos sesiones simultáneas de este tipo, una sesión de escritor y una sesión de lector.
El proceso de repetición espera el tiempo que dura max_standby_streaming_delay
antes de cancelar la consulta del lector. Como se muestra en el ejemplo, el tiempo de espera de bloqueo de 100 ms está muy por debajo del max_standby_streaming_delay
predeterminado de 30 segundos. El tiempo de espera del bloqueo se agota antes de que sea un problema.
Evento de secuencia | Sesión | Comando o salida |
---|---|---|
Establece una variable de entorno denominada READER con el valor especificado e intenta conectarse a la instancia de base de datos con este punto de conexión. |
Sesión de lector |
Comando de la CLI:
Salida: psql (15devel, server 10.14) Type "help" for help. |
Establece una variable de entorno denominada WRITER e intenta conectarse a la instancia de base de datos con este punto de conexión. |
Sesión de escritor |
Comando de la CLI:
Salida: psql (15devel, server 10.14) Type "help" for help. |
La sesión de escritor crea la tabla t1 en la instancia de escritor. |
Sesión de escritor |
Consulta de PostgreSQL:
|
Si no hay consultas en conflicto en el escritor, se adquirirá inmediatamente en el escritor el bloqueo de ACCESS EXCLUSIVE. |
Sesión de escritor |
Bloqueo de |
La sesión de lector establece un intervalo de bloqueo de 100 milisegundos. |
Sesión de lector |
Consulta de PostgreSQL:
|
La sesión de lector intenta leer datos de la tabla t1 en la instancia de lector. |
Sesión de lector |
Consulta de PostgreSQL:
Resultado de ejemplo: b --- (0 rows) |
La sesión de escritor elimina la tabla t1. |
Sesión de escritor |
Consulta de PostgreSQL:
|
Se agota el tiempo de espera de la consulta y se cancela en la sesión de lector. |
Sesión de lector |
Consulta de PostgreSQL:
Resultado de ejemplo: ERROR: canceling statement due to lock timeout LINE 1: SELECT * FROM t1; ^ |
Para determinar la causa del error, la sesión de lector consulta |
Sesión de lector |
Consulta de PostgreSQL:
|
El resultado indica que el proceso de |
Sesión de lector |
Resultado de la consulta:
|