ADG Оставить заявку
Блог Данные и аналитика 4 мин чтения

PostgreSQL 15 GA: обновляем продуктивные базы и замеряем планировщик

PostgreSQL 15 вышел в GA с оператором MERGE и row-level filtering в логической репликации. Составляем чеклист обновления и смотрим на планировщик вживую.

Контекст момента

PostgreSQL 15 GA - первый в истории оператор MERGE в стандарте SQL:2003, улучшена логическая репликация с row-level filtering

PostgreSQL 15 вышел в GA 13 октября. Мы вели наблюдение за бетой с августа, и вот момент настал: пора переводить клиентские базы с PG14. Не все сразу и не с разбегу - у нас несколько продуктивных кластеров под DWH-инфраструктурой, и у каждого своя история индексов, расширений и тонких настроек планировщика. Поэтому первым делом - чеклист, потом замеры, потом решение по каждому кластеру отдельно.

Что реально изменилось в 15

Про MERGE мы писали в августе на бете - команда работает именно так, как ожидалось, и до GA в ней ничего принципиального не сломалось. Кратко для контекста: это первый в PostgreSQL полноценный оператор из стандарта SQL:2003, который позволяет в одном выражении описать несколько веток - вставить если нет, обновить если есть, удалить если пришёл маркер удаления. ETL-код с ним действительно становится чище.

Второй крупный блок - логическая репликация с row-level filtering. Теперь можно описать публикацию с условием WHERE:

CREATE PUBLICATION pub_active_orders
    FOR TABLE orders (id, customer_id, status, amount)
    WHERE (status != 'archived');

Реплика получает только строки, удовлетворяющие условию. До PG15 фильтрация была только на уровне таблиц и столбцов, не строк. У нас есть один клиент с аналитическим стримером, который реплицирует несколько горячих таблиц - эта фича снимает костыль в виде триггеров на источнике, которые мы городили для отсева архивных записей.

Остальное, что замечаем в changelog: улучшения сортировки (incremental sort, сжатие WAL через LZ4/Zstd), изменения в pg_stat_activity и поведении search_path по умолчанию. Последнее важно: в PG15 роль PUBLIC больше не получает привилегию CREATE на схему public по умолчанию. Мелочь, которая может неожиданно сломать объекты, которые скрипты создавали в public без явного GRANT.

Чеклист перед обновлением

Прошлись по каждому кластеру. Список вопросов, которые реально выстреливают:

Расширения. pg_catalog, pg_stat_statements, pg_repack - версии должны быть совместимы с PG15. pg_repack в частности нужно пересобирать. У одного клиента стоял pglogical - пришлось изучать матрицу совместимости отдельно.

Логическая репликация. Если используется - слоты репликации нужно пересоздать после мажорного обновления. Это не баг, это архитектура: слоты привязаны к версии WAL-формата. Плановая остановка стримера, обновление, пересоздание слота, рестарт.

search_path и схемы. Проверили все кастомные роли - у двух клиентов были скрипты, которые создавали объекты в схеме public без явного GRANT, полагаясь на привилегию по умолчанию. Прописали явный GRANT CREATE ON SCHEMA public на соответствующих ролях заранее.

Расширения в contrib. pgcrypto, uuid-ossp - убедились что установлены в целевой версии пакета. Банальность, но экономит нервы при pg_upgrade.

Тест pg_upgrade --check. Запускаем в режиме только проверки без реального обновления. Он находит несовместимости в системных каталогах и нестандартных типах. На двух кластерах нашёл предупреждения по oid-типам в пользовательских таблицах - не критично, но лучше знать заранее.

Что с планировщиком

Это было интересно. На PG14 у одного клиента был медленный запрос - агрегация по нескольким таблицам с несколькими JOIN-ами, выполнялась заметно дольше, чем хотелось бы. Планировщик выбирал nested loop там, где hash join был бы явно эффективнее. Мы ставили enable_nestloop = off локально для сессии как временный workaround.

На PG15 тот же запрос без каких-либо изменений получил другой план - hash join без принудительных подсказок. Время выполнения сократилось ощутимо. Это не реклама и не "магия новой версии" - планировщик в 15 получил доработки в оценке стоимости для некоторых паттернов соединений, и в данном конкретном запросе это сыграло. На других запросах изменений в планах не увидели вообще.

Полезное упражнение: прогнать EXPLAIN (ANALYZE, BUFFERS) на десятке самых частых тяжёлых запросов сначала на PG14, потом на тестовом PG15 с копией данных. У нас три кластера, прогнали всё - нигде регрессий не нашли. На одном кластере несколько запросов ускорились, на двух других - без изменений в пределах погрешности.

Где сейчас

Один кластер уже переведён на PG15 - наименее критичный, с неплохим окном для обслуживания. Работает неделю, замечаний нет. Два других запланированы на ноябрь: один в плановое окно, второй требует согласования с клиентом по времени стопа репликации.

MERGE начинаем переводить в продакшн-код постепенно - только новые ETL-функции, старые пока не трогаем. Row-level filtering в репликации ждёт ноябрьского окна вместе с основным кластером.

PG15 выглядит как добротный релиз без сюрпризов - именно такой, какой хочется видеть когда обновляешь продуктивные базы.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.