준비된 테이블을 짧은 락으로 파티션에 연결(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)나 아카이브 복원 시: 운영 테이블을 건드리지 않고 데이터를 준비한 후 한 번에 온라인으로 전환한다.
주의
ATTACH는 부모에 SHARE UPDATE EXCLUSIVE, 연결할 테이블에 ACCESS EXCLUSIVE를 잡는다. 일치하는 유효한 CHECK가 없으면 경계 검증을 위해 그 락 상태에서 테이블 전체를 스캔한다. 부모와 일치하는 인덱스가 없으면 ATTACH가 락 상태에서 인덱스를 만들므로 둘 다 미리 준비한다. default 파티션이 있으면 새 범위의 행이 없음을 증명하기 위해 default 파티션도 스캔한다(default 파티션 레시피 참고). 컬럼 이름과 타입은 부모와 정확히 일치해야 하며, LIKE ... INCLUDING으로 테이블을 만드는 것이 가장 안전하다.