Lock:tuple - Amazon Aurora

Lock:tuple

El evento Lock:tuple se produce cuando un proceso backend espera adquirir un bloqueo sobre una tupla.

Versiones del motor admitidas

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

Contexto

El evento Lock:tuple indica que un backend espera adquirir un bloqueo sobre una tupla mientras otro backend mantiene un bloqueo conflictivo sobre la misma tupla. La siguiente tabla ilustra un escenario en el que las sesiones generan el evento Lock:tuple.

Time

Sesión 1

Sesión 2

Sesión 3

t1

Inicia una transacción.

t2

Actualiza la fila 1.

t3

Actualiza la fila 1. La sesión adquiere un bloqueo exclusivo sobre la tupla y luego espera a que la sesión 1 libere el bloqueo mediante la confirmación o reversión.

t4

Actualiza la fila 1. La sesión espera a que la sesión 2 libere el bloqueo exclusivo en la tupla.

También puede simular este evento de espera con la herramienta de punto de referencia pgbench. Configure un alto número de sesiones concurrentes para actualizar la misma fila en una tabla con un archivo SQL personalizado.

Para obtener más información sobre los modos de bloqueo conflictivos, consulte E en la documentación de PostgreSQL. Para más información sobre pgbench, consulte pgbench en la documentación de PostgreSQL.

Causas probables del aumento de las esperas

Cuando este evento aparece más de lo normal, lo que posiblemente indica un problema de rendimiento, las causas típicas son las siguientes:

  • Un gran número de sesiones concurrentes están intentando adquirir un bloqueo conflictivo para la misma tupla al ejecutar instrucciones UPDATE o DELETE.

  • Las sesiones altamente concurrentes se encuentran en ejecución con una instrucción SELECT que utiliza los modos de bloqueo FOR UPDATE o FOR NO KEY UPDATE.

  • Varios factores hacen que la aplicación o los grupos de conexión abran más sesiones para ejecutar las mismas operaciones. A medida que nuevas sesiones intentan modificar las mismas filas, la carga de la base de datos puede aumentar y puede aparecer Lock:tuple.

Para más información, consulte Row-Level Locks en la documentación de PostgreSQL.

Acciones

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

Investigue la lógica de su aplicación

Verifique si una sesión del bloqueador se encuentra en el estado idle in transaction por mucho tiempo. Si es así, considere la posibilidad de finalizar la sesión del bloqueador como una solución a corto plazo. Puede utilizar la función pg_terminate_backend. Para más información sobre esta función, consulte Server Signaling Functions en la documentación de PostgreSQL.

Para una solución a largo plazo, haga lo siguiente:

  • Ajuste la lógica de la aplicación.

  • Utilice el parámetro idle_in_transaction_session_timeout. Este parámetro finaliza cualquier sesión con una transacción abierta que haya estado inactiva durante más tiempo del especificado. Para más información, consulte Client Connection Defaults en la documentación de PostgreSQL.

  • Utilice la confirmación automática en la medida de lo posible. Para más información, consulte SET AUTOCOMMIT en la documentación de PostgreSQL.

Encontrar la sesión bloqueadora

Mientras se produce el evento de espera Lock:tuple, identifique el bloqueador y la sesión bloqueada mediante la búsqueda de los bloqueos que dependen unos de otros. Para más información, consulte la Información sobre dependencia de bloqueos en el wiki de PostgreSQL. Para analizar eventos Lock:tuple pasados, utilice la función de Aurora aurora_stat_backend_waits.

El siguiente ejemplo muestra todas las sesiones, con un filtro tuple y ordenadas por 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

Reducir la concurrencia cuando es alta

El evento Lock:tuple puede producirse de manera frecuente, especialmente en un momento de carga de trabajo elevada. En esta situación, considere reducir la alta concurrencia para las filas muy ocupadas. A menudo, solo unas pocas filas controlan una cola o la lógica booleana, lo que hace que estas filas estén muy ocupadas.

Puede reducir la concurrencia mediante el uso de diferentes enfoques basados en los requisitos de la empresa, lógica de la aplicación y tipo de carga de trabajo. Por ejemplo, puede hacer lo siguiente:

  • Rediseñar la lógica de la tabla y los datos para reducir la alta concurrencia.

  • Cambiar la lógica de la aplicación para reducir la alta concurrencia entre filas.

  • Aprovechar y rediseñar las consultas con bloqueos entre filas.

  • Utilizar la cláusula NOWAIT con operaciones de reintento.

  • Considerar el uso de control de concurrencia optimista y de lógica de bloqueo híbrida.

  • Considerar la posibilidad de cambiar el nivel de aislamiento de la base de datos.

Solucionar los cuellos de botella

La Lock:tuple producirse con cuellos de botella, como el agotamiento de la CPU o el uso máximo del ancho de banda de Amazon EBS. Para reducir los cuellos de botella, considere los siguientes enfoques:

  • Escalar verticalmente el tipo de clase de instancia.

  • Optimizar las consultas que consumen muchos recursos.

  • Cambiar la lógica de la aplicación.

  • Archivar los datos a los que rara vez se accede.