Обновление версий PostgreSQL, или Как не уронить базу при update?

Мы решили поделиться памяткой (чеклистом) нашей команды по обновлению PostgreSQL. В ней мы отметили взяли за основу фичи, представленные в release официальной документации PostgreSQL и провели анализ на предмет нарушения совместимости и кому стоит обратить внимание на обновленный функционал.

gogrx_o1snszctdlmfssbp-7ihs.png


Меня зовут Александр Коцюруба, я руковожу разработкой внутренних сервисов в компании DomClick.ru.

Статья разбита на части с заголовками. Каждый заголовок относится к обновлению PostgreSQL с одной версии на другую. В рамках каждой главы мы выделили:

- Фича
- Риск, который может повлечь потенциальная несовместимость
- - Нарушение работы приложения
- - Падение производительности
- Кому обратить внимание при обновлении
- - Системный администратор
- - Разработчик
- Комментарий


Итак, начнем.

Способы обновления


  • pg_upgrade — не самый надежный способ обновления PostreSQL. Например, вы можете получить ошибку при проведении REINDEX’a предыдущей версии PostgreSQL.
  • logical replication — звучит заманчиво, так как позволит свести downtime при обновлении до минимума. Но, logical replication появилось только в 10. Теоретический для этой цели можно использовать pglogical (от 2ndquadrant), он поддерживает версии от 9.4 до 12. Поэтому, если вы используете PostgreSQL<10.0, данное расширение может быть полезно.
  • pg_dumpall — проверенный способ. Недостаток — на больших БД будет большой downtime.
  • pg_dumpall --globals-only с последующим pg_dump --create. На наш взгляд, более предпочтительный метод, чем предыдущий, для обновления кластеров PostgreSQL.


PostgreSQL 9.5 → 9.6


Интересная фича s8khgz1aryhdmzcurk5cxdji7x0.jpeg


Возможность аннулирования старых снимков MVCC после настраиваемого промежутка времени (Кевин Гриттнер)

Обычно удалённые кортежи не могут быть ликвидированы физически при очистке, пока не будет отработана последняя транзакция, в которой они могут быть видны. Транзакция, остающаяся открытой в течение долгого времени, может стать причиной значительного замусоривания таблицы, препятствуя освобождению места. Это средство позволяет задать с помощью нового конфигурационного параметра old_snapshot_threshold ограничение времени, в течение которого снимок MVCC будет гарантированно актуальным. По истечении этого времени мёртвые кортежи могут быть удалены. Транзакция, использующая просроченный снимок, получит ошибку, если она попытается прочитать страницу, которая могла бы содержать такие данные.


Решает проблему «раздутия» БД по причине «открыл транзакцию и ушел в отпуск»; необдуманных апдейтов, которые занимают часы; долгих select как на master, так и на slave. Это одна из двух опций, благодаря которой можно будет решить проблему, из-за которой не могут перегрузить долгие запросы с master на slave.

PostgreSQL 9.6 → 10.0


Интересные фичи s8khgz1aryhdmzcurk5cxdji7x0.jpeg


Логическая репликация по схеме публикации/подписки


Полезная фича, которая может использоваться для апгрейда с минимальным простоем.

Декларативное секционирование таблиц


Новый декларативный синтаксис упростил партицирование таблиц.

Улучшение распараллеливания запросов


Изначально в 9.6 появилась поддержка параллельного выполнения больших запросов. Но она касалась только операций сканирования, join’ов и агрегаций.

В 10.0, в свою очередь, появилась возможность параллельного выполнения:

  • B-Tree index scan
  • Bitmap scan
  • Merge joins
  • Некоррелированных подзапросов


Более сильная защита паролей с использованием SCRAM-SHA-256


Может быть несовместим с какими-то нестандартными (не libpq) библиотеками подключения к PostgreSQL.

PostgreSQL 10.0 → 11.0


Интересные фичи s8khgz1aryhdmzcurk5cxdji7x0.jpeg


Добавление оператора сопоставления префиксов text ^@ text и реализация его поддержки в SP-GiST (Ильдус Курбангалиев)

Он действует подобно конструкции переменная LIKE 'слово%' с индексом btree, но обрабатывается более эффективно.


Поиск по префиксу встречается довольно часто. Для этого добавили специальный оператор с поддержкой специальных индексов. И что самое интересное, в официальной документации про этот оператор не сказано ни слова. Вместо него упоминается функция starts_with — внутренняя функция, на которой основан этот оператор, но её использование не дает ускорения с помощью индекса.

Сведение выражения переменная = переменная к выражению переменная IS NOT NULL там, где они равнозначны (Том Лейн)

Благодаря этому улучшается оценка избирательности.


Как ни странно, встречали такую конструкцию на практике. Судя по всему, данный случай не редкий.

PostgreSQL 11.0 → 12.0


Интересная фича s8khgz1aryhdmzcurk5cxdji7x0.jpeg


Реализация более компактного хранения многоколоночных индексов btree (Питер Гейган, Хейкки Линнакангас)

Внутренние страницы и индикаторы минимума/максимума на страницах листьев теперь содержат не все ключи индекса, а только те, изменение которых является определяющим. Это также улучшает сосредоточенность обращений к индексу.

Это улучшение не распространяется на индексы, полученные в результате обновления предыдущей версии с помощью pg_upgrade.


Еще один аргумент не в пользу pg_upgrade.

Заключение
Этот чеклист — наша «выжимка» из официальных ресурсов PostgreSQL. На практике, в зависимости от подходов в разработке, критичность тех или иных совместимостей для вас может быть иной. Буду рад, если статья кого-то убережет от потери данных или сократит трудозатраты на обновление PostgreSQL.

P.S.
Спасибо Самойлову Олегу (splarv) за помощь в подготовке статьи.

© Habrahabr.ru