Armadilha da partição default: nova partição falha com 'would be violated by some row'
PostgreSQLParticionamentoComando
-- Which periods have rows in the default partition?
SELECT date_trunc('month', created_at)::date AS month, count(*) AS row_count
FROM sales_default
GROUP BY 1
ORDER BY 1;
-- Move the rows into a new partition and attach it in one transaction
BEGIN;
SET LOCAL lock_timeout = '5s';
LOCK TABLE sales_default IN ACCESS EXCLUSIVE MODE;
CREATE TABLE sales_2027_02 (LIKE sales INCLUDING DEFAULTS INCLUDING CONSTRAINTS);
WITH moved AS (
DELETE FROM sales_default
WHERE created_at >= DATE '2027-02-01' AND created_at < DATE '2027-03-01'
RETURNING *
)
INSERT INTO sales_2027_02 SELECT * FROM moved;
ALTER TABLE sales ATTACH PARTITION sales_2027_02
FOR VALUES FROM ('2027-02-01') TO ('2027-03-01');
COMMIT;O que faz
Conta, por período, as linhas que caíram na partição default; move as linhas dentro do intervalo da nova partição para uma nova tabela e a anexa, tudo em uma única transação.
Quando usar
Quando CREATE TABLE ... PARTITION OF ou ATTACH falha com 'updated partition constraint for default partition would be violated by some row' ou quando se percebe que a partição default está crescendo.
Atenção
Com uma partição default presente, toda nova partição varre a default por completo e mantém ACCESS EXCLUSIVE nela enquanto isso; uma partição default grande significa uma indisponibilidade a cada manutenção. A default fica fechada para gravações enquanto as linhas são movidas; faça isso com tráfego baixo. Correção permanente: crie as partições antecipadamente e mantenha a default vazia com monitoramento (alerta se a contagem de linhas > 0), ou não use uma, para que INSERTs fora do intervalo falhem e o problema apareça cedo. Uma partição default também impede DETACH ... CONCURRENTLY.
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)
- Desanexar uma partição antiga sem bloquear o tráfego em produção (DETACH CONCURRENTLY)
- 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