Топ-100
  • Главная
  • Блог
  • Статьи
  • Укрощаем мажорные обновления: сценарий обновления системных данных каталога без лишней боли

Укрощаем мажорные обновления: сценарий обновления системных данных каталога без лишней боли

18.03.2025

В мире разработки и эксплуатации ПО мажорные обновления — это всегда стресс. Независимо от того, насколько хорошо вы тестируете изменения, всегда есть риск, что что-то пойдёт не так. Особенно это касается обновлений, которые затрагивают пользовательские данные. В какой-то момент мы задумались о том, как нам минимизировать риски и сделать обновления более предсказуемыми.

Меня зовут Кристина Демидович, я DevOps‑инженер в СберТехе, занимаюсь автоматизацией в команде СУБД Pangolin — это целевая СУБД в Сбере и не только. Я расскажу о нашем подходе к обновлению СУБД Pangolin, который позволил нам превратить часть мажорных обновлений в обновление данных системного каталога — что проще, удобнее и занимает вдвое меньше времени.

Здесь приводится сокращённая версия текста, больше технических деталей — в полной версии статьи на Хабре.  

Когда нужны мажорные обновления

Традиционно мажорное обновление предполагает полную миграцию данных. Как правило, это полный фарш: полный бэкап, инициализация новой БД и её настройка, подготовка конфигурационных файлов. Миграция с помощью pg_upgrade, после которого необходим запуск сборки новой статистики (vacuumdb). Перенос данных с помощью rsync, обновление версий расширений и так далее. Всё это необходимо выполнить единовременно. В общем, у мажорных обновлений есть ряд существенных недостатков:

  • они требуют много времени и ресурсов;
  • есть риски возникновения сбоев, которые могут привести к потере информации, ввиду того, что мы работаем с пользовательскими данными;
  • сложность откатов.

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

  • изменение мажорной версии базового PostgreSQL;
  • изменение логического или физического формата данных;
  • потеря обратной совместимости с предыдущими версиями функциональностей;
  • изменение системного каталога.

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

Нам надоело это терпеть — и мы дали жизнь новому способу обновления.

Работу разделили на два этапа:

  1. Разработка инструмента для обновления данных системного каталога.
  2. Автоматизация процесса обновления.

Как устроена работа инструмента

Подробно о том, как устроен этот инструмент, расскажет мой коллега Николай Литковец в своей статье. А я расскажу вкратце и перейду к автоматизации обновления. Да, уточню, что мы ставили в приоритет совместимость с инфраструктурой. Логика решения должна была быть прозрачной и не нарушать привычные процессы.

Механизм включает в себя добавление новых объектов в системный каталог и изменение существующих объектов. Всё начинается с создания дампа pg_catalog (это происходит до обновления), чтобы проверить согласованность исходных данных системных каталогов. С помощью дополнительной утилиты update_catalog_version меняется версия каталога. После этого каталоги до пользовательских табличных пространств переименовываются в соответствии с новой версией системного каталога.

Далее загружаем SQL-скрипты на master-хост, для всех баз данных, включая template0 и template1. Проходит это в две итерации. Сначала скрипты запускают с функцией ROLLBACK, чтобы проверить возможность их загрузки. Если тестовая загрузка прошла успешно, то скрипты запускают повторно без ROLLBACK.

После успешной загрузки всех SQL-скриптов во все БД создаётся повторный дамп pg_catalog для проверки консистентности обновлённых данных системного каталога.

Если при первой итерации загрузки данных возникают проблемы, то вторую итерацию не запускаем. Происходит откат к исходной версии системного каталога. Для восстановления работоспособности достаточно вернуть бинарные файлы исходной версии. Если есть проблемы при второй итерации, то требуется не только восстановить бинарные файлы исходной версии, но и запустить утилиту в режиме reset.

В случае кластерной конфигурации на replica-хост данные доезжают с помощью репликации.

Как устроена работа скриптов автоматизации

Следующий шаг — автоматизация запуска. Мы реализовали её через набор ролей Ansible, которые выполняют различные задачи: установку, обновление и настройку компонентов продукта. Простота управления заключается в разделении ролей по функциональным областям и компонентам продукта.

Каждая роль отвечает за выполнение определённых задач, связанных с конкретным компонентом или процессом. 

При подготовке новой модели обновления нам было важно следующее:

  • не затратить много времени на реализацию;
  • сократить время обновления;
  • обеспечить процесс восстановления;
  • сократить требования к процессу обновления (х2 места для бэкапа).

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

Сейчас наши плейбуки работают преимущественно с монолитными системами, хотя у нас есть планы по переходу на компонентную архитектуру. Но это уже другая история. Рассмотрим исходный плейбук для минорного обновления. Он состоит из трёх основных разделов:

  • обновление standalone-архитектур;
  • обновление кластерных архитектур;
  • откат в случае возникновения проблем.

Сосредоточимся на обновлении СУБД Pangolin. В случае кластерной конфигурации мы обеспечиваем отсутствие простоя с помощью последовательного обновления хостов.

При обновлении данных системного каталога БД нам требуется обеспечить полную недоступность СУБД для пользователей. Во время снятия дампов системных таблиц (например, pg_classpg_typepg_proc и других), которые содержат важную информацию о структуре данных, любые изменения этих таблиц могут привести к несоответствию между состоянием БД на момент начала обновления и по его окончании. Это может создать проблемы при восстановлении данных или привести к ошибкам в работе самой СУБД после обновления. Чтобы исключить эти риски, организован полный downtime — период, когда БД недоступна для всех операций записи и чтения со стороны пользователей.

Это ключевое отличие потребовало переработки плейбука.

Путь, по которому идёт обновление, определяется параметром pg_inplace_upgrade. Его значение вычисляется запуском скрипта inplace_upgrade.sh в режиме info. Запуск выполняется после всех проверок готовности стенда к обновлению в рамках роли pangolin_checks, причём одновременно на всех хостах. 

Обновление

Схематично последовательность действий выглядит так:

d0472491712a96ad563af3207719479b.png

Этап, отмеченный жёлтым цветом, играет важную роль. Он включает в себя:

  • бэкап системных файлов для возможности восстановления в случае ошибки во время работы скрипта inplace_upgrade.sh;
  • изменение версии системного каталога;
  • запуск узла БД;
  • снятие SQL-дампа исходного системного каталога для проверки целостности его системных данных;
  • обновление и добавление новых системных объектов;
  • снятие SQL-дампа обновлённого системного каталога для последующей проверки целостности его системных данных;
  • запуск тестов по проверке корректности обновления системных данных.

На этом этапе ключевой аспект — резервное копирование только системных файлов. Это отличается от полного резервного копирования всех данных, которое происходит при мажорном обновлении и может занимать длительное время на большой БД. 

Создание бэкапа определено первым шагом не случайно. На этом этапе обновления могут возникнуть сценарии, требующие последующего восстановления. В зависимости от кода состояния скрипта inplace_upgrade.sh, контролируется дальнейшая работа скриптов автоматизации. Рассмотрим возможные сценарии и их обработку:

  • Некорректное обновление без возможности автоматического восстановления (код: 1). Транзакция по изменению данных системного каталога была запущена, но при выполнении скрипта произошла критическая ошибка. Сообщение скриптов автоматизации:FAIL__В процессе обновления данных системного каталога возникли ошибки: {}. Процесс дальнейшего обновления остановлен. Автоматическое восстановление невозможно. Необходимо произвести анализ состояния стенда вручную и восстановить его к исходному состоянию или дообновить.__FAIL
  • Некорректное обновление с возможностью автоматического восстановления (код: 4). Транзакция по изменению данных системного каталога была запущена, но в дальнейшей работе скрипта произошла ошибка. Сообщение скриптов автоматизации:FAIL__В процессе обновления данных системного каталога возникли ошибки: {}. Процесс дальнейшего обновления остановлен. Будет запущено автоматическое восстановление.__FAIL
  • Некорректное обновление с возможностью автоматического восстановления (альтернативный сценарий) (код: 5). Транзакция по изменению данных системного каталога не была запущена, и данные в системном каталоге остались в исходном состоянии. Сообщение скриптов автоматизации:FAIL__В процессе обновления данных системного каталога возникли ошибки: {}. Процесс дальнейшего обновления остановлен. Будет запущено автоматическое восстановление.__FAIL
  • Корректное обновление (код: 0). Работа скрипта завершилась без ошибок. Сообщение скриптов автоматизации:INFO__Процесс обновления данных системного каталога завершился успешно.__INFOВажно уточнить: если сбой произойдёт до этого этапа, система может быть автоматически восстановлена, после — автоматически это будет уже невозможно. 

Восстановление

Параметр pg_inplace_upgrade управляет тем, как будет выполняться восстановление. 

Посмотрим на процесс восстановления на схеме:

0fac82fdfa368a634e8f0ee161eb0595.png

Как можно заметить, по существующим исходам работы inplace_upgrade.sh может быть два пути восстановления:

  • восстановление версии СУБД с запуском восстановления файлов системного каталога из бэкапа;
  • восстановление версии СУБД без запуска восстановления файлов системного каталога из бэкапа.

Восстановление версии СУБД с запуском восстановления файлов системного каталога из бэкапа предполагает возврат бинарных файлов к предыдущей версии СУБД, а также использование ранее созданной резервной копии данных для восстановления в исходное состояние данных системного каталога. Этот метод используется только если при обновлении были затронуты данные системного каталога. Восстановление из бэкапа происходит с помощью запуска скрипта inplace_upgrade.sh в режиме reset.

И восстановление версии СУБД без запуска восстановления файлов из бэкапа. Если данные системного каталога остались нетронутыми, достаточно вернуть бинарные файлы СУБД к предыдущей версии, не нужно восстанавливать файлы из бэкапа.

Результаты. Что насчёт скорости обновления

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

  • Мажорное обновление. Общее время обновления всех компонентов продукта в конфигурации cluster объёмом 100 ГБ — 65 минут.
  • Минорное обновление. Общее время обновления всех компонентов продукта в конфигурации cluster объёмом 100 ГБ — 25 минут.
  • Обновление данных системного каталога. Общее время обновления всех компонентов продукта в конфигурации cluster объёмом 100 ГБ — 23 минуты.

Мы внедрили обновление данных системных каталогов в версии 6.4.0. В результате этого текущее состояние наших версий выглядит так: 6.1.0 — 6.2.0 — 6.3.0 — 6.4.0 — 6.5.0 — 6.6.0 — 7.1.0. Изменение минорной версии означает обновление данных системных каталогов, а изменение мажорной версии — мажорное обновление. Если бы мы не внедрили этот подход, то наше состояние могло бы быть таким: 6.1.0 — 6.2.0 — 6.3.0 — 7.1.0 — 8.1.0 — 9.1.0 — 10.1.0.

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

  • Главная
  • Блог
  • Статьи
  • Укрощаем мажорные обновления: сценарий обновления системных данных каталога без лишней боли