
Привет, Хабр! Меня зовут Николай Литковец, я инженер-разработчик в СберТехе, развиваю СУБД 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. Он состоит из трёх основных частей:
cкрипта обновления
inplace_upgrade.sh
;SQL-скриптов обновления системного каталога;
утилиты обновления версии системного каталога.
Расскажу о них подробно.
Скрипт 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 в своей статье на Хабре. О развитии этого направления постараемся писать ещё статьи, как минимум будем рассказывать об этом в сообществе нашей команды (присоединяйтесь, будем рады!).
Если у вас есть опыт создания подобных инструментов и их автоматизации, буду рад почитать ваши комментарии!