Vorbereitete Tabelle mit kurzer Sperre als Partition einhängen (ATTACH PARTITION)
PostgreSQLPartitionierungBefehl
-- 1) Prepare the data in a separate table without touching the live table
CREATE TABLE sales_2027_01 (LIKE sales INCLUDING DEFAULTS INCLUDING CONSTRAINTS);
-- ... bulk load (COPY / INSERT) ...
ALTER TABLE sales_2027_01 ADD PRIMARY KEY (id, created_at);
CREATE INDEX CONCURRENTLY sales_2027_01_customer_id_idx ON sales_2027_01 (customer_id);
-- 2) A CHECK that exactly matches the bounds: avoids a full scan during ATTACH
ALTER TABLE sales_2027_01 ADD CONSTRAINT sales_2027_01_bound_chk
CHECK (created_at IS NOT NULL AND created_at >= DATE '2027-01-01' AND created_at < DATE '2027-02-01') NOT VALID;
ALTER TABLE sales_2027_01 VALIDATE CONSTRAINT sales_2027_01_bound_chk;
-- 3) Attach (SHARE UPDATE EXCLUSIVE on the parent; reads/writes continue)
SET lock_timeout = '5s';
ALTER TABLE sales ATTACH PARTITION sales_2027_01
FOR VALUES FROM ('2027-01-01') TO ('2027-02-01');
RESET lock_timeout;
-- 4) Drop the now redundant CHECK
ALTER TABLE sales_2027_01 DROP CONSTRAINT sales_2027_01_bound_chk;Was es tut
Macht in eine separate Tabelle geladene Daten ohne Full Scan und lange Sperren zur Partition, indem ein vorab validierter, zu den Grenzen passender CHECK-Constraint und vorab erstellte Indizes genutzt werden.
Wann einsetzen
Für Massenladungen (ETL) oder Wiederherstellungen aus dem Archiv: Daten vorbereiten, ohne die Live-Tabelle anzufassen, und dann in einem Schritt online bringen.
Vorsicht
ATTACH nimmt SHARE UPDATE EXCLUSIVE auf der Parent-Tabelle und ACCESS EXCLUSIVE auf der einzuhängenden Tabelle. Ohne passenden gültigen CHECK wird die Tabelle unter dieser Sperre vollständig gescannt, um die Grenzen zu validieren; fehlen zu den Parent-Indizes passende Indizes, baut ATTACH sie unter der Sperre auf, also beides vorab vorbereiten. Existiert eine Default-Partition, wird auch sie gescannt, um nachzuweisen, dass sie keine Zeilen im neuen Bereich enthält (siehe Rezept zur Default-Partition). Spaltennamen und -typen müssen exakt der Parent-Tabelle entsprechen; die Tabelle mit LIKE ... INCLUDING anzulegen ist der sicherste Weg.
Verwandte Einträge
- Monatlich Range-partitionierte Tabelle anlegen (Partitionen in einer Schleife erzeugen)
- Alte Partition aushängen, ohne den Live-Betrieb zu blockieren (DETACH CONCURRENTLY)
- Falle Default-Partition: neue Partition scheitert mit 'would be violated by some row'
- Prüfen, ob Partition Pruning funktioniert (Planungs- und Laufzeit)
- Anlegen und Aufbewahrung von Partitionen mit pg_partman automatisieren