How to fix Cannot detach partition in use in PostgreSQL
PostgreSQL prevents detaching a partition when active transactions or queries are accessing the partitioned table. This happens because the DETACH operation needs locks that conflict with running queries. Use DETACH PARTITION CONCURRENTLY (PostgreSQL 14+) or wait for transactions to complete.
Quick fix
Fixes 55006
SELECT pid, usename, application_name, state, query, query_start
FROM pg_stat_activity
WHERE datname = current_database()
AND state != 'idle'
ORDER BY query_start;- Check for active transactions using the partition
- Identify locks held on the partitioned table
- Terminate blocking transactions (if safe)
- Use DETACH PARTITION CONCURRENTLY (PostgreSQL 14+)
SELECT pid, usename, application_name, state, query, query_startFROM pg_stat_activityWHERE datname = current_database()AND state != 'idle'ORDER BY query_start;Cannot detach partition in use
What this error means
Error 55006 occurs when you attempt to detach a partition from a partitioned table while that partition (or its parent table) is in active use by other transactions or queries. PostgreSQL requires exclusive locks on the partitioned table to safely detach a partition, and these locks conflict with any ongoing read or write operations. This is a safety mechanism to prevent data corruption and ensure consistency. The error message "Cannot detach partition in use" indicates that PostgreSQL cannot acquire the necessary Access Exclusive lock on either the partition being detached (in older versions) or the parent table (in all versions), because other sessions are actively using the table. This commonly occurs in production environments where queries are continuously running against the partitioned table.
Typical symptoms
- DETACH PARTITION command hangs or times out while waiting for locks
- Application queries appear to freeze or hang after initiating a DETACH operation
- Error message "Cannot detach partition in use" when attempting ALTER TABLE DETACH PARTITION
- Long-running queries or idle transactions block the DETACH operation
- Database connections accumulate as they wait for the DETACH to complete
Common causes
- Active transactions are querying or modifying rows in the partitioned table or specific partition
- Idle transactions are holding locks on the partitioned table (even if not actively querying)
- Long-running batch jobs or reports are accessing the partition during the detach attempt
- Connection pools or ORMs maintain open transactions that hold locks on the table
- Prior to PostgreSQL 14, DETACH PARTITION requires Access Exclusive lock on the parent table, blocking all access to all partitions
How to fix "Cannot detach partition in use"
First, identify which transactions are blocking the DETACH operation:
SELECT pid, usename, application_name, state, query, query_start
FROM pg_stat_activity
WHERE datname = current_database()
AND state != 'idle'
ORDER BY query_start;This query shows all non-idle connections. Look for any queries accessing your partitioned table. The query_start column shows how long the query has been running.
Check which locks are currently held and which are being waited for:
SELECT l.pid, l.mode, l.granted, a.usename, a.query
FROM pg_locks l
JOIN pg_stat_activity a ON l.pid = a.pid
WHERE l.relation = 'your_table'::regclass
ORDER BY l.granted DESC;Replace your_table with your partitioned table name. Locks with granted = false are waiting for access, while granted = true are holding locks.
If you identify transactions that can be safely terminated, kill them:
-- For a single blocking session
SELECT pg_terminate_backend(12345); -- Replace 12345 with the PID
-- For all idle transactions
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = current_database()
AND state = 'idle in transaction'
AND pid != pg_backend_pid();Be very cautious: terminating transactions can cause data loss or application errors. Only terminate sessions you are certain can be safely killed.
If you are running PostgreSQL 14 or later, use the CONCURRENTLY option to minimize lock duration:
ALTER TABLE parent_table
DETACH PARTITION partition_name CONCURRENTLY;This operation uses SHARE UPDATE EXCLUSIVE lock instead of Access Exclusive, allowing other transactions to continue reading and writing to the parent table (including other partitions). CONCURRENTLY cannot be used in a transaction block—run it as a standalone statement. It also cannot be used if the partitioned table has a default partition.
The CONCURRENTLY detach runs in two transactions:
1. First transaction marks the partition as detached in the catalog
2. Second transaction waits for older snapshots to clear and completes the detach
This ensures consistency while minimizing blocking.
If running PostgreSQL < 14, you must wait for all active transactions to complete before DETACH can proceed. During low-traffic periods:
1. Monitor activity to confirm no long-running queries:
SELECT COUNT(*) FROM pg_stat_activity
WHERE datname = current_database() AND state != 'idle';2. Once the count is 0 or only idle transactions remain, attempt DETACH:
ALTER TABLE parent_table
DETACH PARTITION partition_name;3. Consider draining application connections before the DETACH to reduce wait time.
If a concurrent detach was cancelled or crashed mid-operation, complete it with:
ALTER TABLE parent_table
DETACH PARTITION partition_name FINALIZE;This finishes the second transaction of a previously started concurrent detach operation.
Advanced notes
PostgreSQL Versions and Locking: Prior to PostgreSQL 14, DETACH PARTITION acquires Access Exclusive lock on both the partition and the parent table, effectively freezing all access to all partitions until the operation completes. This is why "cannot detach partition in use" is such a severe issue in pre-14 deployments. PostgreSQL 14 introduced DETACH PARTITION CONCURRENTLY which uses only SHARE UPDATE EXCLUSIVE lock on the parent, allowing concurrent reads and writes. For production systems with continuous traffic, always upgrade to PostgreSQL 14+ if partition detachment is a regular operation.
Deadlock with DETACH CONCURRENTLY: In rare cases, DETACH PARTITION CONCURRENTLY can cause deadlocks with SERIALIZABLE or REPEATABLE READ transactions due to snapshot consistency checks (WaitForOlderSnapshots). If you encounter persistent deadlocks with concurrent detach, switch temporarily to non-concurrent detach during maintenance windows, or use SERIALIZABLE isolation on the fewest possible transactions.
Partitioned Tables with Foreign Keys: If the partitioned table has a foreign key constraint that references itself (where the partition key is part of the FK), PostgreSQL may prevent detach even if no data violations exist. The workaround is to drop the global FK, detach the partition, then rebuild independent FKs on each partition if needed.
Application Connection Pools: ORM connection pools and database drivers often maintain open transactions automatically. If you cannot identify blocking queries, check your application's connection pool settings. Tools like pgBouncer can help manage connections, and consider setting idle_in_transaction_session_timeout to automatically terminate idle transactions.
Frequently asked questions
- What does "55006" mean?
- Error 55006 occurs when you attempt to detach a partition from a partitioned table while that partition (or its parent table) is in active use by other transactions or queries. PostgreSQL requires exclusive locks on the partitioned table to safely detach a partition, and these locks conflict with any ongoing read or write operations. This is a safety mechanism to prevent data corruption and ensure consistency.
- How do I fix "55006"?
- PostgreSQL prevents detaching a partition when active transactions or queries are accessing the partitioned table. This happens because the DETACH operation needs locks that conflict with running queries. Use DETACH PARTITION CONCURRENTLY (PostgreSQL 14+) or wait for transactions to complete.
- What causes "55006"?
- Active transactions are querying or modifying rows in the partitioned table or specific partition Idle transactions are holding locks on the partitioned table (even if not actively querying) Long-running batch jobs or reports are accessing the partition during the detach attempt
- Is the "55006" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- 📚PostgreSQL Official Documentation
- 📖PostgreSQL Table Partitioning Documentation(Official Docs)
- 📖PostgreSQL Error Codes(Official Docs)