Error de PostgreSQL: canceling statement due to lock timeout

ERROR:  canceling statement due to lock timeout

La sentencia esperó un bloqueo más tiempo del que permite lock_timeout y se rindió. A diferencia de la mayoría de errores de esta lista, este normalmente significa que un mecanismo de seguridad funcionó: fallar rápido ante un bloqueo casi siempre es mejor que encolarse detrás de él — especialmente para el DDL.

Qué significa este error

Por qué importa fallar rápido tiene que ver con la cola, no con el que espera: un ALTER TABLE necesita un bloqueo ACCESS EXCLUSIVE. Mientras espera detrás de alguna consulta de larga duración, cada nueva consulta sobre esa tabla — incluidos los SELECT simples — se encola detrás de él. Una migración atascada puede congelar una tabla de producción en segundos. lock_timeout convierte ese escenario en un fallo rápido y reintentable.

No lo confundas con statement_timeout: ese acota el tiempo total de ejecución; lock_timeout acota una sola espera de bloqueo y tiene su propio SQLSTATE (55P03).

Causas comunes

Cómo diagnosticarlo

-- Quién bloquea a quién, ahora mismo:
SELECT waiting.pid, waiting.query AS waiting_query,
       blocking.pid AS blocking_pid, blocking.query AS blocking_query,
       now() - blocking.xact_start AS blocking_xact_age
FROM pg_stat_activity waiting
JOIN pg_stat_activity blocking
  ON blocking.pid = ANY (pg_blocking_pids(waiting.pid));

Configura también log_lock_waits = on: las esperas más largas que deadlock_timeout se registran con ambos lados, dándote un historial de contención, no solo la vista en vivo.

Cómo solucionarlo

🔍 La otra manera en que las esperas de bloqueo terminan mal: deadlock detected.