SlideShare a Scribd company logo
Долгожданный релиз pg_pathman
Дмитрий Иванов, Александр Коротков
Так зачем секционировать?
• Управление большими объемами данных
• Быстрые запросы к наиболее используемым секциям
(локальность данных)
• Хранение старых данных на медленных носителях или
отдельных серверах (FDW)
• Pagination без OFFSET + LIMIT
• Ротация данных при помощи секций
• Таблица содержит архивные данные, в последнюю секцию
добавляются новые данные
• Содержимое таблицы должно быть распределено между
дисками или серверами (шардинг)
• Хочется ускорить запросы к определенным срезам данных
Когда нужно секционировать?
Старый добрый метод
CREATE TABLE partitioned (val INT);
CREATE TABLE partitioned_1 (LIKE partitioned INCLUDING ALL)
INHERITS (partitioned);
ALTER TABLE partitioned_1 ADD CHECK (val >= 1 AND val < 100);
Минусы
• Много ручной работы (управление секциями)
• Полный перебор секций при планировании
• Отсутствие оптимизаций во время исполнения
• Нет встроенной поддержки HASH секционирования
• Не копируются foreign keys родителя
• “Интересные” проблемы с ACL (привилегии)
Решение
• Выбрать какое-нибудь расширение для автоматизации
рутины (не решает проблему с планированием)
• Попробовать написать свое :)
pg_pathman - это:
• Поддержка HASH и RANGE секционирования
• Автоматическое + ручное управление секциями
• Улучшенное планирование запросов
• RuntimeAppend - выбор секции во время исполнения
• PartitionFilter - INSERT без триггеров
• Перехват оператора COPY FROM/TO
• Неблокирующее конкурентное секционирование
• Поддержка FDW
Основные элементы API
• Создание секций (add, attach, append, prepend)
• Управление созданными секциями (merge, split, drop)
• Генерация check constraints и триггеров для UPDATE
• Установка обработчиков создания секций
• Представление (view) с информацией о секциях
• Представление (view) с перечнем задач конкурентного
секционирования
• Таблица для хранения опциональных настроек
Этапы выполнения запроса
Parser Rewriter Planner Executor
RuntimeAppend
(узел исполнения)
PartitionFilter
(узел исполнения)
условия WHERE
(исключение секций)
Обработка условий (WHERE)
1. Механизм constraint exclusion в PostgreSQL не упрощает
условия WHERE, которые попадают в секции. Они
передаются “как есть”.
2. pg_pathman упрощает условия WHERE, которые попадают в
каждую конкретную секцию.
3. Рассмотрим, как pg_pathman справляется с этим, на
примере. Пусть данные разбиты на 6 секций по колонке
ts. Каждая секция – один месяц начиная с 01.2016.
SELECT * FROM test WHERE (ts >= '2015-02-01' AND ts < '2015-03-15')
OR (ts >= '2015-05-15' AND ts < '2015-07-01');
OR
AND AND
ts >= ‘2016-02-01’ ts < ‘2016-03-15’ ts >= ‘2016-05-15’ ts < ‘2016-07-01’
OR
AND AND
ts >= ‘2016-02-01’ ts < ‘2016-03-15’ ts >= ‘2016-05-15’ ts < ‘2016-07-01’
F T T T T T T T M F F F
OR
AND AND
ts >= ‘2016-02-01’ ts < ‘2016-03-15’ ts >= ‘2016-05-15’ ts < ‘2016-07-01’
F T T T T T T T M F F F F F F F M T T T T T T T
OR
AND AND
ts >= ‘2016-02-01’ ts < ‘2016-03-15’ ts >= ‘2016-05-15’ ts < ‘2016-07-01’
F T T T T T T T M F F F F F F F M T T T T T T T
F F F F M TF T M F F F
OR
AND AND
ts >= ‘2016-02-01’ ts < ‘2016-03-15’ ts >= ‘2016-05-15’ ts < ‘2016-07-01’
F T T T T T T T M F F F F F F F M T T T T T T T
F F F F M TF T M F F F
F T M F M T
EXPLAIN SELECT * FROM test WHERE (ts >= '2015-02-01' AND ts < '2015-03-15')
OR (ts >= '2015-05-15' AND ts < '2015-07-01');
QUERY PLAN
--------------------------------------------------------------------------------
Append (cost=0.00..3248.59 rows=0 width=0)
-> Seq Scan on test_2 (cost=0.00..780.20 rows=0 width=0)
-> Index Scan using test_3_ts_idx on test_3 (cost=0.29..767.99 rows=0 width=0)
Index Cond: (ts < '2015-03-15 00:00:00'::timestamp without time zone)
-> Seq Scan on test_5 (cost=0.00..864.40 rows=0 width=0)
Filter: (ts >= '2015-05-15 00:00:00'::timestamp without time zone)
-> Seq Scan on test_6 (cost=0.00..836.00 rows=0 width=0)
(7 rows)
AppendSeqScan
21
28
10
21
14
10
10
14
AppendSeqScan
21
28
10
21
14
10
10
14 [10, 21)
[21, 31)
AppendSeqScan
10
21
14
10
10
14 [10, 21)
[21, 31)
28
21
RuntimeAppend
• Выбирает только те секции, которые подходят под условия
(WHERE) в данный момент времени (на этапе исполнения)
• Умеет вычислять условия с параметрами ($N)
• Побочный эффект: EXPLAIN (без ANALYZE) показывает
всех детей, так как мы должны запланировать все сканы
до стадии исполнения
RuntimeAppendSeqScan
10
21
14
10
10
14 [10, 21)
RuntimeAppendSeqScan
10
21
14
25
27
21
[21, 31)
RuntimeAppendSeqScan
10
21
14
10
10
14 [10, 21)
SELECT * FROM partitioned_table
WHERE id = (SELECT * FROM some_table LIMIT 1);
SELECT * FROM partitioned_table
WHERE id = ANY (SELECT * FROM some_table LIMIT 4);
SELECT * FROM partitioned_table
JOIN some_table USING (id);
Было:
EXPLAIN (COSTS OFF)
INSERT INTO partitioned_table
SELECT generate_series(1, 10), random();
QUERY PLAN
-----------------------------------------
Insert on partitioned_table
-> Subquery Scan on “*SELECT*”
-> Result
(3 rows)
PartitionFilter
Стало:
EXPLAIN (COSTS OFF)
INSERT INTO partitioned_table
SELECT generate_series(1, 10), random();
QUERY PLAN
-----------------------------------------
Insert on partitioned_table
-> Custom Scan (PartitionFilter)
-> Subquery Scan on “*SELECT*”
-> Result
(4 rows)
PartitionFilter
INSERT
SubPlan
(данные)
PartitionFilter
PartitionFilter
INSERT
SubPlan
(данные)
PartitionFilter
PartitionFilter
INSERT
SubPlan
(данные)
PartitionFilter
секция #1 [1, 101)
секция #2 [101, 201)
секция #3 [201, 301)
секция #4 [301, 401)
…
(схема партицирования)
PartitionFilter
INSERT
SubPlan
(данные)
PartitionFilter
секция #1 [1, 101)
секция #2 [101, 201)
секция #3 [201, 301)
секция #4 [301, 401)
…
(схема партицирования)
текущая таблица
PartitionFilter
INSERT
SubPlan
(данные)
PartitionFilter
выбранная секция
PartitionFilter
INSERT
SubPlan
(данные)
PartitionFilter
выбранная секция
Плюсы PartitionFilter
• Быстрая вставка данных (сравнимо с обычной таблицей)
• Поддержка предложения RETURNING *
• Как следствие, корректно отображается число
вставленных строк
• Поддержка триггеров
INSERT INTO journal (dt, level, msg)
VALUES ('2016-12-31', random(), 'test')
RETURNING *;
id | dt | level | msg
---------+-----------------------+-------+------
1051202 | 2016-12-31 00:00:00 | 0 | test
(1 row)
INSERT 0 1
COPY journal TO stdout;
1051203 2016-12-31 00:00:00 1 test
COPY journal FROM '/home/dmitry/journal.sql';
PATHMAN COPY 1
SELECT * FROM ONLY journal;
id | dt | level | msg
----+----+-------+-----
(0 rows)
Бенчмарки
CREATE TABLE journal (
id SERIAL PRIMARY KEY ,
dt TIMESTAMP NOT NULL ,
level INTEGER,
msg TEXT);
CREATE INDEX journal_dt_idx ON journal (dt);
/* разбиваем на 366 секций, по 1 на день, затем заполняем данными: */
INSERT INTO journal (dt, level, msg) SELECT g, random() * 6, md5(g:: TEXT)
FROM generate_series( '2016-01-01'::DATE, '2016-12-31'::DATE, '30 seconds') as g;
Долгожданный релиз pg_pathman 1.0 / Александр Коротков,  Дмитрий Иванов (Postgres Professional)
Долгожданный релиз pg_pathman 1.0 / Александр Коротков,  Дмитрий Иванов (Postgres Professional)
Долгожданный релиз pg_pathman 1.0 / Александр Коротков,  Дмитрий Иванов (Postgres Professional)
Долгожданный релиз pg_pathman 1.0 / Александр Коротков,  Дмитрий Иванов (Postgres Professional)
Бенчмарки - RuntimeAppend
CREATE TABLE rappend_test(
id INT NOT NULL,
val REAL,
comment TEXT);
CREATE INDEX ON rappend_test (id, comment);
/* разбиваем, заполняем данными */
SELECT create_range_partitions( 'rappend_test' , 'id', 1, W, N);
INSERT INTO rappend_test select g, random(), g:: TEXT FROM generate_series(1, (1E8)) AS g;
(500 partitions)
(1000 partitions)
Выводы
• pg_pathman даёт достаточно богатую функциональность. И гораздо
более высокую производительность, чем все другие расширения,
основанные на constraint exclusion.
• pg_pathman’ом можно пользоваться уже сейчас. Мы знаем, что то там,
то тут баги, но реагируем оперативно!
• Декларативный синтаксис будет в 10 (очень надеемся!). Но всех фич
pg_pathman он достигнет (самое раннее) к 11 (2018 г.).
• Как только с декларативным синтаксисом будут решены основные
вопросы, мы будем портировать свои фичи туда.

More Related Content

PDF
"Секционирование без границ" Ильдар Мусин (Postgres Professional)
PDF
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
PPTX
Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...
PDF
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
PDF
Как читать и интерпретировать вывод команды EXPLAIN
PDF
Where is the space, Postgres?
PDF
#RuPostgresLive 4: как писать и читать сложные SQL-запросы
PDF
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...
"Секционирование без границ" Ильдар Мусин (Postgres Professional)
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
Разработка real-time приложений с RethinkDB / Илья Вербицкий (Независимый кон...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Как читать и интерпретировать вывод команды EXPLAIN
Where is the space, Postgres?
#RuPostgresLive 4: как писать и читать сложные SQL-запросы
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...

What's hot (20)

PDF
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
PDF
Дмитрий Новиков - Tarantool в Badoo
PDF
Call of Postgres: Advanced Operations (part 3)
PDF
2014.10.15 блиц-доклад PostgreSQL kNN search
PDF
PostgreSQL performance recipes
PDF
2014.12.23 Николай Самохвалов, Ещё раз о JSON(b) в PostgreSQL 9.4
PDF
Использование Tarantool для хранения чатов и лент друзей (Константин Осипов)
PDF
Call of Postgres: Advanced Operations (part 4)
PDF
Лекция 10. Apache Mahout
PDF
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
PDF
Новые возможности отладки MySQL 5.7 на практике
PDF
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
ODP
Hacking PostgreSQL. Физическое представление данных
PDF
MariaDB 10.1 - что нового.
PDF
Haskell
PDF
MySQL: Есть ли жизнь после 1 млрд. записей.
PPTX
MyRocks: табличный движок для MySQL на основе RocksDB
PDF
Hacking PostgreSQL. Разделяемая память и блокировки.
PDF
Расширения для PostgreSQL
PDF
Делаем очередь поверх Кассандры
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
Дмитрий Новиков - Tarantool в Badoo
Call of Postgres: Advanced Operations (part 3)
2014.10.15 блиц-доклад PostgreSQL kNN search
PostgreSQL performance recipes
2014.12.23 Николай Самохвалов, Ещё раз о JSON(b) в PostgreSQL 9.4
Использование Tarantool для хранения чатов и лент друзей (Константин Осипов)
Call of Postgres: Advanced Operations (part 4)
Лекция 10. Apache Mahout
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Новые возможности отладки MySQL 5.7 на практике
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Hacking PostgreSQL. Физическое представление данных
MariaDB 10.1 - что нового.
Haskell
MySQL: Есть ли жизнь после 1 млрд. записей.
MyRocks: табличный движок для MySQL на основе RocksDB
Hacking PostgreSQL. Разделяемая память и блокировки.
Расширения для PostgreSQL
Делаем очередь поверх Кассандры
Ad

Viewers also liked (20)

PDF
История успеха Яндекс.Почты с PostgreSQL / Владимир Бородин (Яндекс)
PDF
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
PDF
NoSQL внутри SQL: приземленные вопросы практического применения / Дмитрий До...
PDF
Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...
PDF
Девять кругов ада или PostgreSQL Vacuum / Алексей Лесовский (PostgreSQL-Consu...
PDF
Хайлоад и безопасность в мире DevOps: совместимы ли? / Юрий Колесов (security...
PPTX
Мастер-класс "Микросервисы: удобно, надежно, серебрянопульно" / Евгений Павло...
PDF
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
PDF
Последние новости постгреса с PGCon / О.Бартунов, А.Коротков, Ф.Сигаев (Postg...
PDF
"High load в условиях ограниченных ресурсов", Олег Бунин
PDF
2015.07.16 Способы диагностики PostgreSQL
PDF
"Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (...
PDF
Опыт миграции между дата-центрами / Михаил Тюрин, Сергей Бурладян (Avito)
PDF
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
PDF
Non-Relational Postgres / Bruce Momjian (EnterpriseDB)
PPTX
DCI @ XING - масштабируя бизнес-логику / Борис Тверитнев (XING)
PDF
Performance management lessons learnt / Андрей Дмитриев (JUGRU)
PDF
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
PDF
Как защитить 1 триллион IoT-устройств / Алексей Ермишкин (Virgil Security)
PDF
Хранение данных на виниле / Константин Осипов (tarantool.org)
История успеха Яндекс.Почты с PostgreSQL / Владимир Бородин (Яндекс)
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
NoSQL внутри SQL: приземленные вопросы практического применения / Дмитрий До...
Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...
Девять кругов ада или PostgreSQL Vacuum / Алексей Лесовский (PostgreSQL-Consu...
Хайлоад и безопасность в мире DevOps: совместимы ли? / Юрий Колесов (security...
Мастер-класс "Микросервисы: удобно, надежно, серебрянопульно" / Евгений Павло...
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
Последние новости постгреса с PGCon / О.Бартунов, А.Коротков, Ф.Сигаев (Postg...
"High load в условиях ограниченных ресурсов", Олег Бунин
2015.07.16 Способы диагностики PostgreSQL
"Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (...
Опыт миграции между дата-центрами / Михаил Тюрин, Сергей Бурладян (Avito)
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Non-Relational Postgres / Bruce Momjian (EnterpriseDB)
DCI @ XING - масштабируя бизнес-логику / Борис Тверитнев (XING)
Performance management lessons learnt / Андрей Дмитриев (JUGRU)
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
Как защитить 1 триллион IoT-устройств / Алексей Ермишкин (Virgil Security)
Хранение данных на виниле / Константин Осипов (tarantool.org)
Ad

Similar to Долгожданный релиз pg_pathman 1.0 / Александр Коротков, Дмитрий Иванов (Postgres Professional) (20)

PDF
SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение во...
PDF
Олег Бартунов, Федор Сигаев, Александр Коротков (PostgreSQL)
PPTX
High Load 2009 Dimaa Rus Ready
PPTX
Что такое Postgresql (Максим Богук)
PDF
Народные средства оптимизации PostgreSQL
PDF
Максим Богук. Postgres-XC
PDF
Всеволод Поляков "История одного мониторинга"
PPTX
#PostgreSQLRussia в банке Тинькофф, доклад №1
PPTX
СУБД осень 2012 Лекция 2
PDF
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
PPT
SAMag2007 Conference: PostgreSQL 8.3 presentation
PDF
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
PDF
Waits monitoring in PostgreSQL
PDF
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
PPTX
High Load 2009 Dimaa Rus Ready 16 9
PPT
поиск узких мест в производительности My sql ботанический определитель. г. ру...
PPTX
Новые возможности языка SQL в Firebird 3.0
PDF
Java 8 puzzlers
PDF
React со скоростью света: не совсем обычный серверный рендеринг
PPTX
Oracle how to live without cloud control
SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение во...
Олег Бартунов, Федор Сигаев, Александр Коротков (PostgreSQL)
High Load 2009 Dimaa Rus Ready
Что такое Postgresql (Максим Богук)
Народные средства оптимизации PostgreSQL
Максим Богук. Postgres-XC
Всеволод Поляков "История одного мониторинга"
#PostgreSQLRussia в банке Тинькофф, доклад №1
СУБД осень 2012 Лекция 2
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
SAMag2007 Conference: PostgreSQL 8.3 presentation
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
Waits monitoring in PostgreSQL
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
High Load 2009 Dimaa Rus Ready 16 9
поиск узких мест в производительности My sql ботанический определитель. г. ру...
Новые возможности языка SQL в Firebird 3.0
Java 8 puzzlers
React со скоростью света: не совсем обычный серверный рендеринг
Oracle how to live without cloud control

More from Ontico (20)

PDF
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
PDF
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
PPTX
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
PDF
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
PDF
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
PDF
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PDF
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
PDF
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
PPTX
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
PPTX
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
PDF
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
PPTX
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
PPTX
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
PDF
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
PPT
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
PPTX
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
PPTX
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
PPTX
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
PPTX
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
PDF
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...

Долгожданный релиз pg_pathman 1.0 / Александр Коротков, Дмитрий Иванов (Postgres Professional)

  • 1. Долгожданный релиз pg_pathman Дмитрий Иванов, Александр Коротков
  • 2. Так зачем секционировать? • Управление большими объемами данных • Быстрые запросы к наиболее используемым секциям (локальность данных) • Хранение старых данных на медленных носителях или отдельных серверах (FDW) • Pagination без OFFSET + LIMIT • Ротация данных при помощи секций
  • 3. • Таблица содержит архивные данные, в последнюю секцию добавляются новые данные • Содержимое таблицы должно быть распределено между дисками или серверами (шардинг) • Хочется ускорить запросы к определенным срезам данных Когда нужно секционировать?
  • 4. Старый добрый метод CREATE TABLE partitioned (val INT); CREATE TABLE partitioned_1 (LIKE partitioned INCLUDING ALL) INHERITS (partitioned); ALTER TABLE partitioned_1 ADD CHECK (val >= 1 AND val < 100);
  • 5. Минусы • Много ручной работы (управление секциями) • Полный перебор секций при планировании • Отсутствие оптимизаций во время исполнения • Нет встроенной поддержки HASH секционирования • Не копируются foreign keys родителя • “Интересные” проблемы с ACL (привилегии)
  • 6. Решение • Выбрать какое-нибудь расширение для автоматизации рутины (не решает проблему с планированием) • Попробовать написать свое :)
  • 7. pg_pathman - это: • Поддержка HASH и RANGE секционирования • Автоматическое + ручное управление секциями • Улучшенное планирование запросов • RuntimeAppend - выбор секции во время исполнения • PartitionFilter - INSERT без триггеров • Перехват оператора COPY FROM/TO • Неблокирующее конкурентное секционирование • Поддержка FDW
  • 8. Основные элементы API • Создание секций (add, attach, append, prepend) • Управление созданными секциями (merge, split, drop) • Генерация check constraints и триггеров для UPDATE • Установка обработчиков создания секций • Представление (view) с информацией о секциях • Представление (view) с перечнем задач конкурентного секционирования • Таблица для хранения опциональных настроек
  • 11. Обработка условий (WHERE) 1. Механизм constraint exclusion в PostgreSQL не упрощает условия WHERE, которые попадают в секции. Они передаются “как есть”. 2. pg_pathman упрощает условия WHERE, которые попадают в каждую конкретную секцию. 3. Рассмотрим, как pg_pathman справляется с этим, на примере. Пусть данные разбиты на 6 секций по колонке ts. Каждая секция – один месяц начиная с 01.2016.
  • 12. SELECT * FROM test WHERE (ts >= '2015-02-01' AND ts < '2015-03-15') OR (ts >= '2015-05-15' AND ts < '2015-07-01');
  • 13. OR AND AND ts >= ‘2016-02-01’ ts < ‘2016-03-15’ ts >= ‘2016-05-15’ ts < ‘2016-07-01’
  • 14. OR AND AND ts >= ‘2016-02-01’ ts < ‘2016-03-15’ ts >= ‘2016-05-15’ ts < ‘2016-07-01’ F T T T T T T T M F F F
  • 15. OR AND AND ts >= ‘2016-02-01’ ts < ‘2016-03-15’ ts >= ‘2016-05-15’ ts < ‘2016-07-01’ F T T T T T T T M F F F F F F F M T T T T T T T
  • 16. OR AND AND ts >= ‘2016-02-01’ ts < ‘2016-03-15’ ts >= ‘2016-05-15’ ts < ‘2016-07-01’ F T T T T T T T M F F F F F F F M T T T T T T T F F F F M TF T M F F F
  • 17. OR AND AND ts >= ‘2016-02-01’ ts < ‘2016-03-15’ ts >= ‘2016-05-15’ ts < ‘2016-07-01’ F T T T T T T T M F F F F F F F M T T T T T T T F F F F M TF T M F F F F T M F M T
  • 18. EXPLAIN SELECT * FROM test WHERE (ts >= '2015-02-01' AND ts < '2015-03-15') OR (ts >= '2015-05-15' AND ts < '2015-07-01'); QUERY PLAN -------------------------------------------------------------------------------- Append (cost=0.00..3248.59 rows=0 width=0) -> Seq Scan on test_2 (cost=0.00..780.20 rows=0 width=0) -> Index Scan using test_3_ts_idx on test_3 (cost=0.29..767.99 rows=0 width=0) Index Cond: (ts < '2015-03-15 00:00:00'::timestamp without time zone) -> Seq Scan on test_5 (cost=0.00..864.40 rows=0 width=0) Filter: (ts >= '2015-05-15 00:00:00'::timestamp without time zone) -> Seq Scan on test_6 (cost=0.00..836.00 rows=0 width=0) (7 rows)
  • 22. RuntimeAppend • Выбирает только те секции, которые подходят под условия (WHERE) в данный момент времени (на этапе исполнения) • Умеет вычислять условия с параметрами ($N) • Побочный эффект: EXPLAIN (без ANALYZE) показывает всех детей, так как мы должны запланировать все сканы до стадии исполнения
  • 26. SELECT * FROM partitioned_table WHERE id = (SELECT * FROM some_table LIMIT 1); SELECT * FROM partitioned_table WHERE id = ANY (SELECT * FROM some_table LIMIT 4); SELECT * FROM partitioned_table JOIN some_table USING (id);
  • 27. Было: EXPLAIN (COSTS OFF) INSERT INTO partitioned_table SELECT generate_series(1, 10), random(); QUERY PLAN ----------------------------------------- Insert on partitioned_table -> Subquery Scan on “*SELECT*” -> Result (3 rows) PartitionFilter Стало: EXPLAIN (COSTS OFF) INSERT INTO partitioned_table SELECT generate_series(1, 10), random(); QUERY PLAN ----------------------------------------- Insert on partitioned_table -> Custom Scan (PartitionFilter) -> Subquery Scan on “*SELECT*” -> Result (4 rows)
  • 30. PartitionFilter INSERT SubPlan (данные) PartitionFilter секция #1 [1, 101) секция #2 [101, 201) секция #3 [201, 301) секция #4 [301, 401) … (схема партицирования)
  • 31. PartitionFilter INSERT SubPlan (данные) PartitionFilter секция #1 [1, 101) секция #2 [101, 201) секция #3 [201, 301) секция #4 [301, 401) … (схема партицирования) текущая таблица
  • 34. Плюсы PartitionFilter • Быстрая вставка данных (сравнимо с обычной таблицей) • Поддержка предложения RETURNING * • Как следствие, корректно отображается число вставленных строк • Поддержка триггеров
  • 35. INSERT INTO journal (dt, level, msg) VALUES ('2016-12-31', random(), 'test') RETURNING *; id | dt | level | msg ---------+-----------------------+-------+------ 1051202 | 2016-12-31 00:00:00 | 0 | test (1 row) INSERT 0 1
  • 36. COPY journal TO stdout; 1051203 2016-12-31 00:00:00 1 test COPY journal FROM '/home/dmitry/journal.sql'; PATHMAN COPY 1 SELECT * FROM ONLY journal; id | dt | level | msg ----+----+-------+----- (0 rows)
  • 37. Бенчмарки CREATE TABLE journal ( id SERIAL PRIMARY KEY , dt TIMESTAMP NOT NULL , level INTEGER, msg TEXT); CREATE INDEX journal_dt_idx ON journal (dt); /* разбиваем на 366 секций, по 1 на день, затем заполняем данными: */ INSERT INTO journal (dt, level, msg) SELECT g, random() * 6, md5(g:: TEXT) FROM generate_series( '2016-01-01'::DATE, '2016-12-31'::DATE, '30 seconds') as g;
  • 42. Бенчмарки - RuntimeAppend CREATE TABLE rappend_test( id INT NOT NULL, val REAL, comment TEXT); CREATE INDEX ON rappend_test (id, comment); /* разбиваем, заполняем данными */ SELECT create_range_partitions( 'rappend_test' , 'id', 1, W, N); INSERT INTO rappend_test select g, random(), g:: TEXT FROM generate_series(1, (1E8)) AS g;
  • 45. Выводы • pg_pathman даёт достаточно богатую функциональность. И гораздо более высокую производительность, чем все другие расширения, основанные на constraint exclusion. • pg_pathman’ом можно пользоваться уже сейчас. Мы знаем, что то там, то тут баги, но реагируем оперативно! • Декларативный синтаксис будет в 10 (очень надеемся!). Но всех фич pg_pathman он достигнет (самое раннее) к 11 (2018 г.). • Как только с декларативным синтаксисом будут решены основные вопросы, мы будем портировать свои фичи туда.