準備した表を短いロックでパーティションとしてアタッチ(ATTACH PARTITION)
PostgreSQLパーティション化コマンド
-- 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;概要
別の表にロードしたデータを、境界と一致する事前検証済みのCHECK制約と事前作成したインデックスを使用して、フルスキャンや長いロックなしでパーティションにする。
使用する場面
一括ロード(ETL)やアーカイブからのリストアに: ライブの表に触れずにデータを準備し、1回の手順でオンラインにする。
注意
ATTACHは親表にSHARE UPDATE EXCLUSIVE、アタッチする表にACCESS EXCLUSIVEを取得する。一致する有効なCHECKがない場合、境界を検証するためにそのロックの下で表がフルスキャンされる。親と一致するインデックスがない場合、ATTACHはロックの下でそれを作成するため、両方を事前に準備する。デフォルトパーティションが存在する場合、新しい範囲の行を含まないことを証明するためにそれもスキャンされる(デフォルトパーティションのレシピを参照)。列名と型は親と完全に一致する必要がある。LIKE ... INCLUDINGで表を作成するのが最も安全。