DBAtlas · Atlas de operações de banco de dados

Desanexar uma partição antiga sem bloquear o tráfego em produção (DETACH CONCURRENTLY)

PostgreSQLParticionamento

Comando

-- 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.

Abrir no DBAtlas →

Relacionados