Подключить подготовленную таблицу как секцию с короткой блокировкой (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 строит их под блокировкой, поэтому подготовьте и то, и другое заранее. Если существует секция по умолчанию, она тоже сканируется, чтобы доказать, что в ней нет строк нового диапазона (см. рецепт про секцию по умолчанию). Имена и типы столбцов должны точно совпадать с родителем; создание таблицы через LIKE ... INCLUDING — самый надёжный способ.
Связанные материалы
- Создать таблицу с помесячным range-секционированием (генерация секций в цикле)
- Отключить старую секцию, не блокируя рабочий трафик (DETACH CONCURRENTLY)
- Ловушка секции по умолчанию: создание новой секции завершается ошибкой 'would be violated by some row'
- Проверить, что работает отсечение секций (partition pruning) на этапе планирования и выполнения
- Автоматизировать создание секций и их хранение через pg_partman