Desanexar uma partição antiga sem bloquear o tráfego em produção (DETACH CONCURRENTLY)
PostgreSQLParticionamentoComando
-- Must run outside a transaction block
ALTER TABLE sales DETACH PARTITION sales_2026_01 CONCURRENTLY;
-- If interrupted (cancel, lost connection) the partition stays 'detach pending'; complete it:
ALTER TABLE sales DETACH PARTITION sales_2026_01 FINALIZE;
-- Any pending detach?
SELECT inhrelid::regclass AS partition_name, inhparent::regclass AS parent
FROM pg_inherits
WHERE inhdetachpending;
-- The detached table is now standalone: archive or drop it
DROP TABLE sales_2026_01;O que faz
Desanexa a partição em duas transações; obtém apenas SHARE UPDATE EXCLUSIVE no pai, para que as consultas em execução não sejam bloqueadas, e adiciona à tabela desanexada uma constraint CHECK equivalente ao limite da partição.
Quando usar
Ao desanexar períodos antigos em um sistema em produção para retenção/arquivamento (seguido de DROP, de uma movimentação para outro tablespace ou de um arquivo pg_dump).
Atenção
Não pode ser executado dentro de um bloco BEGIN ... COMMIT e não pode ser usado quando o pai tem uma partição default. Espera todas as transações que usam o pai e começaram antes dele; transações longas o prolongam. Se interrompido, a partição fica oculta das consultas, mas não desanexada ('detach pending'), e precisa ser concluída com FINALIZE. Um DETACH simples sem CONCURRENTLY é mais rápido, mas precisa de ACCESS EXCLUSIVE no pai; tente-o com lock_timeout.
Relacionados
- Criar uma tabela particionada por range mensal (gerar as partições em um loop)
- Anexar uma tabela preparada como partição com um lock curto (ATTACH PARTITION)
- Armadilha da partição default: nova partição falha com 'would be violated by some row'
- Verificar se o partition pruning funciona (em tempo de planejamento e de execução)
- Automatizar a criação e a retenção de partições com pg_partman