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 выглядит как добротный релиз без сюрпризов - именно такой, какой хочется видеть когда обновляешь продуктивные базы.
- MERGE в PostgreSQL 15 beta: тестируем на реальных ETL-процессах · 4 августа 2022