Détacher une ancienne partition sans bloquer le trafic (DETACH CONCURRENTLY)
PostgreSQLPartitionnementCommande
-- 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;Ce que fait la commande
Détache la partition en deux transactions ; ne prend que SHARE UPDATE EXCLUSIVE sur le parent pour ne pas bloquer les requêtes en cours, et ajoute à la table détachée une contrainte CHECK équivalente à la borne de partition.
Quand l'utiliser
Lors du détachement d'anciennes périodes sur un système en production pour rétention/archivage (suivi d'un DROP, d'un déplacement vers un autre tablespace ou d'une archive pg_dump).
Attention
Ne peut pas s'exécuter dans un bloc BEGIN ... COMMIT et ne peut pas être utilisé lorsque le parent a une partition par défaut. Il attend toutes les transactions qui utilisent le parent et ont démarré avant lui ; les transactions longues le prolongent. En cas d'interruption, la partition reste masquée aux requêtes mais non détachée ('detach pending') et doit être finalisée avec FINALIZE. Un DETACH simple sans CONCURRENTLY est plus rapide mais exige ACCESS EXCLUSIVE sur le parent ; essayez-le avec lock_timeout.
Voir aussi
- Créer une table partitionnée par range mensuel (générer les partitions dans une boucle)
- Attacher une table préparée comme partition avec un verrou court (ATTACH PARTITION)
- Piège de la partition par défaut : une nouvelle partition échoue avec 'would be violated by some row'
- Vérifier que le partition pruning fonctionne (à la planification et à l'exécution)
- Automatiser la création et la rétention des partitions avec pg_partman