Table Partitioning
AngaraBase поддерживает декларативное партицирование (RFC-2026-097 v1): RANGE и LIST стратегии с DEFAULT catch-all.
Поддерживаемые стратегии
| Стратегия | Синтаксис | Когда использовать |
|---|---|---|
| RANGE | PARTITION BY RANGE (col) | Временны́е ряды, диапазоны ID |
| LIST | PARTITION BY LIST (col) | Категориальные значения (регион, тип) |
| DEFAULT | PARTITION OF parent DEFAULT | Catch-all для строк вне всех диапазонов |
DDL
Создание партицированной таблицы
Для создания партицированной таблицы используется предложение PARTITION BY.
CREATE TABLE orders (
id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
amount_usd BIGINT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
month_ts BIGINT NOT NULL,
CONSTRAINT orders_pkey PRIMARY KEY (id, month_ts)
) PARTITION BY RANGE (month_ts);
Прикрепление дочерней секции
Дочерние секции (партиции) создаются с указанием родительской таблицы и диапазона значений (для RANGE) или списка значений (для LIST).
-- RANGE партиция для января 2025
CREATE TABLE orders_p2025_01 PARTITION OF orders
FOR VALUES FROM (1735689600) TO (1738368000);
-- RANGE партиция для февраля 2025
CREATE TABLE orders_p2025_02 PARTITION OF orders
FOR VALUES FROM (1738368000) TO (1740787200);
-- DEFAULT партиция (catch-all)
CREATE TABLE orders_p_default PARTITION OF orders DEFAULT;
DML через parent
INSERT
INSERT в parent автоматически маршрутизируется в подходящую child partition по значению partition key.
-- Строка попадёт в соответствующую month-partition
INSERT INTO orders (id, user_id, amount_usd, month_ts)
VALUES (1, 42, 9900, 1735689601);
Ошибка при отсутствии совпадения: если строка не входит ни в один диапазон и нет DEFAULT partition — SQLSTATE 23514 check_violation.
Ограничение ON CONFLICT: ON CONFLICT не поддерживается на partitioned parent — вернёт ошибку feature_not_supported (SQLSTATE 0A000).
SELECT через parent (UNION ALL expansion + pruning)
SELECT из parent автоматически разворачивается в UNION ALL по всем children. Если WHERE содержит условие на partition key — нерелевантные partitions пропускаются (pruning).
-- Сканирует только partition для January 2025
SELECT * FROM orders WHERE month_ts >= 1735689600 AND month_ts < 1738368000;
UPDATE через parent
UPDATE по non-partition key столбцам работает через fan-out на все (или pruned) children.
UPDATE orders SET status = 'shipped' WHERE id = 42 AND month_ts = 1735689601;
Ограничение: UPDATE partition key column запрещён — вернёт SQLSTATE 23514. Cross-partition row movement не поддерживается в v1.
DELETE через parent
DELETE с WHERE на partition key применяет pruning и удаляет только из matching children.
DELETE FROM orders WHERE month_ts = 1735689601 AND id = 42;
Мониторинг
| Метрика | Описание |
|---|---|
angarabase_partition_route_ok_total | Успешных INSERT routing в child |
angarabase_partition_route_no_match_total | INSERT без matching partition (→ 23514) |
angarabase_partition_route_default_total | INSERT в DEFAULT partition |
angarabase_partition_pruned_branches_total | Children пропущено при SELECT/DML |
Ограничения v1
- Hash partitioning — не поддерживается (planned v0.7)
- Subpartitioning / multi-column partition key — не поддерживается (v0.7)
- Cross-partition UPDATE — запрещён (явная ошибка 23514)
- ON CONFLICT на parent table — не поддерживается
- REINDEX через parent — не поддерживается
Troubleshooting
| Симптом | Причина | Решение |
|---|---|---|
ERROR 23514 check_violation при INSERT | Значение partition key не попадает ни в один диапазон | Добавить DEFAULT partition или проверить значение |
ERROR 23514 при UPDATE | Попытка изменить partition key column | Не изменяй partition key; DELETE + INSERT вместо UPDATE |
ERROR 0A000 ON CONFLICT not supported | ON CONFLICT через parent partition | Выполняй INSERT напрямую в child partition |