Erreur PostgreSQL : canceling statement due to lock timeout

ERROR:  canceling statement due to lock timeout

L'instruction a attendu un verrou plus longtemps que ne l'autorise lock_timeout et a renoncé. Contrairement à la plupart des erreurs de cette liste, celle-ci signifie généralement qu'un mécanisme de sécurité a fonctionné : échouer vite sur un verrou vaut presque toujours mieux que de faire la queue derrière — surtout pour le DDL.

Ce que signifie cette erreur

Pourquoi échouer vite compte concerne la file d'attente, pas celui qui attend : un ALTER TABLE a besoin d'un verrou ACCESS EXCLUSIVE. Pendant qu'il attend derrière une requête de longue durée, toute nouvelle requête sur cette table — y compris de simples SELECT — fait la queue derrière lui. Une migration coincée peut geler une table de production en quelques secondes. lock_timeout transforme ce scénario en un échec rapide et réessayable.

Ne le confondez pas avec statement_timeout : celui-ci borne la durée d'exécution totale ; lock_timeout borne une seule attente de verrou et a son propre SQLSTATE (55P03).

Causes fréquentes

Comment la diagnostiquer

-- Qui bloque qui, maintenant :
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));

Activez aussi log_lock_waits = on : les attentes plus longues que deadlock_timeout sont journalisées avec les deux côtés, vous donnant un historique de la contention, pas seulement la vue en direct.

Comment la corriger

🔍 L'autre façon dont les attentes de verrou finissent mal : deadlock detected.