Как стать автором
Обновить
443.74
Сбер
Технологии, меняющие мир

Как мы упростили обновление СУБД Pangolin: показываю бэкенд решения

Уровень сложностиСредний
Время на прочтение17 мин
Количество просмотров984

Привет, Хабр! Меня зовут Николай Литковец, я инженер-разработчик в СберТехе, развиваю СУБД Pangolin — это реляционная СУБД, целевая в Сбере и не только. До недавнего времени у нас было два типа обновлений СУБД: минорное и мажорное. Минорное обновление — быстро и сравнительно просто, мажорное — долго, муторно, со значительными затратами ресурсов сервера. Мы стали думать, можем ли мы где-то обойтись без перехода на мажорные версии? Нашли сценарий, где это было возможным, и через некоторое время у нас появилось минорно-мажорное обновление, которое теперь экономит нам силы и время. Я расскажу про создание инструмента, который позволил нам устроить эту реформу, как обходили риски, и что нам это дало.

В Platform V Pangolin DB изначально было предусмотрено два сценария обновления:

  • Обновление исполняемых данных. Или минорное обновление. Здесь достаточно заменить старые файлы (исполняемые, конфигурационные, файлы расширений) их обновлёнными версиями. Либо обновить версии утилит в составе дистрибутива. Формат внутреннего хранилища при таких модификациях не меняется. Минорное обновление мы проводим, например, при изменении конфигурационных файлов, используемых утилит и расширений. Или при доработке кода самой базы данных, когда в формат её внутреннего хранилища не вносятся изменения. 

  • Обновление с переносом данных. Или мажорное обновление. Здесь требуется провести миграцию данных, так как в этом сценарии вносятся изменения в формат внутреннего хранилища БД. 

Раньше мы проводили мажорные обновления в следующих случаях:

  • изменение мажорной версии базового PostgreSQL;

  • изменение логического или физического формата данных;

  • потеря обратной совместимости с предыдущими версиями функциональностей;

  • изменение системного каталога.

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

Как устроен системный каталог и его изменение

Системный каталог PostgreSQL — это центральный элемент базы данных. Он содержит метаданные обо всех её объектах: таблицах, индексах, пользователях и так далее. Его изменение может быть необходимо для повышения производительности, безопасности или добавления новых возможностей. 

Что именно понимается под изменением системного каталога:

  • изменение состава или структуры встроенных функций — pg_proc;

  • изменение списка встроенных типов данных — pg_type;

  • изменение состава или структуры встроенных представлений — pg_class, pg_type, pg_rewrite, а также ряда других таблиц.

Именно это зачастую требовало обновления с переносом данных. Наши изменения в составе и структуре вышеописанных системных каталогов включали в себя добавление новых объектов или модификацию (удаление) существующих.

Каждая функция, тип и представление имеют уникальный идентификатор OID (Object Identifier). Для перечисленных системных объектов он находится в диапазоне значений от 0 до 16 383 включительно. Внутри этого диапазона есть особенности:

  • OID 1–9999 зарезервированы для ручного присвоения;

  • OID 10 000–11 999 зарезервированы для автоматического присвоения с использованием скрипта genbki.pl;

  • OID 12 000–16 383 зарезервированы для неподключённых объектов, создаваемых в процессе инициализации базы данных командой initdb.

Системный каталог с описанными выше таблицами создаётся в каждой новой базе из шаблонов template0 и template1. Поэтому изменения каталогов требуется делать во всех БД.

При изменении системного каталога обновляется номер его версии, который хранится в файле global/pg_control.

Имена папок в табличных пространствах, создаваемых пользователями, совпадают с версиями системного каталога (PG_<POSTGRES_VERSION>_<CATALOG_VERSION_NO>).

При мажорном обновлении структура OID сохраняется благодаря созданию и инициализации новых баз данных с помощью команды initdb. Эта команда создаёт все объекты в соответствии с описанными правилами, включая назначение OID. При этом создаётся новый файл global/pg_control с актуальной версией системного каталога. Для переноса данных в новую базу переименовываются папки в пользовательских табличных пространствах. И создаются жёсткие символьные ссылки на эти пространства для новой БД. Это позволяет сохранить доступ к данным и обеспечить их целостность при обновлении системы.

Наша задача — сделать то же самое в уже существующей базе данных.

Реализация решения

Создаём сценарий минорно-мажорного обновления, называем его inplace upgrade. Он состоит из трёх основных частей:

  1. cкрипта обновления inplace_upgrade.sh;

  2. SQL-скриптов обновления системного каталога;

  3. утилиты обновления версии системного каталога.

Расскажу о них подробно.

Скрипт inplace_upgrade.sh содержит всю последовательность действий для обновления. Его задача — запустить Pangolin в режиме binary и применить SQL-скрипты обновления для всех баз данных. Запускается командой:

postgres --single -D $PGDATA -j -b $db_name -E -d 0

После чего СУБД запускается в режиме single: без pg_cron, autovacuum, пользовательских бэкендов и других процессов, которые могут помешать работе inplace upgrade. Режим binary используется, чтобы задавать OID новых объектов с системными значениями.

Но как запустить Pangolin с новыми исполняемыми файлами, если версия системного каталога, которая им соответствует, отличается от текущей версии? Для решения этой проблемы мы разработали утилиту update_catalog_version. С её помощью мы меняем версию системного каталога в начале запуска скрипта. 

Cистемные каталоги есть во всех обновляемых базах данных. Нам нужно предварительно получить их список. В скрипте обновления подразумевается запрос всех присутствующих БД. Запускаем БД в обычном режиме, применяем запрос: 

SELECT datname FROM pg_database;

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

mv -v $tbsp_dir/PG_$VERSION_POSTGRES_NO"_"$version_catalog_old "$tbsp_dir/PG_$VERSION_POSTGRES_NO"_"$version_catalog_new"

Чтобы не возникло проблем при доступе к БД, нужно сделать это до первого запуска Platform V Pangolin DB при обновлении. Нам требуется получить список всех табличных пространств, переименовать их. И список нужен до обновления исполняемых файлов СУБД.

Мы решили выполнять всё это на работающей базе до обновления. Список пользовательских табличных пространств получаем SQL-запросом:

SELECT pg_tablespace_location(oid) FROM pg_tablespace WHERE spcname not in ('pg_default', 'pg_global')

Так у нас появился ещё один режим работы скрипта. Мы назвали его info. Добавили ещё ряд дополнительных проверок, опишу их ниже. 

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

Что может пойти не так?

Главная опасность — испортить системный каталог. Если он сломается, то база данных вообще не запустится. Или может перестать работать ранее заявленная функциональность. Мы решили собирать все SQL-скрипты в одну транзакцию. Если где-то произойдёт ошибка, то изменения системного каталога не применятся. Однако ввиду того, что обновлять нужно больше одной базы данных, проблема может возникнуть в любой из них. Тогда получится, что часть баз данных обновится, а часть — нет. Чтобы этого не произошло, мы применяем скрипты обновления ко всем базам данных с последующим откатом. Если в результате не возникло ошибок, то обновляем все БД нашими скриптами.

Вроде бы задача решена. Только как нам убедиться в том, что мы не испортили целостность системных каталогов во всех БД? Используем утилиту pg_dump. Формируем дамп системных каталогов во всех базах данных после обновления:

pg_dump -h $HOST -p $PORT -U $USER -d $dbname -n pg_catalog

Если ошибок при снятии дампа не возникло, считаем, что системный каталог не повреждён. А чтобы определить, что базы данных изначально были в консистентном состоянии, мы формируем дампы системных каталогов во всех БД до обновления и не начинаем процесс, если где-то возникли ошибки.

Что делать, если мы всё-таки испортили системный каталог в какой-нибудь базе данных? Делаем резервную копию файлов системного каталога во всех БД. С помощью системной функции pg_relation_filepath узнаём имена файлов, соответствующих таблицам системного каталога, и сохраняем их копию. Если портится системный каталог, то восстанавливаем все его файлы из сохранённых копий.

Процедура восстановления системного каталога довольно сложная, поэтому она вынесена в отдельный режим работы скрипта reset.

Собственно, основной режим его работы мы назвали update. Он существует в двух вариантах:

  • на мастере;

  • на реплике.

Отличаются они только тем, что на реплике системный каталог дообновляется не с помощью скриптов обновления, а с помощью репликации.

Итак, у нас получилось три режима работы скрипта inplace_upgrade.sh:

  • info;

  • update;

  • reset.

Далее расскажу, как они работают.

Утилита обновления версии системного каталога update_catalog_version

Эта утилита разработана для обновлении версии системного каталога в файле global/pg_control. Как ранее упоминалось, Pangolin не запустится, если версия системного каталога в его исполняемых файлах не соответствует версии системного каталога в файле global/pg_control. Для этого утилита при остановленной базе данных считывает файл global/pg_control, формирует его копию pg_control.bak, проверяет, что новая версия системного каталога превышает текущую, и устанавливает новую версию системного каталога. Также можно поменять версию системного каталога в обход проверок на случай ручного восстановления версии системного каталога, при исправлении неполадок обновления.

SQL-скрипты обновления системного каталога

Они хранятся в отдельной директории sql_upgrade_6xx (пример для мажорной версии Platform V Pangolin DB 6хх) и представляют из себя следующую структуру:

+sql_upgrade_6xx

|+610

||CATALOG_VERSION

|+611

||CATALOG_VERSION

|+612

||CATALOG_VERSION

|+613

||CATALOG_VERSION

|+reset_sql

|+binary_upgrade_sql

|+upgrade_sql

|+614

||CATALOG_VERSION

|+615

||CATALOG_VERSION

|+616

||CATALOG_VERSION

|+reset_sql

|+upgrade_sql

|+617

||CATALOG_VERSION

|+618

||CATALOG_VERSION

|+620

||CATALOG_VERSION

|+reset_sql

|+upgrade_sql

|+630

||CATALOG_VERSION

|+reset_sql

|+upgrade_sql

|+640

||CATALOG_VERSION  

|+reset_sql

|+binary_upgrade_sql

Директория sql_upgrade_6xx содержит поддиректории для каждой версии Platform V Pangolin DB (например, 6.1.3). В каждой директории версии хранится файл с номером текущей версии системного каталога CATALOG_VERSION, папки со скриптами обновления binary_upgrade_sql и upgrade_sql и со скриптами ручного отката reset_sql. Эти скрипты отвечают за создание, удаление или изменения DDL-объектов базы данных. Единственное отличие скриптов работы с DDL-объектами заключается в использовании функций binary_upgrade_*. Эти функции, как и упоминалось ранее, позволяют создавать объекты в системном каталоге по заданным системным OID. Изначально они использовались при мажорном обновлении с помощью утилиты pg_upgrade. Вот пример такого SQL-скрипта для создания системной функции:

-- Создать функцию, если её нет по системному OID: system_oid < 10000
IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_proc WHERE
proname = 'my_function') THEN

-- Создание новой системной функции 

-- Вызов функции binary_upgrade_set_next_pg_proc_oid для задания конкретного OID системного каталога
    PERFORM pg_catalog.binary_upgrade_set_next_pg_proc_oid('9999'::pg_catalog.oid);
    CREATE FUNCTION pg_catalog.my_function() -- Здесь присутствует список аргументов функции, который создал разработчик
        RETURNS text
        LANGUAGE internal
        STABLE PARALLEL SAFE STRICT
    AS $function$my_function$function$;

 -- Обновление параметров в таблице pg_catalog.pg_proc (если требуется):
    UPDATE pg_catalog.pg_proc AS pp SET
    proacl = '{postgres=X/postgres}'
    WHERE pp.oid = (select oid from pg_catalog.pg_proc where proname = 'my_function');

 -- распечатка состояния после изменений из затронутых таблиц системного каталога (эта информация может понадобиться позже для диагностики или восстановления):
    SELECT rtrim(ltrim(replace(pg_proc::text, ',', '|'), '('), ')') INTO msg FROM pg_catalog.pg_proc WHERE proname = 'my_function';
    RAISE NOTICE 'CREATE FUNCTION pg_catalog.my_function: %', quote_ident(msg);
ELSE

-- Если функция уже присутствует в системном каталоге, то выдавать ошибку, так как неправильно установлены параметры обновления для текущей и новой версий СУБД:
    RAISE EXCEPTION 'The function "my_function" already exists, there may be a product version error.';
END IF;

-- Проверка наличия функции после обновления:

IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_proc WHERE proname = 'my_function') THEN
    RAISE EXCEPTION 'The function "my_function" does not exist.';
END IF;

SQL-скрипты создаются для каждой версии СУБД Pangolin, в которой происходят изменения в составе системного каталога. 

Разберём сценарии работы скрипта inplace_upgrade.sh

Обновление системного каталога проходит в два этапа.

  • Разведка: оценка возможностей и необходимости обновления.

  • Обновление: выполнение всех необходимых изменений и модификаций системы.

Рассмотрим пример обновления с версии 6.3.1 на версию 6.3.4. В этом процессе изменения системного каталога происходят в версиях 6.3.3 и 6.3.4. Это условный сценарий, но он демонстрирует последовательность действий.

Разведка

Здесь оценивается, можно и нужно ли выполнять обновление. Важно учесть, что в этот период база данных продолжает функционировать, но пользователям ограничен доступ к ней до завершения обновления. Сценарий выполняется как на основном сервере (мастере), так и на репликах.

Запуск сценария для разведки:

./inplace_upgrade.sh info -d <pgdata> -l <log_upgrade_dir> -s <test_util> -B <backup_dir> -p <port> -h <host> -u <user> -P <password> -b <db_name> --pg_ctldir <path_util postgres, pg_ctl> --pg_utildir <path_util psql, pg_dump> -n <version_old> -N <version_new>

Сценарий состоит из следующих этапов.

Проверка необходимости обновления: анализ структуры SQL-скриптов, предназначенных для обновления:

======= START INPLACE_UPGRADE IN INFO MODE =======

----------- Initial update analysis -----------

CATALOG_VERSION_NO_OLD: 202412111
Following directories will be searched to find sql-scripts applicable in this run:
<path_sql_scripts>/sql_upgrade_6xx/6.3.3/
Version: 6.3.3 CATALOG_VERSION_NO_NEW: 202412271
<path_sql_scripts>/sql_upgrade_6xx/6.3.4/
Version: 6.3.4 CATALOG_VERSION_NO_NEW: 202501151
Initial update analysis........................... OK

Проверка возможности обновления версии системного каталога:

----------- Update CATALOG_VERSION_NO -----------

Sat Feb 15 10:37:58 MSK 2025 INFO: update_catalog_version: Check catalog_version_no OK!.
Sat Feb 15 10:37:58 MSK 2025 INFO: Update CATALOG_VERSION_NO......................... OK

Проверка доступа к SQL-скриптам обновления на чтение:

----------- Read all catalog update SQL-scripts -----------

Read all catalog update SQL-scripts............... OK

Формирование списка табличных пространств:

----------- Extract info about users tablespaces -----------

paths: <list of directories>
version: <Pangolin version>
Extract info about users tablespaces.............. OK

При успешном прохождении всех этапов получаем соответствующее сообщение.

INFO mode finished with Success. Update required.

===================================================

Если все этапы проверок прошли без ошибок, переходим к обновлению.

Обновление

Есть два сценария обновления:

  • обновление мастера;

  • обновление реплики.

Сценарий обновления мастера

Запуск сценария:

./inplace_upgrade.sh update -d <pgdata> -l <log_upgrade_dir> -p <port> -h <host> -u <user> -b <db_name> -s <test_util> -m <dir_test> -P <password> -B <backup_dir> -n <version_old> -N <version_new> --pg_ctldir <path_util postgres, pg_ctl> --pg_utildir <path_util psql, pg_dump> -k

Выполняется на остановленной СУБД и состоит из следующих этапов.

Проверка необходимости обновления: анализ структуры SQL-скриптов, предназначенных для процесса. Этот шаг повторяет аналогичный этап разведки, где заново считываются версии системного каталога, нуждающиеся в обновлении.

======= START INPLACE_UPGRADE IN UPDATE MODE =======

CATALOG_VERSION_NO_OLD: 202412111
Following directories will be searched to find sql-scripts applicable in this run:
<path_sql_scripts>/sql_upgrade_6xx/6.3.3/
Version: 6.3.3 CATALOG_VERSION_NO_NEW: 202412271
<path_sql_scripts>/sql_upgrade_6xx/6.3.4/
Version: 6.3.4 CATALOG_VERSION_NO_NEW: 202501151
Initial update analysis........................... OK

Обновление версии системного каталога в файле global/pg_control: проводится с использованием утилиты update_catalog_version. Этот шаг крайне важен, поскольку без него СУБД не сможет запуститься.

----------- Update CATALOG_VERSION_NO -----------

update_catalog_version: Catalog version has been successfully updated to 202501151.

Update CATALOG_VERSION_NO......................... OK

Формирование общего SQL-скрипта обновления в соответствии с обновляемыми версиями:

----------- Read all catalog update SQL-scripts -----------

Read all catalog update SQL-scripts............... OK

Обновление названий папок в пользовательских табличных пространствах. Без этого шага после обновления нельзя получить доступ к пользовательским табличным пространствам.

----------- Update user tablespaces -----------

<list of updated directories>

Rename directories of user tablespaces

Update user tablespaces........................... OK

Создание дампов системного каталога во всех обновляемых БД с помощью утилиты pg_dump. Эти дампы нужны для анализа внесенных изменений в системный каталог (если возникнет такая потребность) и проверки его целостности.

Make dump for DB1

----------- Dump catalog_old_<DB1> -----------

Creating sql-dump of DB1 database's system catalog in <path_dump>/catalog_old_DB1.sql
Dump catalog_old_DB1......................... OK
Make dump for DB2...

Создание резервной копии системных каталогов для всех обновляемых баз данных. Запускаем СУБД, формируем список файлов, соответствующих таблицам системного каталога для всех баз данных. И эти файлы сохраняются в резервную копию. Также создаётся копия файла global/pg_control с версией системного каталога до обновления, чтобы сохранить указатель на текущий чекпоинт.

----------- Backup generation for all databases -----------

update_catalog_version: Catalog version has been successfully updated to 202412111.
Backup generation for all databases............... OK

Кроме того, мы сохраняем резервные копии папок pg_wal, pg_replslot и файла global/pg_control. Это нужно для полного отката изменений в случае возникновения проблем на дальнейших этапах.

Проверка обновления системных каталогов. СУБД запускается в режиме binary upgrade (аналогичном тому, что используется утилитой pg_upgrade для переноса объектов системного каталога с сохранением OID). Перед обновлением все необходимые скрипты применяются в тестовом режиме в одной транзакции с последующим откатом для всех баз данных.

Trial run of update sql-scripts (to check if they run fine) for database: DB1----------- Running sql-scripts for database: DB1 -----------

======== SQL script update ========

do $$
DECLARE
msg TEXT;
BEGIN
SET allow_system_table_mods = true;
SET LOCAL search_path TO pg_catalog;<update scripts>
SET allow_system_table_mods = false;
< update scripts >
ROLLBACK;
END
$$;

===================================

<output log>
Running sql-scripts for database: DB1........ OK
----------- Running sql-scripts for database: DB2 -----------
...

Обновление системных каталогов. СУБД запускается в режиме binary upgrade. После чего применяется скрипт обновления к одной базе данных.

----------- UPDATE RUN -----------

Upgrading database: DB1

----------- Running sql-scripts for database: DB1 -----------

======== SQL script update ========

do $$
	 DECLARE
	  msg TEXT;
BEGIN
SET allow_system_table_mods = true;
SET LOCAL search_path TO pg_catalog;
< update scripts >
SET allow_system_table_mods = false;
END
$$;

Затем СУБД останавливается и запускается в обычном режиме для создания дампа системного каталога после обновления одной базы данных. Этот дамп проверяет целостность системного каталога и если где-то что-то повреждено, выдаёт ошибку.

----------- Dump catalog_new_DB1 -----------

Creating sql-dump of DB1 database's system catalog in <path_dump>/catalog_new_DB1.sql
Dump catalog_new_DB1......................... OK

Эта процедура повторяется для всех обновляемых баз данных. После обновления системных каталогах во всех базах данных СУБД останавливается.

Окончание сценария обновления: после успешного обновления всех баз данных сценарий завершает работу.

Update Complete!

----------- Finish upgrade -----------
Finish upgrade.................................... OK
	UPDATE mode finished with Success.

===================================================

Важно: при возникновении проблем до этапа «Обновление системных каталогов», автоматически восстанавливается прежняя версия системного каталога и имена пользовательских табличных пространств (и обновления не происходит). Если же проблемы возникают после, то требуется запустить сценарий inplace_upgrade.sh в режиме восстановления. Опишу его ниже.

Обновление реплики

Это значительно проще, чем обновление мастера. Само обновление системного каталога происходит в момент синхронизации с мастером после завершения сценария обновления.

Запуск сценария на реплике:

./inplace_upgrade.sh update -d <pgdata> -l <log_upgrade_dir> -p <port> -h <host_standby> -u <user> -b <db_name> -s <test_util> -m <dir_test> -P <password> -B <backup_dir> -n <version_old> -N <version_new> --pg_ctldir <path_util postgres, pg_ctl> --pg_utildir <path_util psql, pg_dump> -r

Обновление выполняется на остановленной реплике и включает следующие этапы.

Проверка необходимости обновления: анализ структуры SQL-скриптов, предназначенных для обновления. 

======= START INPLACE_UPGRADE IN UPDATE MODE =======

ATALOG_VERSION_NO_OLD: 202412111
Following directories will be searched to find sql-scripts applicable in this run:
<path_sql_scripts>/sql_upgrade_6xx/6.3.3/
Version: 6.3.3 CATALOG_VERSION_NO_NEW: 202412271
<path_sql_scripts>/sql_upgrade_6xx/6.3.4/
Version: 6.3.4 CATALOG_VERSION_NO_NEW: 202501151
Initial update analysis........................... OK

Обновление версии системного каталога в файле global/pg_control:

----------- Update CATALOG_VERSION_NO -----------

update_catalog_version: Catalog version has been successfully updated to 202501151.
Update CATALOG_VERSION_NO......................... OK

Формирование общего SQL-скрипта обновления в соответствии с обновляемыми версиями. Сам скрипт для обновления не требуется, но он проверяет целостность всего сценария обновления.

----------- Read all catalog update SQL-scripts -----------

Read all catalog update SQL-scripts............... OK

Обновление названий папок в пользовательских табличных пространствах:

----------- Update user tablespaces -----------

<list of updated directories>
Rename directories of user tablespaces
Update user tablespaces........................... OK

Обновление мастера и реплики может происходить параллельно. В завершение обновления требуется восстановить синхронизацию между ними и убедиться в том, что она полностью завершилась. Это нужно, чтобы изменения системного каталога, сделанные на мастере, применились на реплике. Лишь после этого можно предоставить пользователям доступ к СУБД.

Откат изменений

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

Запуск сценария в режиме отката:

./inplace_upgrade.sh reset -d <pgdata> -l <log_upgrade_dir> -p <port> -h <host> -u <user> -b <db_name> -s <test_util> -m <dir_test> -P <password> -B <backup_dir> --pg_ctldir <path_util postgres, pg_ctl> --pg_utildir <path_util psql, pg_dump>

Откат изменений подразумевает запуск сценария восстановления на остановленной СУБД и включает следующие шаги.

Восстановление из резервной копии:

  • файла global/pg_control;

  • WAL-файлов;

  • физических слотов репликации;

  • файлов системных таблиц для всех баз данных.

======= START INPLACE_UPGRADE IN RESET MODE =======

----------- Restoring table files from backup -----------

<path_backup>/backup_db/base was restored to <path_pgdata>/.
<path_backup>/backup_db/global was restored to <path_pgdata>/.
<path_backup>/backup_db/db1 was restored to <path_db1>/.
...
Restoring table files from backup................. OK

Восстановление структуры системного каталога: удаляются те директории, которые появились после обновления СУБД и отсутствовали ранее.

----------- Restoring catalog structure -----------

An empty folder <path_pgdata>/test_dir was deleted
...
Sat Feb 15 16:17:04 MSK 2025 INFO: Restoring catalog structure....................... OK

Запуск СУБД и создание дампов системного каталога для всех баз данных. Эти дампы проверяют корректность отката изменений системного каталога и его целостность.

----------- Dump catalog_restore_DB1 -----------

Creating sql-dump of DB1 database's system catalog in <path_dump>/catalog_restore_DB1.sql
Dump catalog_restore_DB1......................... OK

----------- Dump catalog_restore_DB2 -----------

Creating sql-dump of DB2 database's system catalog in <path_dump>/catalog_restore_DB2.sql
Dump catalog_restore_DB2......................... OK
...

После выполнения этих шагов восстановление считается успешным.

	RESET mode finished with Success.

===================================================

Вместо заключения

Внедрение inplace upgrade значительно сократило время обновления Platform V Pangolin DB в сценарии с изменением данных системного каталога. Если мажорное обновление 100 ГБ базы занимает 65 минут, то обновление по новому сценарию выполняется за 23 минуты. К тому же он позволяет обновлять продукт проще и с меньшими рисками.

Собираемся развивать инструмент и адаптировать его для новых задач. Сейчас мы видим, что пользователи приходят с вопросами по содержанию логов инструмента — хочется сделать их более удобочитаемыми. И есть планы по небольшим доработкам скриптов обновления — о том, как здесь всё работает, писала моя коллега-DevOps в своей статье на Хабре. О развитии этого направления постараемся писать ещё статьи, как минимум будем рассказывать об этом в сообществе нашей команды (присоединяйтесь, будем рады!).

Если у вас есть опыт создания подобных инструментов и их автоматизации, буду рад почитать ваши комментарии! 

Теги:
Хабы:
+6
Комментарии0

Информация

Сайт
www.sber.ru
Дата регистрации
Дата основания
Численность
свыше 10 000 человек
Местоположение
Россия