PostgreSQL 19 выходит без SQL/PGQ: правильное решение
Каждый, кто администрировал Postgres-primary объёмом больше терабайта, смотрел на отчёт о bloat и прикидывал время простоя. Либо смириться с ростом диска, либо назначить окно технического обслуживания, которого никто не хочет, либо потянуться к стороннему инструменту и надеяться, что топология репликации не подведёт. PostgreSQL 19 наконец решает эту проблему в ядре. И при этом тихо отказывается от громкой функции, которая была ещё не готова.
В чём проблема
Коротко: как сообщал The Register, разработчики PostgreSQL убрали из версии 19 запланированную поддержку граф-запросов SQL/PGQ из-за неустранённых ошибок. Четвёртая бета выходит 24 сентября, а окончательная дата релиза пока не подтверждена. Давний участник проекта Том Лейн высказался прямо: «Сейчас я готов поспорить на ужин, что если мы выпустим это в v19, после релиза обнаружатся баги, которые невозможно будет исправить до v20.» Том Кинкейд, старший вице-президент по разработке программного обеспечения в EDB, подтвердил это решение и сообщил, что сообщество хотело проработать ещё ряд моментов перед выпуском.
SQL/PGQ важен тем, что стал частью стандарта SQL в 2023 году и даёт переносимый синтаксис для запросов к узлам и рёбрам графа, не покидая реляционного движка. Для команд, которые держали отдельную графовую базу рядом с Postgres для графов мошенничества, KYC-сетей, партнёрских иерархий или путей атрибуции в ad-tech, обещание было значительным: убрать sidecar, сохранить один источник истины, одну стратегию резервного копирования, одну HA-историю. Это обещание теперь откладывается до версии 20.
Между тем операционная боль, которая никогда не попадала в маркетинговые слайды, — это как раз то, что исправляет данный релиз. VACUUM FULL переписывает таблицу, чтобы вернуть место, занятое устаревшими версиями строк, и освободить его для операционной системы. При этом удерживается эксклюзивная блокировка таблицы на всё время операции, блокируя все операции чтения и записи. На нагруженной OLTP-таблице это не операция технического обслуживания. Это авария с прикреплённым тикетом на изменение.
Кинкейд описал паттерн, который я наблюдал десятки раз во время дежурств: «Ночные звонки случались из-за того, что кто-то запускал VACUUM FULL, и клиенты не могли получить доступ к данным, или кто-то хотел знать, почему это выполняется». Каждый DBA, читающий это, понимающе кивнул. Bloat накапливается, autovacuum не успевает за высоконагруженной таблицей, кто-то в итоге запускает VACUUM FULL, и пейджер начинает кричать.
Доступные варианты
До версии 19 у команд было три реалистичных варианта для освобождения места в горячей таблице, и ни один из них не был приятным.
Вариант первый: запланировать VACUUM FULL и принять простой. Это работает для внутренних отчётных таблиц или всего, что можно заморозить в низкотрафиковое окно. Для iGaming-оператора, принимающего ставки в реальном времени, или финтех-компании, закрывающей позиции, низкотрафикового окна достаточной продолжительности попросту нет. Производственные инциденты, которые я наблюдал, обычно начинаются именно здесь — когда кто-то предполагает, что «это будет быстро», применительно к таблице в 400 ГБ.
Вариант второй: pg_repack как расширение. Это расширение сообщества годами выполняет задачу конкурентной перезаписи, и оно работает. Но оно также добавляет операционную нагрузку: установить и версионировать расширение на каждой реплике, следить за его временными таблицами, обрабатывать крайние случаи со слотами репликации, и надеяться, что провайдер управляемого Postgres его поддерживает. Кто-то поддерживает, кто-то нет. Когда перезапись прерывается на полпути, очистка выполняется вручную и сопровождается стрессом.
Вариант третий: партиционировать таблицу и удалять старые партиции. Это правильный долгосрочный ответ для временны́х рядов и рабочих нагрузок с преобладающей записью, и это должно быть настройкой по умолчанию для любой таблицы, которая, по вашим ожиданиям, превысит несколько сотен гигабайт. Это не поможет вам сегодня с существующей монструозной таблицей, которая никогда не была партиционирована. Перевод партиционирования на живую таблицу объёмом 2 ТБ — это самостоятельный проект на несколько недель.
PostgreSQL 19 добавляет четвёртый вариант: новую команду REPACK с модификатором CONCURRENTLY. Обычный REPACK ведёт себя как VACUUM FULL и удерживает эксклюзивную блокировку на всё время. REPACK CONCURRENTLY позволяет другим транзакциям обращаться к таблице в течение большей части операции и требует короткой эксклюзивной блокировки лишь при подмене переписанных файлов таблицы и индексов. Именно такую операцию команды хотели видеть в ядре на протяжении десяти лет.
Моё мнение: это тихо переносит работу pg_repack в базовый дистрибутив, что гораздо важнее для клиентов managed-database, чем для тех, кто разворачивает Postgres самостоятельно. Если вы работаете на облачном провайдере, который исторически медленно добавляет расширения в белый список, теперь вы получите конкурентный repack, как только они перейдут на 19. Это на один разговор с закупками меньше и на один режим отказа в вашем runbook меньше.
На стороне SQL/PGQ альтернативы остаются прежними. Сохраняйте существующее графовое хранилище (Neo4j, Memgraph, AGE на Postgres) или моделируйте связи с помощью рекурсивных CTE и платите налог в виде нагрузки на планировщик запросов. В этом цикле нечего нового оценивать. Возвращайтесь к этому в версии 20. Следите за документацией PostgreSQL, когда выйдут заметки о релизе с точным синтаксисом REPACK.
Что реально нужно сделать инженерным командам
Во-первых, не переписывайте дорожные карты вокруг SQL/PGQ. Если ваш план на 2026 год предполагал вывод из эксплуатации графового sidecar в Q4, этот план мёртв. Перенесите миграцию на конец 2027 года в лучшем случае — при условии, что версия 20 выйдет по обычному годовому расписанию и PGQ действительно войдёт в неё. Ставки на невыпущенные функции обжигали команды, с которыми я работал, больше раз, чем я могу сосчитать. Фраза Лейна «поспорю на ужин» — это вежливый инженерный способ сказать «это нас преследует». Уважайте это.
Во-вторых, проведите аудит bloat сейчас, до выхода 19. Определите десять таблиц с наибольшим соотношением мёртвых кортежей и физическим bloat. Ранжируйте их по критичности для бизнеса и допустимости блокировок. Это ваши кандидаты для REPACK CONCURRENTLY в первые девяносто дней после обновления. Вам нужен готовый приоритизированный список, а не авральное тушение пожара.
В-третьих, рассматривайте обновление до 19 как двухфазное развёртывание. Фаза первая: перейти на 19 на read-репликах и некритичных кластерах, проверить инструменты резервного копирования и PITR, убедиться, что мониторинг обнаруживает новую команду. Фаза вторая: запустить REPACK CONCURRENTLY на staging-клоне вашей наиболее раздутой таблицы и измерить фактическую продолжительность короткой эксклюзивной блокировки на шаге подмены. «Как правило, удерживается лишь кратковременно» — такова формулировка в документации. Ваше конкретное железо, задержка репликации и профиль конкуренции за блокировки определяют, что значит «кратковременно» именно для вас.
В-четвёртых, если вы сейчас платите за сторонний инструмент repack или уровень управления расширениями, существующий главным образом для поддержки pg_repack, запланируйте ревизию через шесть месяцев после обновления. Возможно, вы сможете упростить стек.
Подводные камни и крайние случаи
Короткая эксклюзивная блокировка на шаге подмены файлов — это всё равно блокировка. На таблице с SLO субмиллисекундной задержки и активными конкурентными записями даже короткая блокировка может поставить в очередь достаточно транзакций, чтобы исчерпать пул соединений. Тестируйте с нагрузкой, репрезентативной для продакшна, а не с синтетическим бенчмарком. Неудобная истина: команды, воспринимающие «concurrent» как «нулевое воздействие», получают неприятные сюрпризы.
Поведение репликации — второй момент для проверки. Любая операция, переписывающая таблицу, генерирует значительный объём WAL. Если ваши реплики географически удалены или ограничены по пропускной способности, планируйте всплеск задержки во время repack и убедитесь, что трафик чтения может это допустить или корректно переключиться. Рассмотрите запуск OpenTelemetry-спанов вокруг операции, чтобы коррелировать задержку приложения с окном перезаписи.
В-третьих, следите за свободным местом на диске. Конкурентная перезапись требует достаточно свободного пространства, чтобы хранить вторую копию таблицы вместе с индексами до завершения подмены. Для таблицы в 500 ГБ с тремя индексами это не погрешность округления. Подготовьте ресурсы заранее, иначе операция прервётся на полпути и придётся выполнять очистку вручную.
Наконец, не пропускайте бета-тестирование на том основании, что «это просто команда repack». Тот же релизный поезд, который вызвал достаточно опасений, чтобы убрать SQL/PGQ, выпускает и REPACK. Запустите бета 4 против копии вашей рабочей нагрузки после 24 сентября. Лучше найти крайний случай самостоятельно, чем в 3 часа ночи в ожидании клиентов.
Ключевые выводы
- SQL/PGQ исключён из 19. Любой пункт дорожной карты, предполагавший нативные граф-запросы в Postgres в этом году, должен быть перенесён на версию 20 или откатан к существующим графовым хранилищам и рекурсивным CTE.
- REPACK CONCURRENTLY — это скрытая жемчужина. Он переносит работу pg_repack в ядро, требуя лишь короткой эксклюзивной блокировки при подмене файлов вместо полной блокировки на всё время, как это делает VACUUM FULL.
- Проведите аудит bloat до обновления. Подготовьте ранжированный список таблиц для первоочередной перезаписи, чтобы действовать в первый квартал после обновления, а не в панике.
- Тестируйте окно подмены под нагрузкой. «Кратковременно» зависит от рабочей нагрузки. Измерьте длительность блокировки на staging с реалистичным уровнем конкурентности перед применением к таблице, обслуживающей клиентов.
- Поаплодируйте решению об исключении. Убрать сырую громкую функцию до релиза — это правильное решение. Именно так должна вести себя база данных, которой вы доверяете деньги и данные клиентов.
Часто задаваемые вопросы
В: Почему SQL/PGQ убрали из PostgreSQL 19?
Сообщество PostgreSQL исключило SQL/PGQ из-за неустранённых ошибок. Давний участник проекта Том Лейн предупредил, что выпуск в версии 19 с высокой вероятностью приведёт к обнаружению пострелизных багов, которые невозможно будет исправить до версии 20. Том Кинкейд из EDB подтвердил, что сообщество хотело больше времени перед выпуском.
В: В чём разница между VACUUM FULL и REPACK CONCURRENTLY?
VACUUM FULL переписывает таблицу для освобождения места, но удерживает эксклюзивную блокировку всё время, блокируя все операции чтения и записи. REPACK CONCURRENTLY позволяет другим транзакциям обращаться к таблице в течение большей части перезаписи и требует лишь короткой эксклюзивной блокировки при подмене переписанных файлов.
В: Когда выйдет PostgreSQL 19?
Окончательная дата релиза пока не подтверждена. Четвёртая бета запланирована на 24 сентября 2026 года, а дата общедоступного выпуска будет зависеть от хода бета-цикла и от того, появятся ли новые блокирующие проблемы.
Уязвимость PostGREShell в PostgreSQL за 12 лет превратила репликацию в RCE
CVE-2026-6471 скрывалась в логическом декодировании PostgreSQL с релиза 9.4 в 2014 году. Двенадцать лет в production-коде — и роль репликации без суперпользователя стала вектором RCE.
Дорожная карта США и Великобритании по стейблкоинам ставит ФРС в условия жёстких сроков
США и Великобритания согласовали правила резервов стейблкоинов, приоритет при банкротстве и токенизированные активы — с прогнозом £44 млрд для Великобритании и дедлайном GENIUS Act в январе 2027 года.
332 рекламных объявления с CSAM от Meta угрожают статусу посредника
Министр IT Индии заявил, что Meta признала нарушения в рекламе CSAM. 332 объявления с AI-контентом, выявленные TTP, при затратах менее $5 000, ставят под угрозу статус посредника.




