PostgreSQL-Fehler: canceling statement due to lock timeout

ERROR:  canceling statement due to lock timeout

Die Anweisung wartete länger auf einen Lock, als lock_timeout erlaubt, und gab auf. Anders als die meisten Fehler auf dieser Liste bedeutet dieser meist, dass ein Sicherheitsmechanismus funktioniert hat: bei einem Lock schnell zu scheitern ist fast immer besser, als sich dahinter anzustellen — besonders bei DDL.

Was dieser Fehler bedeutet

Warum schnelles Scheitern wichtig ist, hat mit der Warteschlange zu tun, nicht dem Wartenden: ein ALTER TABLE braucht einen ACCESS EXCLUSIVE-Lock. Während es hinter einer lange laufenden Query wartet, stellt sich jede neue Query auf dieser Tabelle — einschließlich schlichter SELECTs — hinter ihm an. Eine feststeckende Migration kann eine Produktionstabelle innerhalb von Sekunden einfrieren. lock_timeout verwandelt dieses Szenario in einen schnellen, wiederholbaren Fehlschlag.

Verwechseln Sie es nicht mit statement_timeout: das begrenzt die Gesamtlaufzeit; lock_timeout begrenzt eine einzelne Lock-Wartezeit und hat einen eigenen SQLSTATE (55P03).

Häufige Ursachen

So diagnostizieren Sie ihn

-- Wer wen blockiert, jetzt:
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));

Setzen Sie außerdem log_lock_waits = on: Wartezeiten länger als deadlock_timeout werden mit beiden Seiten protokolliert und geben Ihnen eine Historie der Contention, nicht nur die Live-Ansicht.

So beheben Sie ihn

🔍 Die andere Art, wie Lock-Wartezeiten schlecht enden: deadlock detected.
🔍 Das Geschwister-Timeout: canceling statement due to statement timeout.