Inspeccionar en detalle las esperas de bloqueo por objeto y modo de bloqueo (pg_locks)
PostgreSQLSesionesComando
SELECT DISTINCT
w.pid AS waiting_pid,
w.locktype,
coalesce(w.relation::regclass::text, 'xid ' || w.transactionid, w.virtualxid, w.objid::text) AS target,
w.mode AS wanted_mode,
b.pid AS blocker_pid,
b.mode AS blocker_mode,
b.granted AS blocker_holds,
now() - wa.state_change AS waiting_for,
left(wa.query, 60) AS waiting_query,
left(ba.query, 60) AS blocker_query
FROM pg_locks w
JOIN pg_locks b
ON b.pid = ANY (pg_blocking_pids(w.pid))
AND b.locktype = w.locktype
AND b.database IS NOT DISTINCT FROM w.database
AND b.relation IS NOT DISTINCT FROM w.relation
AND b.page IS NOT DISTINCT FROM w.page
AND b.tuple IS NOT DISTINCT FROM w.tuple
AND b.virtualxid IS NOT DISTINCT FROM w.virtualxid
AND b.transactionid IS NOT DISTINCT FROM w.transactionid
AND b.classid IS NOT DISTINCT FROM w.classid
AND b.objid IS NOT DISTINCT FROM w.objid
AND b.objsubid IS NOT DISTINCT FROM w.objsubid
JOIN pg_stat_activity wa ON wa.pid = w.pid
JOIN pg_stat_activity ba ON ba.pid = b.pid
WHERE NOT w.granted
ORDER BY waiting_for DESC, waiting_pid;Qué hace
Para cada solicitud de bloqueo no concedida (granted = false), muestra el objeto de destino (tabla, transaction id, etc.), el modo solicitado, el PID bloqueante y su modo, si el bloqueador retiene realmente el bloqueo y el tiempo de espera aproximado.
Cuándo usarlo
Para entender qué conflicto de tabla y modo de bloqueo causa el bloqueo; p. ej., un DDL que espera AccessExclusiveLock, o un bloqueo de fila que aparece como espera transactionid.
Precaución
Como la correspondencia usa pg_blocking_pids(), solo se listan las solicitudes realmente en conflicto. blocker_holds = false significa que el bloqueador aún no retiene el bloqueo pero está en la cola por delante con un modo en conflicto (lock queue). locktype = 'transactionid' es un conflicto a nivel de fila: el que espera aguarda a que termine la transacción que modificó la fila; la fila en sí no es visible en pg_locks. pg_locks puede contener miles de filas en sistemas grandes; no lo ejecute con frecuencia. waiting_for es una aproximación basada en state_change.
Relacionado
- Terminar un backend (pg_terminate_backend)
- Cancelar una consulta en ejecución (pg_cancel_backend)
- Mostrar consultas activas y bloqueantes
- Construir el árbol de bloqueos (encontrar el bloqueador raíz)
- Encontrar transacciones de larga duración e 'idle in transaction'
- Terminar de forma masiva y controlada las sesiones 'idle in transaction' largas