SQLSTATE 57014 — query_canceled: Autovacuum Task Canceled by Lock Conflict
! Symptoms Free
Conditions:
- Log shows
ERROR: canceling autovacuum taskon specific tables pg_stat_user_tables.n_dead_tupkeeps growing for the affected tablepg_stat_user_tables.last_autovacuumtimestamp is stale (hours/days ago)- Long-running queries (
pg_stat_activitywith oldxact_start) on the same table age(relfrozenxid)approachingautovacuum_freeze_max_age(200M transactions)
1 Environment & reproduce Free
Difficulty: Intermediate | PostgreSQL versions: 12, 13, 14, 15, 16, 17
? Root cause Free
canceling autovacuum taskis not a crash — autovacuum politely yields to user queries. But if it is cancelled repeatedly, dead tuple accumulation risks transaction ID wraparound (which DOES force a full-table emergency VACUUM).idle_in_transaction_session_timeoutis the best prevention — it kills sessions that have been idle-in-transaction for too long, freeing vacuum to proceed.- Manually running
VACUUM tablenamecompetes with user queries just like autovacuum. For wraparound risk:VACUUM FREEZE tablenametakes priority. vacuum_cost_delaycontrols autovacuum's I/O throttling — reducing it makes autovacuum faster but more intrusive.autovacuum_vacuum_cost_delay = -1means autovacuum usesvacuum_cost_delaysetting.
Terminate long-running idle-in-transaction sessions. Set idle_in_transaction_session_timeout. For urgent wraparound risk: run VACUUM FREEZE manually. Tune autovacuum aggressiveness for the affected table.
2 Diagnose Free
RESULT-- Find tables with high dead tuple counts and stale vacuum:
SELECT schemaname, relname,
n_live_tup, n_dead_tup,
round(100.0 * n_dead_tup / NULLIF(n_live_tup + n_dead_tup, 0), 1) AS dead_pct,
last_autovacuum, last_autoanalyze
FROM pg_stat_user_tables
WHERE n_dead_tup > 10000
ORDER BY n_dead_tup DESC LIMIT 20;
-- Find tables close to wraparound (CRITICAL if age > 1.5 billion):
SELECT relname,
age(relfrozenxid) AS xid_age,
current_setting('autovacuum_freeze_max_age')::int AS freeze_max
FROM pg_class
WHERE relkind = 'r'
ORDER BY age(relfrozenxid) DESC LIMIT 10;
-- Find long-running queries blocking vacuum:
SELECT pid, usename, state, now() - xact_start AS txn_age, left(query,80)
FROM pg_stat_activity
WHERE xact_start < now() - INTERVAL '5 minutes'
ORDER BY xact_start;🔒 Diagnose deeper Pro
Find every latent occurrence before it ships
The steps above clear this incident. Pro adds the executed, verified depth that stops the whole class of bug across your fleet.
- ✓Catalog & log queries that surface every at-risk object before a migration ships.
- ✓Inspect-without-running tricks (
\gdescand friends). - ✓Exactly where the log line surfaces on RDS, Azure & Cloud SQL.
- ✓Cross-version gotchas, verified on PostgreSQL 14–18.
Every Pro query on this site is executed against real PostgreSQL and verified — we never publish an untested snippet.
Already a member? Log in
3 Recovery & verify Free
Terminate long-running idle-in-transaction sessions. Set idle_in_transaction_session_timeout. For urgent wraparound risk: run VACUUM FREEZE manually. Tune autovacuum aggressiveness for the affected table.