Обновление системных каталогов Pangolin без изменения структуры данных#

Описание решения#

Для выполнения задачи обновления каталога используется инструмент inplace_upgrade.sh, который применяет заранее подготовленные разработчиками SQL-скрипты обновления системного каталога (правила написания приведены в разделе «Правила написания SQL-скриптов для обновления системных данных каталога»), а также утилиту update_catalog_version для изменения версии каталога в global/pg_control. Скрипт обновления и все что он использует находится в директории installer/utilities/pg_inplace_upgrade.

Внимание!

Скрипт inplace_upgrade.sh, прилагаемые SQL-скрипты обновления и утилита update_catalog_version являются необходимыми для корректной работы. Изменение/удаление любого из них приведет к неправильной работе утилиты.

Наличие скрипта недостаточно для проведения обновления – для работы скриптов обновления необходимы бинарные функции, доступные с версии Pangolin 6.4.0.

При обновлении каталога меняется содержимое системных таблиц pg_catalog (таких, как pg_class, pg_type и т.д.). Сами системные таблицы и индексы в данном типе обновления не затрагиваются. Объекты базы данных (функции, представления, типы) описаны в системном каталоге и хранятся в виде записей его таблиц. Добавлять или изменять можно только объекты по OID до 16383 включительно. Все объекты OID которых выше 16383 не должны меняться c помощью SQL-скриптов обновления, так как они относятся к пользовательским объектам, изменение которых не предусмотрено.

inplace_upgrade.sh использует функцию ядра block_user_data_modification для установки ограничений на следующий ряд SQL-операций на время ее работы:

  • DROP TYPE/FUNCTION/VIEW;

  • ALTER TYPE/FUNCTION/VIEW ... RENAME;

  • CREATE OR REPLACE FUNCTION/VIEW, кроме CREATE FUNCTION/VIEW.

Вышеперечисленные ограничения можно при необходимости снять, тем самым разрешив любые изменения системного и пользовательских каталогов, но это увеличит вероятность порчи пользовательских данных и системного каталога в случае наличия ошибок в SQL скриптах. Снятие ограничений производится флагом --drop-on.

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

Скрипт inplace_upgrade.sh#

Скрипт выполняет обновление системного каталога для всех баз данных СУБД. Также обновляется номер версии системного каталога в global/pg_control и имена папок пользовательских табличных пространств PG_<MAJOR_POSTGRESQL>_<CATALOG_VERSION_NO>.

При вызове скрипта inplace_upgrade.sh используются ключи:

  • Обязательные ключи:

    • -s | --utildir - директория со скриптом inplace_upgrade.sh, утилитой update_catalog_version и папкой sql_upgrade_6xx, содержащей SQL-скрипты для обновления pg_catalog. SQL-скрипты пишутся разработчиками в соответствии изменениями в pg_catalog, которые вносят их доработки. В случае стандартной установки данный параметр имеет значение installer/utilities/pg_inplace_upgrade;

    • -d | --pgdatadir - путь к директории с данными (обычно имеет такое же значение, как и $PGDATA);

    • -l | --logdir - директория для сохранения логов:

      • логи PostgreSQL, сгенерированные в процессе обновления, записываются в файл postgres_update.log;

      • полный лог работы скрипта обновления inplace_upgrade.sh записываются в файл inplace_upgrade.log;

      • короткий отчет обновления report.log;

    • -h | --host - хост СУБД для подключения pg_dump и psql;

    • -p | --port - порт СУБД для подключения pg_dump, pg_ctl и psql;

    • -u | --user - пользователь СУБД с правами суперпользователя для подключения pg_dump и psql;

    • -n | --old-version - текущая версия продукта (например 6.1.8 для СУБД Pangolin 6.1.8). Формат строки проверяется;

    • -N | --new-version - версия продукта на которую происходит обновление (например 6.4.0 для СУБД Pangolin 6.4.0). Формат строки проверяется;

    • -b | --dbname - имя базы данных для подключения pg_dump и psql (обычно имеет значение postgres);

    • -m | --dumpdir - директория для сохранения дампов (sql-дампы до, после и после отката обновления);

    • -B | --backupdir - директория для сохранения:

      • резервной копии файлов системного каталога;

      • файлов с перечнем таблиц и индексов системного каталога и информацией о соответствующих им файлах;

      • файл user_tbls.txt с директориями пользовательских табличных пространств;

      • файл version.txt с версией PostgreSQL до обновления;

    • -t | --pg_ctldir - директория с исполняемыми файлами утилит pg_ctl и postgres новой версии;

    • -T | --pg_utildir - директория с исполняемыми файлами утилит psql и pg_dump новой версии.

Необязательные ключи:

  • -P | --password - пароль для подключения к СУБД. Если не задан, то пароль берется из переменной окружения PASSWORD;

  • -r | --replica - ключ указывается при запуске утилиты обновления на реплике;

  • -D | --drop_on - флаг, разрешающий операции, запрещенные функцией block_user_data_modification;

  • -k | --test-skip - флаг, устанавливается для отключения запуска тестов системного каталога;

  • -a | --add-tables - флаг для выполнения резервного копирования таблиц pg_largeobject, pg_largeobject_metadata при необходимости;

  • -V | --version - версия утилиты;

  • -? | --help - справка.

Команды:

  • info - команда проверки актуальности обновления и формирования информационных файлов user_tbls.txt, version.txt для последующего запуска обновления;

  • update - команда запуска обновления;

  • reset - команда отката обновления. Откат возможен до первого запуска базы с доступом пользователей.

Требования для запуска#

Пользователь должен иметь права на запуск скрипта обновления inplace_upgrade.sh. Также этот пользователь должен иметь права суперпользователя на доступ к СУБД.

Режимы работы скрипта#

Существуют три режима работы скрипта inplace_upgrade.sh:

  • info - проверка возможности обновления;

  • update - обновление;

  • reset - откат обновления;

inplace_upgrade.sh в режиме info#

В режиме info скрипт осуществляет проверку возможности обновления (наличие утилиты update_catalog_version, папок с SQL-скриптами и всех необходимых прав доступа к ним) и необходимость обновления для новой версии СУБД. Также скрипт создает два файла user_tbls.txt и version.txt. Файл user_tbls.txt содержит список директорий пользовательских табличных пространств для последующего их обновления скриптом в режиме update. Файл version.txt используется для сохранения значения мажорной версии PostgreSQL (MAJOR_POSTGRESQL), которая является элементом пути в пользовательском табличном пространстве PG_<MAJOR_POSTGRESQL>_<CATALOG_VERSION_NO>.

Для кластерной конфигурации необходимо запускать скрипт в режиме info и на мастере и на реплике.

Запуск скрипта осуществляется при включенной СУБД.

Пример запуска скрипта:

./inplace_upgrade.sh -d <pgdata> -l <директория логов> -s <директория с утилитой> -B <директория резервной копии> -p <порт> -h <хост> -u <суперпользователь> -b <база данных для подключения по умолчанию> -n  <текущая версия продукта> -N <новая версия продукта> info --t <директория утилит postgres and pg_ctl> -T <директория утилит psql and pg_dump>
Ограничения#

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

Коды возврата#

Предусмотренные коды:

  • 0 - вызов утилиты требуется;

  • 1 - провал запуска утилиты, утилита не может быть запущена корректно;

  • 2 - вызов утилиты в режиме update не требуется.

inplace_upgrade.sh в режиме update#

В режиме update скрипт осуществляет обновление таблиц схемы pg_catalog, номера версии системного каталога в pg_control и табличных пространств пользователей.

Пример запуска скрипта:

./inplace_upgrade.sh -d <pgdata> -l <дирктория логов> -p <порт> -h <хост> -u <суперпользоватесь> -b <база данных для подключения по умолчанию> -s <директория с утилитой> -m <директория для sql-дампов> -B <директория бэкапа> -n  <текущая версия продукта> -N <новая версия продукта> update -t <директория утилит postgres and pg_ctl> -T <директория утилит psql and pg_dump>

Примечание:

Процесс восстановления СУБД после неудачного окончания работы скрипта в режиме update описан в разделе «Ручное обновление системных каталогов СУБД Pangolin».

Ограничения#

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

Пример отсутствия функция в ядре (при ее добавлении может быть ошибка в транзакции):

"ERROR: Fail script: ERROR: there is no built-in function named \"<name_function>\"", "CONTEXT: SQL statement \"CREATE FUNCTION pg_catalog.name_function()"
Коды возврата#

Предусмотренные коды:

  • 0 - успех;

  • 1 - провал запуска утилиты, требуется ручное восстановление СУБД;

  • 4 - требуется восстановление файлов из резервной копии системного каталога, также необходим откат исполняемых файлов СУБД к исходной версии;

  • 5 - изменения не применились, необходим откат исполняемых файлов СУБД к исходной версии.

inplace_upgrade.sh в режиме reset#

В режиме reset скрипт осуществляет восстановление pg_catalog и номера каталога СУБД.

Пример запуска скрипта:

./inplace_upgrade.sh -d <pgdata> -l <дирктория логов> -p <порт> -h <хост> -u <суперпользоватесь> -b <база данных для подключения по умолчанию> -s <директория с утилитой> -m <директория для sql-дампов> -B <директория бэкапа> reset -t <директория утилит postgres and pg_ctl> -T <директория утилит psql and pg_dump>

Примечание:

Процесс восстановления СУБД после неудачного окончания работы скрипта в режиме reset описан в разделе «Ручное обновление системных каталогов СУБД Pangolin».

Ограничения#

Должен быть доступ к папке, указанной в --backupdir и доступ на чтение к файлам, внутри этой папки.

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

Коды возврата#
  • 0 - успех;

  • 1 - провал запуска утилиты, требуется ручное восстановление СУБД.

Утилита update_catalog_version#

Пользователь должен иметь права на исполнение утилиты update_catalog_version, запускающим обновление.

Утилита update_catalog_version производит сравнение версии текущего каталога, считанной из global/pg_control (расположение файла по умолчанию $PGDATA/global/pg_control), с версией на которую планируется обновление. Также проверяется наличие файла резервной копии pg_control.bak в директории указанной в --backup, если файл есть (возможно происходит повторный запуск), то утилита заканчивает свою работу, пишет сообщение с описанием ошибки и возвращает код ошибки 1. В случае совпадения проверяется отличие номера текущей версии от версии на которую необходимо производить обновление, если они совпали, то обновление версии не происходит и утилита заканчивает свою работу, возвращается код 2. Если новая версия больше текущей версии, то делается резервная копия pg_control.bak (файл будет располагаться в --backup) и происходит обновление версии каталога в файле pg_control. В случае успешного обновления утилита заканчивает свою работу и возвращает код 0. Если произошла ошибка при обновлении версии, то происходит восстановление pg_control и завершение работы утилиты с кодом 1. Если восстановить старый pg_control из резервной копии не удалось, то утилита возвращает код 3. Если новая версия меньше текущей версии каталога, то обновление не производится, пишется сообщение об ошибке и возвращается код 1. Если необходимо понизить версию, то нужно использовать ключ --force (-f), с этим ключом не производится проверка повышения версии каталога, также не производится проверка наличия файла резервной копии и он перезаписывается. Если не сделать обновление версии каталога, то бинарные файлы СУБД не смогут запуститься.

Ключи утилиты update_catalog_version:

  • -D, --pgdatadir - директория с СУБД (PGDATA);

  • -b, --backupdir - директория для сохранения резервной копии файла pg_control;

  • -C, --catalog-version-new - новая версия системного каталога (на которую происходит обновление) (CATALOG_VERSION_NO);

  • -c, --catalog-version-old - старая версия системного каталога (с которой происходит обновление) (CATALOG_VERSION_NO);

  • -f, --force - флаг принудительной смены версии;

  • -y, --dry-run - флаг проверки соответствия версии текущего каталога обновлению, без его изменения;

  • -V, --version - флаг печати версии утилиты;

  • -?, --help - флаг печати справки об утилите.

Режимы работы утилиты update_catalog_version#
Работа утилиты без –force#

Утилита запускается с ключами: update_catalog_version catalog_version_no_old -C catalog_version_no_new -b <dir_backup> -D <PGDATA>.

Ход работы:

  1. Проверяется что заданы все основные параметры (-D, -c, -C, -b), если хотя бы один не задан, то пишется сообщение в stdout и возвращается код ошибки 1.

  2. Проверяется что PostgreSQL не запущен. Если запущен, то выдается сообщение об ошибке и возвращается код возврата 1.

  3. Проверяется что версия каталога не понижается, если версия понижается, то выдается сообщение об ошибке и возвращается код возврата 1.

  4. Проверяется наличие файла резервной копии pg_control.bak, если он есть, то выдается сообщение об ошибке и возвращается код возврата 1. Это нужно для исключения повторного ошибочного обновления.

  5. Проверяется соответствие версии текущего каталога, версии переданной с ключом -c, если версии разные, то выдается сообщение об ошибке и возвращается код возврата 1.

  6. Проверяется соответствие версии текущего каталога, версии переданной с ключом , если версии одинаковые, то выдается сообщение соответствия версий и возвращается код 2.

  7. Формируется файл резервной копии pg_control.bak. Если файл не сформировался, то выдается сообщение об ошибке и возвращается код возврата 1.

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

Работа утилиты с –force#

Утилита запускается сключами: update_catalog_version catalog_version_no_old -C catalog_version_no_new -b <dir_backup> -D <PGDATA> -f.

Ход работы:

  1. Проверяется что заданы все основные параметры (-D, -c, -C, -b), если хотя бы один не задан, то пишется сообщение в stdout и возвращается код ошибки 1.

  2. Проверяется что PostgreSQL не запущен. Если запущен, то выдается сообщение об ошибке и возвращается код возврата 1.

  3. Проверяется соответствие версии текущего каталога, версии переданной с ключом -c, если версии разные, то выдается сообщение об ошибке и возвращается код возврата 1.

  4. Проверяется соответствие версии текущего каталога, версии переданной с ключом , если версии одинаковые, то выдается сообщение соответствия версий и возвращается код 2.

  5. Формируется файл бэкапа pg_control.bak. Если файл не сформировался, то выдается сообщение об ошибке и возвращается код возврата 1.

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

Работа утилиты с –dry-run#

Утилита запускается с ключами: update_catalog_version catalog_version_no_old -C catalog_version_no_new -b <dir_backup> -D <PGDATA> -y.

Ход работы:

  1. Проверяется что заданы все основные параметры (-D, -c, -C, -b), если хотя бы один не задан, то пишется сообщение в stdout и возвращается код ошибки 1.

  2. Проверяется что версия каталога не понижается. Если версия понижается, то выдается сообщение об ошибке и возвращается код возврата 1.

  3. Проверяется наличие файла резервной копии pg_control.bak. Если он есть, то выдается сообщение об ошибке и возвращается код возврата 1. Это нужно для исключения повторного ошибочного обновления.

  4. Проверяется соответствие версии текущего каталога, версии переданной с ключом -c. Если версии разные, то выдается сообщение об ошибке и возвращается код возврата 1.

  5. Проверяется соответствие версии текущего каталога версии переданной с ключом . Если версии одинаковые, то выдается сообщение соответствия версий и возвращается код 2, если версии разные то выдается сообщение о возможности обновления и возвращается код 0.

Ограничения#

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

Коды возврата утилиты update_catalog_version#

Предусмотренные коды:

  • 0 - успешное завершения обновления версии каталога (в режиме проверки --dry-run данный код означает, что обновление возможно);

  • 1 - ошибка обновления версии каталога, файл pg_control не поменялся;

  • 2 - обновление каталога не требуется (в режиме проверки --dry-run данный код означает, что обновление не требуется);

  • 3 - ошибка обновления версии каталога, файл pg_control поменялся, требуется ручное восстановление из файла резервной копии pg_control.bak.

Ручное обновление исполняемых файлов СУБД Pangolin (с использованием утилиты inplace_upgrade.sh)#

Перед началом обновления необходимо знать особенности, в связи с изменением формата WAL-файлов:

  1. Корректный откат к исходной версии Pangolin (6.1.0/6.1.2/6.1.4) при отсутствии резервной копии осуществить не получится, поэтому необходимо это учесть при попытке обновиться.

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

Перед началом выполнения инструкции необходимо убедиться, что yum/dnf-репозитории настроены корректно.

Внимание!

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

Обновление СУБД осуществляется от пользователя с правами sudo, пользователя postgres и пользователя kmadmin_pg.

Поскольку инструкция является универсальной для standalone и cluster-архитектур, каждый пункт необходимо выполнить на всех узлах кластера БД. На узле arbiter производить обновление компонентов только по необходимости.

Обозначения

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

  • PANGOLIN_VER – новая версия СУБД Pangolin (формат - х.х.х);

  • PANGOLIN_BACKUP_TOOLS – новая версия компонента pangolin-backup-tools (формат - х.х.х);

  • PANGOLIN_POOLER – новая версия компонента pangolin-pooler (формат - х.х.х);

  • PANGOLIN_MANAGER – новая версия компонента pangolin-manager (формат - х.х.х);

  • PANGOLIN_TIMESCALEDB – новая версия компонента pangolin-timescaledb (формат - х.х.х);

  • PANGOLIN_TIMESCALEDB_OLD – исходная версия компонента pangolin-timescaledb (формат - х.х.х);

  • PANGOLIN_PGHOME_VER – новая версия в пути к бинарным файлам СУБД Pangolin (формат - х.х);

  • PANGOLIN_PGHOME_OLD_VER – исходная версия в пути к бинарным файлам СУБД Pangolin (формат - х.х.х/х.х);

  • PANGOLIN_OLD_VER – исходная версия СУБД Pangolin (формат - х.х.х);

  • PANGOLIN_FULL_VER – новая версия СУБД Pangolin (формат - 0х.00х.0х);

  • PANGOLIN_FULL_OLD_VER – исходная версия СУБД Pangolin (формат - 0х.00х.0х).

Шаг 1. Подготовка#

  1. Скачайте дистрибутив в рабочий каталог и распакуйте его. Далее по инструкции путь к компонентам дистрибутива будет формироваться по ~/pangolin:

    mkdir -p ~/pangolin
    tar -xzvf pangolin_6.tar.gz  -C ~/pangolin
    
  2. Перед началом обновления убедитесь, что данный сценарий подходит для текущего стенда:

    sudo mkdir -p /home/postgres/pg_inplace_upgrade/{util,backup,log,dump}
    sudo cp -r ~/pangolin/installer/utilities/pg_inplace_upgrade/* /home/postgres/pg_inplace_upgrade/util
    sudo chmod 700 -R /home/postgres/pg_inplace_upgrade
    sudo chown postgres:postgres -R /home/postgres/pg_inplace_upgrade
    
    sudo su - postgres
    cd /home/postgres/pg_inplace_upgrade/util
    ./inplace_upgrade.sh info -n 6.3.0 -N 6.4.0 -s /home/postgres/pg_inplace_upgrade/util -B /home/postgres/pg_inplace_upgrade/backup -d /pgdata/06/data -l /home/postgres/pg_inplace_upgrade/log -p 5433 -h 127.0.0.1 -u postgres -b postgres -m /home/postgres/pg_inplace_upgrade/dump -t /usr/pangolin/bin -T /usr/pangolin-dbms-client/bin
    

    В случае, если необходимо произвести обновление системных данных каталога, будет выведено сообщение:

    INFO: Location of update_catalog_version utility: /opt/pangolin_cache/pg_inplace_upgrade/update_catalog_version
    INFO: The log-file containing postgresql logs produced during catalog update: /pgarclogs/pg_inplace_upgrade/log/postgres_updade.log
    INFO: The summarized catalog update report: /pgarclogs/pg_inplace_upgrade/log/report.log
    INFO: ======= START INPLACE_UPGRADE IN INFO MODE =======
    INFO: ----------- Initial update analysis -----------
    INFO: CATALOG_VERSION_NO_OLD: 202310091
    INFO: Following directories will be searched to find sql-scripts applicable in this run:
    INFO: /opt/pangolin_cache/pg_inplace_upgrade/update_catalog_version/sql_upgrade_6xx/6.4.0/
    INFO: Version: 6.4.0 CATALOG_VERSION_NO_NEW: 202409231
    INFO: Initial update analysis........................... OK
    INFO: ----------- Update CATALOG_VERSION_NO -----------
    INFO: update_catalog_version: The new catalog version is the same as the current one.
    INFO: Update CATALOG_VERSION_NO......................... OK
    INFO: ----------- Read all catalog update SQL-scripts -----------
    INFO: Read all catalog update SQL-scripts............... OK
    INFO: ----------- Extract info about users tablespaces -----------
    INFO: paths: /opt/pangolin_cache/pg_inplace_upgrade/tmp_check/test_db
    INFO: version: PostgreSQL 15.5 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Platform V SberLinux 8.5.0-18), 64-bit
    INFO: Extract info about users tablespaces.............. OK
    INFO:
       INFO mode finished with Success. Update required.
    ===================================================
    

    Если нет необходимости в обновлении системных данных каталога, будет выведено сообщение:

    INFO: Location of update_catalog_version utility: /opt/pangolin_cache/pg_inplace_upgrade/update_catalog_version
    INFO: The log-file containing postgresql logs produced during catalog update: /pgarclogs/pg_inplace_upgrade/log/postgres_updade.log
    INFO: The summarized catalog update report: /pgarclogs/pg_inplace_upgrade/log/report.log
    INFO: ======= START INPLACE_UPGRADE IN INFO MODE =======
    INFO: ----------- Initial update analysis -----------
    INFO: CATALOG_VERSION_NO_OLD: 202409231
    INFO: Following directories will be searched to find sql-scripts applicable in this run:
    INFO: /opt/pangolin_cache/pg_inplace_upgrade/sql_upgrade_6xx/6.4.0/
    INFO: Version: 6.4.0 CATALOG_VERSION_NO_NEW: 202409231
    INFO: Initial update analysis........................... OK
    INFO:
       INFO mode finished with Success. Update not required.
    ===================================================
    

    Если в процессе работы утилиты что то пошло не так, будет выведено сообщение:

    INFO: Location of update_catalog_version utility: /opt/pangolin_cache/pg_inplace_upgrade/update_catalog_version
    INFO: The log-file containing postgresql logs produced during catalog update: /pgarclogs/pg_inplace_upgrade/log/postgres_updade.log
    INFO: The summarized catalog update report: /pgarclogs/pg_inplace_upgrade/log/report.log
    INFO: ======= START INPLACE_UPGRADE IN INFO MODE =======
    INFO: ----------- Initial update analysis -----------
    INFO: CATALOG_VERSION_NO_OLD: 202310091
    INFO: Following directories will be searched to find sql-scripts applicable in this run:
    INFO: /opt/pangolin_cache/pg_inplace_upgrade/sql_upgrade_6xx/6.2.0/
    INFO: Version: 6.2.0 CATALOG_VERSION_NO_NEW: 202310091
    INFO: /opt/pangolin_cache/pg_inplace_upgrade/sql_upgrade_6xx/6.3.0/
    INFO: Version: 6.3.0 CATALOG_VERSION_NO_NEW: 202310091
    INFO: /opt/pangolin_cache/pg_inplace_upgrade/sql_upgrade_6xx/6.4.0/
    INFO: Version: 6.4.0 CATALOG_VERSION_NO_NEW: 202409231
    ERROR: File /opt/pangolin_cache/pg_inplace_upgrade/sql_upgrade_6xx/6.4.1/CATALOG_VERSION was not found
    INFO: Initial update analysis........................... FAIL
    INFO:
       INFO mode finished with Error.
    ===================================================
    
  3. Создайте временный физический слот репликации на master:

    sudo -iu postgres  
    SELECT * FROM pg_create_physical_replication_slot('tmp_update_slot', 'TRUE');
    exit
    

Шаг 2. Остановка компонентов СУБД Pangolin#

  1. В случае конфигурации с Pangolin Manager введите компонент в режим паузы:

    sudo -iu postgres
    patronictl -c /etc/patroni/postgres.yml edit-config --set 'pause=true' --force
    exit
    

    или

    sudo -iu postgres
    pangolin-manager-ctl -c /etc/pangolin-manager/postgres.yml edit-config --set 'pause=true' --force
    exit
    
  2. Остановите все компоненты СУБД Pangolin. В случае кластерной конфигурации действия по остановке произведите сначала на реплике, затем на основном узле:

    # Для конфигурации без pangolin-manager
    sudo systemctl stop postgresql
    
    # Для конфигурации с pangolin-manager
    sudo -iu postgres
    pg_ctl stop
    exit
    sudo systemctl stop patroni
    sudo systemctl stop pangolin-manager
    
    # Для конфигурации с etcd
    sudo systemctl stop etcd
    
    # Для любой конфигурации
    sudo systemctl stop pangolin-pooler
    sudo systemctl stop pangolin_reencrypt@postgres.service
    sudo systemctl stop pangolin_reencrypt@kmadmin_pg.service
    sudo systemctl stop pg_certs_rotate_agent.service
    sudo systemctl stop pangolin-certs-rotate
    sudo systemctl stop pangolin-auth-reencrypt@postgres
    sudo systemctl stop pangolin-auth-reencrypt@kmadmin_pg
    

    С включенной функциональностью «Отказ от root»:

    # Для конфигурации с etcd
    sudo systemctl stop etcd
    
    sudo -iu postgres
    
    # Для конфигурации с pangolin-manager
    pg_ctl stop
    systemctl --user stop pangolin-manager
    
    # Для конфигурации без pangolin-manager
    systemctl --user stop postgresql
    
    # Для любой конфигурации
    systemctl --user stop pangolin-pooler
    systemctl --user stop pangolin-certs-rotate
    systemctl --user stop pangolin-auth-reencrypt
    exit
    sudo -iu kmadmin_pg
    export XDG_RUNTIME_DIR=/run/user/$(id -u)
    export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"
    systemctl --user stop pangolin-auth-reencrypt
    exit
    
  3. Проверьте, что все компоненты корректно остановлены:

    sudo ps aux | grep -E "pangolin-pooler|pangolin-manager|postgresql|pangolin-certs-rotate|pg_certs_rotate_agent|pangolin-auth-reencrypt@postgres|pangolin_reencrypt@postgres.service|pangolin-auth-reencrypt@kmadmin_pg|pangolin_reencrypt@kmadmin_pg.service|etcd" | grep -v grep
    

    Если команда на шаге 3 вернула результат, то выполните следующее:

    sudo kill -9 <pid>
    
    sudo ps aux | grep -E "pangolin-pooler|pangolin-manager|postgresql|pangolin-certs-rotate|pg_certs_rotate_agent|pangolin-auth-reencrypt@postgres|pangolin_reencrypt@postgres.service|pangolin-auth-reencrypt@kmadmin_pg|pangolin_reencrypt@kmadmin_pg.service|etcd" | grep -v grep
    

Шаг 3. Обновление компонента pangolin-auth-reencrypt#

Произведите обновление пакета компонента:

export PANGOLIN_VER=6.3.0
sudo dnf install -y ~/pangolin/utilities/pangolin-auth-reencrypt-$PANGOLIN_VER-sberlinux8.8.x86_64.rpm

Для конфигурации с DCS произведите дополнительно обновление на узле arbiter.

Шаг 4. Обновление компонента pangolin-certs-rotate#

Произведите обновление пакета компонента:

export PANGOLIN_VER=6.3.0
sudo dnf install -y ~/pangolin/utilities/pangolin-certs-rotate-$PANGOLIN_VER-sberlinux8.8.x86_64.rpm

Для конфигурации с DCS произведите дополнительно обновление на узле arbiter.

Шаг 5. Обновление компонента pangolin-security-utilities#

Произведите обновление пакета компонента:

export PANGOLIN_VER=6.3.0
sudo dnf install -y ~/pangolin/utilities/pangolin-security-utilities-$PANGOLIN_VER-sberlinux8.8.x86_64.rpm

Для конфигурации с DCS произведите дополнительно обновление на узле arbiter.

Шаг 6. Обновление компонента pangolin-diagnostic-tools#

Произведите обновление пакета компонента:

export PANGOLIN_VER=6.3.0
sudo dnf install -y ~/pangolin/utilities/pangolin-diagnostic-tool-$PANGOLIN_VER-sberlinux8.8.x86_64.rpm

Шаг 7. Обновление компонента pangolin-backup-tools#

  1. Произведите обновление пакета компонента:

    export PANGOLIN_BACKUP_TOOLS=1.2.1
    sudo dnf install -y ~/pangolin/pangolin-backup-tools-$PANGOLIN_BACKUP_TOOLS-sberlinux8.8.x86_64.rpm
    
  2. Актуализируйте конфигурационный файл backup-tools-env согласно шаблону ниже, если установка компонента первичная:

    # PATH, used for access to required executable files, default value: "${PATH}:{PGHOME}/bin/"
    PATH="${PATH}:/usr/pangolin-6.3/bin/"
    # path to PGHOME, default value: "/opt/pangolin-backup-tools/bin"
    PGHOME="/opt/pangolin-backup-tools"
    # path to python libraries, required for manage_backup.bin, default value: "/opt/pangolin-backup-tools/lib/python3/site-packages"
    PYTHONPATH="/opt/pangolin-backup-tools/lib/python3/site-packages"
    # path to libraries, required for executable files, default value: "/opt/pangolin-backup-tools/lib"
    LD_LIBRARY_PATH="/opt/pangolin-backup-tools/lib"
    # path to plugins libraries, default value: "/opt/pangolin-backup-tools/lib"
    PG_PLUGINS_PATH="/opt/pangolin-backup-tools/lib"
    
    # Pangolin DBMS server IP, default value: "127.0.0.1"
    ARG_KEY_DBMS_SERVER_IP="127.0.0.1"
    # Pangolin DBMS port, default value: "5433"
    ARG_KEY_DBMS_SERVER_PORT="5433"
    # user used for access to database, default value: "backup_user"
    ARG_KEY_DBMS_CONNECT_USER="backup_user"
    # database to connect, default value: "postgres"
    ARG_KEY_DBMS_CONNECT_DATA_BASE="postgres"
    # path to backup storage, default value: "/pgarclogs"
    ARG_KEY_DBMS_CONNECT_BACKUP_DIR="/pgarclogs/06"
    # password to connect to Pangolin DBMS, default value: 'sample_password'
    # cluster name, default value: "clustername"
    PGINSTANCE="clustername"
    # WAL archives list
    WALSTATE_FILE="$ARG_KEY_DBMS_CONNECT_BACKUP_DIR/wals_to_delete"
    # Log file
    LOG_FILE="$ARG_KEY_DBMS_CONNECT_BACKUP_DIR/archive.log"
    # path to script, used for creating backup files, default value: "/opt/pangolin-backup-tools/bin/manage_backup.sh"
    MANAGE_BACKUP_SCRIPT="/opt/pangolin-backup-tools/bin/manage_backup.sh"
    
    # setting up of connection string
    PANGOLIN_BACKUP_TOOLS_ARGS="$PANGOLIN_BACKUP_TOOLS_ARGS --host $ARG_KEY_DBMS_SERVER_IP"
    PANGOLIN_BACKUP_TOOLS_ARGS="$PANGOLIN_BACKUP_TOOLS_ARGS -p $ARG_KEY_DBMS_SERVER_PORT"
    PANGOLIN_BACKUP_TOOLS_ARGS="$PANGOLIN_BACKUP_TOOLS_ARGS -U $ARG_KEY_DBMS_CONNECT_USER"
    PANGOLIN_BACKUP_TOOLS_ARGS="$PANGOLIN_BACKUP_TOOLS_ARGS -d $ARG_KEY_DBMS_CONNECT_DATA_BASE"
    PANGOLIN_BACKUP_TOOLS_ARGS="$PANGOLIN_BACKUP_TOOLS_ARGS -B $ARG_KEY_DBMS_CONNECT_BACKUP_DIR"
    
    # environment variables to launch manage backup
    export PATH
    export PGHOME
    export PYTHONPATH
    export LD_LIBRARY_PATH
    export PG_PLUGINS_PATH
    
    # опционально
    sudo rm -rf /opt/omni/lbin/*manage_backup*
    sudo rm -rf /opt/omni/lbin/*pg_se_archlogs*
    

Шаг 8. Обновление компонента Pangolin Pooler#

Произведите обновление пакета компонента:

export PANGOLIN_POOLER=1.3.1
sudo dnf install -y ~/pangolin/pangolin-pooler-$PANGOLIN_POOLER-sberlinux8.8.x86_64.rpm

Шаг 9. Обновление компонента Pangolin Manager#

  1. Произведите обновление пакета компонента:

    # опционально
    sudo rm -rf /usr/patroni
    
    
    export PANGOLIN_PGHOME_VER=6.3
    export PANGOLIN_PGHOME_OLD_VER=6.2.0
    export PANGOLIN_MANAGER=2.1.1
    sudo dnf install -y ~/pangolin/pangolin-manager-$PANGOLIN_MANAGER-sberlinux8.8.x86_64.rpm
    sudo sed -i "s/$PANGOLIN_PGHOME_OLD_VER/$PANGOLIN_PGHOME_VER/g" /etc/pangolin-manager/postgres.yml
    
    # Добавить в файл /etc/pangolin-manager/postgres.yml параметр в секцию postgresql, если его нет
    bin_dir_client: /usr/pangolin-dbms-client-$PANGOLIN_PGHOME_VER/bin
    

    Для конфигурации с DCS произведите дополнительно обновление на узле arbiter.

  2. Для конфигурации с DCS выполните данный шаг только на узле arbiter:

    sudo chmod -R 0440 /opt/pangolin-manager/lib/plugins/ /opt/pangolin-manager/lib/libfe_elog.so
    sudo chmod 0770 /opt/pangolin-manager /opt/pangolin-manager/bin /opt/pangolin-manager/lib /opt/pangolin-manager/lib/plugins
    sudo chown postgres:pangolin_users /opt/pangolin-manager /opt/pangolin-manager/bin /opt/pangolin-manager/lib /opt/pangolin-manager/lib/plugins /opt/pangolin-manager/lib/libfe_elog.so
    

Шаг 10. Обновление компонента pangolin-dbms#

Произведите обновление пакета компонента:

# опционально
export PANGOLIN_OLD_VER=6.3.0
sudo dnf remove -y pangolin-dbms-6.3-$PANGOLIN_OLD_VER
export PANGOLIN_VER=6.3.0
sudo dnf install -y ~/pangolin/pangolin-dbms-6.3-$PANGOLIN_VER-sberlinux8.8.x86_64.rpm
sudo rm -rf /usr/pangolin-6.1* /usr/pangolin-6.2* /usr/pgsql-se-06

# Для конфигурации без pangolin-manager
export PANGOLIN_PGHOME_VER=6.3
export PANGOLIN_OLD_VER=6.2.0
sudo sed -i "s/$PANGOLIN_OLD_VER/$PANGOLIN_VER/g" /pgdata/06/data/postgresql.conf
sudo sed -i "s/$PANGOLIN_OLD_VER/$PANGOLIN_VER/g" /etc/systemd/system/postgresql.service

Шаг 11. Обновление компонента pangolin-dbms-client#

Произведите обновление пакета компонента:

# опционально
export PANGOLIN_OLD_VER=6.3.0
sudo dnf remove -y pangolin-dbms-6.3-client-$PANGOLIN_OLD_VER
export PANGOLIN_VER=6.3.0
sudo dnf install -y ~/pangolin/pangolin-dbms-6.3-client-$PANGOLIN_VER-sberlinux8.8.x86_64.rpm

Шаг 12. Обновление компонента pangolin-timescaledb#

Произведите обновление пакета компонента:

# опционально
export PANGOLIN_TIMESCALEDB_OLD=2.14.2
sudo dnf remove -y pangolin-timescaledb-6.3-apache-$PANGOLIN_TIMESCALEDB_OLD
export PANGOLIN_TIMESCALEDB=2.14.2
sudo dnf install -y ~/pangolin/timescaledb/pangolin-timescaledb-6.3-apache-$PANGOLIN_TIMESCALEDB-sberlinux8.8-x86_64.rpm

Шаг 13. Дополнительные действия#

  1. Скопируйте 3rd-party компоненты:

    sudo cp -r ~/pangolin/3rdparty/ /usr/pangolin/
    sudo tar -xzvf /usr/pangolin/3rdparty/3rdparty.tar.gz -C /usr/pangolin/3rdparty/
    sudo chown -R postgres:postgres /usr/pangolin/3rdparty
    sudo chmod -R 0700 /usr/pangolin/3rdparty
    
  2. Актуализируйте .bash_profile и dynmotd.sh:

    export PANGOLIN_MANAGER=2.1.1
    export PANGOLIN_OLD_MANAGER=1.1.1  
    export PANGOLIN_FULL_VER=06.003.00
    export PANGOLIN_FULL_OLD_VER=06.002.00
    export PANGOLIN_PGHOME_VER=6.3
    export PANGOLIN_PGHOME_OLD_VER=6.2.0
    
    sudo sed -i "s/$PANGOLIN_PGHOME_OLD_VER/$PANGOLIN_PGHOME_VER/g" /home/postgres/.bash_profile
    sudo sed -i "s/$PANGOLIN_PGHOME_OLD_VER/$PANGOLIN_PGHOME_VER/g" /home/kmadmin_pg/.bash_profile
    sudo sed -i "s/$PANGOLIN_PGHOME_OLD_VER/$PANGOLIN_PGHOME_VER/g" /home/postgres/.bashrc
    sudo sed -i "s/$PANGOLIN_PGHOME_OLD_VER/$PANGOLIN_PGHOME_VER/g" /home/kmadmin_pg/.bashrc
    sudo sed -i "s/$PANGOLIN_OLD_MANGER/$PANGOLIN_MANAGER/g"        /usr/local/sbin/dynmotd.sh
    sudo sed -i "s/$PANGOLIN_FULL_OLD_VER/$PANGOLIN_FULL_VER/g"     /usr/local/sbin/dynmotd.sh
    

    Выполните данный шаг дополнительно на узле arbiter.

Шаг 14. Запуск утилиты обновления системных данных каталога СУБД Pangolin#

Внимание!

Выполните данный шаг, если утилита inplace_upgrade.sh вернула сообщение на Шаге 1: «INFO mode finished with Success. Update required».

  1. Добавьте в конец конфигурационного файла postgresql.conf временные значения для мастера и реплики:

    sudo su - postgres
    echo "synchronous_commit = 'off' #tmp_line" >> /pgdata/data/data/postgresql.conf
    echo "autovacuum = 'off' #tmp_line" >> /pgdata/data/data/postgresql.conf
    echo "cron.database_name = 'template1' #tmp_line" >> /pgdata/data/data/postgresql.conf
    exit
    
  2. Произведите запуск обновления системных данных на мастере:

    sudo su - postgres
    cd /home/postgres/pg_inplace_upgrade/util
    ./inplace_upgrade.sh update -n 6.3.0 -N 6.4.0 -s /home/postgres/pg_inplace_upgrade/util -B /home/postgres/pg_inplace_upgrade/backup -d /pgdata/06/data -l /home/postgres/pg_inplace_upgrade/log -p 5433 -h 127.0.0.1 -u postgres -b postgres -m /home/postgres/pg_inplace_upgrade/dump -t /usr/pangolin/bin -T /usr/pangolin-dbms-client/bin
    exit
    

    Ожидаемый успешный результат:

    ...
    INFO: Update Complete!
    INFO: ----------- Finish upgrade -----------
    INFO: Finish upgrade.................................... OK
    INFO: 
       UPDATE mode finished with Success.
    ===================================================
    

    Внимание!

    В случае, если на мастере обновление прошло неуспешно, произведите восстановление по инструкции «Восстановление после неудачного обновления исполняемых файлов».

    Все дальнейшие шаги данной инструкции необходимо пропустить.

  3. Произведите запуск обновления системных данных на реплике, если кластерная конфигурация и обновления на матер-узле прошло успешно.

    sudo su - postgres
    cd /home/postgres/pg_inplace_upgrade/util
    ./inplace_upgrade.sh update -n 6.3.0 -N 6.4.0 -s /home/postgres/pg_inplace_upgrade/util -B /home/postgres/pg_inplace_upgrade/backup -d /pgdata/06/data -l /home/postgres/pg_inplace_upgrade/log -p 5433 -h 127.0.0.1 -u postgres -b postgres -m /home/postgres/pg_inplace_upgrade/dump -t /usr/pangolin/bin -T /usr/pangolin-dbms-client/bin -r
    

    Ожидаемый результат:

    INFO: Location of update_catalog_version utility: /opt/pangolin_cache/pg_inplace_upgrade/update_catalog_version
    INFO: The log-file containing postgresql logs produced during catalog update: /pgarclogs/pg_inplace_upgrade/log/postgres_updade.log
    INFO: The summarized catalog update report: /pgarclogs/pg_inplace_upgrade/log/report.log
    INFO: ======= START INPLACE_UPGRADE IN UPDATE MODE =======
    INFO: ----------- Initial update analysis -----------
    INFO: CATALOG_VERSION_NO_OLD: 202310091
    INFO: Following directories will be searched to find sql-scripts applicable in this run:
    INFO: /opt/pangolin_cache/pg_inplace_upgrade/tmp_check/upgrade9/sql_upgrade_6xx/6.4.0/
    INFO: Version: 6.4.0 CATALOG_VERSION_NO_NEW: 202409231
    INFO: Initial update analysis........................... OK
    INFO: ----------- Update CATALOG_VERSION_NO -----------
    INFO: update_catalog_version: Catalog version has been successfully updated to 202409231.
    INFO: Update CATALOG_VERSION_NO......................... OK
    INFO: ----------- Read all catalog update SQL-scripts -----------
    INFO: Read all catalog update SQL-scripts............... OK
    INFO: ----------- Update user tablespaces -----------
    INFO: renamed '/tmp/WDfqY_1Ing/PG_15_202310091' -> '/tmp/WDfqY_1Ing/PG_15_202409231'
    INFO: Rename directories of user tablespaces
    INFO: Update user tablespaces........................... OK
    INFO: Replica is updated
    INFO: 
       UPDATE mode finished with Success.
    ===================================================
    

    Внимание!

    В случае, если на мастере обновление прошло неуспешно, произведите восстановление по инструкции «Восстановление после неудачного обновления исполняемых файлов».

    Все дальнейшие шаги данной инструкции необходимо пропустить.

Шаг 15. Запуск компонентов СУБД Pangolin#

  1. Удалите временные переменные из postgresql.conf на мастере и реплике:

    vim
    synchronous_commit = 'off' #tmp_line
    autovacuum = 'off' #tmp_line
    cron.database_name = 'template1' #tmp_line
    
  2. Запустите компоненты Pangolin на мастере:

    Без функциональности «Отказ от root»:

    sudo systemctl daemon-reload
    sudo systemctl restart user@$(id -u postgres)
    sudo systemctl restart user@$(id -u kmadmin_pg)
    
    # Для конфигурации без pangolin-manager
    sudo systemctl restart postgresql
    
    # Для конфигурации с pangolin-manager
    sudo systemctl restart pangolin-manager
    
    # Для конфигурации с etcd
    sudo systemctl restart etcd
    
    # Для любой конфигурации
    sudo systemctl restart pangolin-pooler
    sudo systemctl restart pangolin-certs-rotate
    sudo systemctl restart pangolin-auth-reencrypt@postgres
    sudo systemctl restart pangolin-auth-reencrypt@kmadmin_pg
    

    С функциональностью «Отказ от root»:

    sudo systemctl restart user@$(id -u postgres)
    sudo systemctl restart user@$(id -u kmadmin_pg)
    
    # Для конфигурации с etcd
    sudo systemctl restart etcd
    
    sudo -iu postgres
    systemctl --user daemon-reload
    # Для конфигурации без pangolin-manager
    systemctl --user restart postgresql
    
    # Для конфигурации с pangolin-manager
    systemctl --user restart pangolin-manager
    
    # Для любой конфигурации
    systemctl --user restart pangolin-pooler
    systemctl --user restart pangolin-certs-rotate
    systemctl --user restart pangolin-auth-reencrypt
    exit
    sudo -iu kmadmin_pg
    systemctl --user daemon-reload  
    export XDG_RUNTIME_DIR=/run/user/$(id -u)
    export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"
    systemctl --user restart pangolin-auth-reencrypt
    exit
    
  3. Произведите проверку состояния служб на мастере:

    Без функциональности «Отказ от root»:

    # Для конфигурации без pangolin-manager
    sudo systemctl status postgresql
    
    # Для конфигурации с pangolin-manager
    sudo systemctl status pangolin-manager
    
    # Для конфигурации с etcd
    sudo systemctl status etcd
    
    # Для любой конфигурации
    sudo systemctl status pangolin-pooler
    sudo systemctl status pangolin-certs-rotate
    sudo systemctl status pangolin-auth-reencrypt@postgres
    sudo systemctl status pangolin-auth-reencrypt@kmadmin_pg
    

    С функциональностью «Отказ от root»:

    # Для конфигурации с etcd
    sudo systemctl status etcd
    
    sudo -iu postgres
    # Для конфигурации без pangolin-manager
    systemctl --user status postgresql
    
    # Для конфигурации с pangolin-manager
    systemctl --user status pangolin-manager
    
    # Для любой конфигурации
    systemctl --user status pangolin-pooler
    systemctl --user status pangolin-certs-rotate
    systemctl --user status pangolin-auth-reencrypt
    exit
    sudo -iu kmadmin_pg
    export XDG_RUNTIME_DIR=/run/user/$(id -u)
    export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"
    systemctl --user status pangolin-auth-reencrypt
    exit
    
  4. Для конфигурации с pangolin-manager: выведите pangolin-manager из режима паузы, дождитесь активного состояния и статуса master – Leader:

    sudo -iu postgres
    pangolin-manager-ctl -c /etc/pangolin-manager/postgres.yml edit-config --set 'pause=false' --force
    pangolin-manager-ctl -c /etc/pangolin-manager/postgres.yml list
    exit
    
  5. Для конфигурации с pangolin-manager: включите синхронизацию:

    sudo -iu postgres
    pangolin-manager-ctl -c /etc/pangolin-manager/postgres.yml edit-config > save_old_dcs_value.txt
    exit
    sudo -iu postgres
    pangolin-manager-ctl -c /etc/pangolin-manager/postgres.yml edit-config --set 'synchronous_mode=true' --force
    pangolin-manager-ctl -c /etc/pangolin-manager/postgres.yml edit-config --set 'synchronous_mode_strict=true' --force
    exit
    
  6. Произведите запуск компонентов Pangolin на master:

    Без функциональности «Отказ от root»:

    sudo systemctl daemon-reload
    sudo systemctl restart user@$(id -u postgres)
    sudo systemctl restart user@$(id -u kmadmin_pg)
    
    # Для конфигурации без pangolin-manager
    sudo systemctl restart postgresql
    
    # Для конфигурации с pangolin-manager
    sudo systemctl restart pangolin-manager
    
    # Для конфигурации с etcd
    sudo systemctl restart etcd
    
    # Для любой конфигурации
    sudo systemctl restart pangolin-pooler
    sudo systemctl restart pangolin-certs-rotate
    sudo systemctl restart pangolin-auth-reencrypt@postgres
    sudo systemctl restart pangolin-auth-reencrypt@kmadmin_pg
    

    С функциональностью «Отказ от root»:

    sudo systemctl restart user@$(id -u postgres)
    sudo systemctl restart user@$(id -u kmadmin_pg)
    
    # Для конфигурации с etcd
    sudo systemctl restart etcd
    
    sudo -iu postgres
    systemctl --user daemon-reload
    # Для конфигурации без pangolin-manager
    systemctl --user restart postgresql
    
    # Для конфигурации с pangolin-manager
    systemctl --user restart pangolin-manager
    
    # Для любой конфигурации
    systemctl --user restart pangolin-pooler
    systemctl --user restart pangolin-certs-rotate
    systemctl --user restart pangolin-auth-reencrypt
    exit
    sudo -iu kmadmin_pg
    systemctl --user daemon-reload  
    export XDG_RUNTIME_DIR=/run/user/$(id -u)
    export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"
    systemctl --user restart pangolin-auth-reencrypt
    exit
    
  7. Произведите проверку состояния служб:

    Без функциональности «Отказ от root»:

    # Для конфигурации без pangolin-manager
    sudo systemctl status postgresql
    
    # Для конфигурации с pangolin-manager
    sudo systemctl status pangolin-manager
    
    # Для конфигурации с etcd
    sudo systemctl status etcd
    
    # Для любой конфигурации
    sudo systemctl status pangolin-pooler
    sudo systemctl status pangolin-certs-rotate
    sudo systemctl status pangolin-auth-reencrypt@postgres
    sudo systemctl status pangolin-auth-reencrypt@kmadmin_pg
    

    С функциональностью «Отказ от root»:

    # Для конфигурации с etcd
    sudo systemctl status etcd
    
    sudo -iu postgres
    # Для конфигурации без pangolin-manager
    systemctl --user status postgresql
    
    # Для конфигурации с pangolin-manager
    systemctl --user status pangolin-manager
    
    # Для любой конфигурации
    systemctl --user status pangolin-pooler
    systemctl --user status pangolin-certs-rotate
    systemctl --user status pangolin-auth-reencrypt
    exit
    sudo -iu kmadmin_pg
    export XDG_RUNTIME_DIR=/run/user/$(id -u)
    export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"
    systemctl --user status pangolin-auth-reencrypt
    exit
    
  8. Дождитесь статуса синхронизации на реплике – sync_standby:

    sudo -iu postgres
    pangolin-manager-ctl -c /etc/pangolin-manager/postgres.yml list
    exit
    
  9. Удалите временный физический слот репликации на master:

    sudo -iu postgres  
    SELECT * FROM pg_drop_replication_slot('tmp_update_slot');
    exit
    

Шаг 16. Обновление расширений#

  1. Создайте временный файл ext_update.sql:

    ext_update.sql
    sudo -iu postgres
    echo "
    \set ON_ERROR_STOP true
    DO \$\$
    DECLARE
    r text;
    BEGIN
    FOR r IN (SELECT extname FROM pg_catalog.pg_extension WHERE extname in ( 'adminpack', 'amcheck', 'auth_delay', 'auto_explain', 'autoinc', 'bloom', 'btree_gin', 'btree_gist', 'citext', 'cube', 'dblink', 'dict_int', 'dict_xsyn', 'earthdistance', 'file_fdw', 'fuzzystrmatch', 'hstore', 'hstore_plperl', 'hstore_plperlu', 'hstore_plpython3u', 'insert_username', 'intagg', 'intarray', 'isn', 'jsonb_plperl', 'jsonb_plperlu', 'jsonb_plpython3u', 'lo', 'ltree', 'ltree_plpython3u', 'moddatetime', 'pageinspect', 'pg_buffercache', 'pg_freespacemap', 'pg_prewarm', 'pg_stat_statements', 'pg_trgm', 'pg_visibility', 'pgcrypto', 'pgrowlocks', 'pgstattuple', 'plperl', 'plperlu', 'plpgsql', 'pltcl', 'pltclu', 'postgres_fdw', 'refint', 'seg', 'sslinfo', 'tablefunc', 'tcn', 'timetravel', 'tsm_system_rows', 'tsm_system_time', 'unaccent', 'uuid-ossp', 'xml2', 'bool_plperlu', 'bool_plperl', 'rum', 'oid2name', 'online_analyze', 'pg_backup', 'pg_standby', 'protected_dump', 'pg_profile', 'orafce', 'pg_squeeze', 'pg_cron', 'pg_repack', 'pgse_backup', 'pg_hint_plan', 'pg_outline', 'oracle_fdw', 'tds_fdw', 'psql_lockmon', 'pg_stat_kcache', 'psql_rotate_password', 'fasttrun', 'fulleq', 'mchar', 'psql_diagpack', 'pg_store_plans', 'pg_orphaned', 'psql_resources_consumption_limits') and extname not in ('pg_repack', 'timescaledb'))
    LOOP
    RAISE NOTICE 'Update extension %', r;
    EXECUTE FORMAT('ALTER EXTENSION %I UPDATE;', r);
    END LOOP;
    FOR r IN (SELECT extname FROM pg_catalog.pg_extension WHERE extname = 'pg_repack')
    LOOP
    RAISE NOTICE 'Update extension %', r;
    EXECUTE FORMAT('DROP EXTENSION IF EXISTS %I;', r);
    EXECUTE FORMAT('CREATE EXTENSION IF NOT EXISTS %I WITH SCHEMA ext;', r);
    END LOOP;
    END \$\$;
    " > /home/postgres/ext_update.sql
    exit
    
  2. Создайте временный файл run_update_extentions.sh:

    run_update_extentions.sh
    sudo -iu postgres
    echo "
    #!/bin/bash \
    
    databases=(\$(\$PG_HOME/bin/psql -t --csv -c \"SELECT datname FROM pg_database WHERE datname NOT LIKE 'template0';\"))
    echo \"databases: \" \$databases
    for ud in \"\${databases[@]}\"; do
    echo \"database: \" \$ud
    \$PG_HOME/bin/psql -d \$ud -f /home/postgres/ext_update.sql -1
    done
    if [ \$? -eq 0 ]
    then
    echo \"All extentions have updated on nodes\"
    else
    echo \"There were some problems during proccess updating\"
    exit 1
    fi
    " > /home/postgres/run_update_extentions.sh
    exit
    
  3. Запустите sh-скрипт run_update_extentions.sh:

    run_update_extentions.sh
    sudo -iu postgres
    chmod 0700 run_update_extentions.sh
    cd ~/
    PG_LICENSE_PATH=/opt/pangolin_license PG_HOME=/usr/pangolin-dbms-client PGHOST=127.0.0.1 PGPORT=5433 ./run_update_extentions.sh
    rm -f /home/postgres/run_update_extentions.sh /home/postgres/ext_update.sql
    exit
    

    Внимание!

    Произведите выключение блокировки трафика и запуск службы crond, если ранее они были выключены.

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

Разработчикам необходимо придерживаться правил написания SQL-скриптов обновления:

  1. SQL-скрипты должны иметь права на чтение пользователем, запускающим обновление.

  2. На данный момент возможно добавление в системный каталог объектов: functions, view, type. Добавление других объектов возможно, но на текущий момент это не проверялось.

  3. Системные объекты (например, функции), с OID<10000 добавляются по заданному системному OID. Если задаваемый OID уже занят другим системным объектом, то возникнет конфликт, и транзакция откатится с указанием конфликта OID.

  4. Для некоторых системных объектов добавление по заданному OID невозможно, так как они инициализируются в СУБД при вызове initdb, а при обновлении данной утилиты должны добавляться по свободным системных OID в диапазоне 12000<=OID<16384, чтобы не вызвать конфликтов с существующими системными объектами СУБД.

Написание скриптов должно проводиться строго в соответствии с описанными далее шаблонам, отклонение от шаблонов может привести к порче объектов системного каталога.

При создании новых объектов системного каталога необходимо точно знать какие таблицы системного каталога задействуются при создании этого объекта и учесть это в скрипте обновления.

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

Примечание:

При создании новой функции обновляется таблица pg_proc системного каталога.

Шаблоны#

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

Для функций по системному OID<10000#

Условия проверки функции перед ее созданием пишутся разработчиками в соответствии с их задачами. Удаление функции не рекомендуется, так как OID системных функций находится в диапазоне от 1 до 9999, а в данном диапазоне удаление функции производится без учета зависимостей, относящихся к этой функции.

Примечание:

Для функций добавляемых в исходные файлы:

  • postgresql/src/include/catalog/pg_proc.dat;

  • postgresql/src/include/catalog/pg_proc.pangolin.dat;

  • postgresql/src/include/catalog/pg_proc.xid64.dat.

OID задается в диапазоне от 0 до 9999 включительно.

Шаблон:

-- Создать функцию, если ее нет по системному 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('system_oid'::pg_catalog.oid);
    CREATE FUNCTION pg_catalog.my_function(text, bool, int4) -- Здесь присутствует список аргументов функции, который создал разработчик
        RETURNS void
        LANGUAGE internal
        STABLE PARALLEL SAFE STRICT
    AS $function$my_function$function$;
 
    -- Обновление параметров в таблице pg_catalog.pg_proc (если требуется)
    UPDATE pg_catalog.pg_proc AS pp SET
    -- Числовые аргументы типов для поля proallargtypes можно узнать с помощью запроса "select oid from pg_type where typname = '<имя типа>';".
    proallargtypes = '{25,16,23}', --{text, bool, int4}
    -- Указать тип аргументов как входных и выходных
    proargmodes = '{i,i,o}',
    -- Установить права на выполнения функции (если требуется)
    proacl = '{postgres=X/postgres}'
    WHERE pp.oid = (select oid from pg_catalog.pg_proc where proname = 'my_function');
 
    -- распечатка состояния "после изменений" из затронутых таблиц системного каталога
    -- (эта информация может понадобиться позже для диагностики или восстановления)
    SELECT rtrim(ltrim(replace(pg_catalog.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;

Для функций по системному 12000<=OID<116384#

Примечание:

Для функций добавляемых в исходный файл postgresql/src/backend/catalog/system_functions.sql OID задается в диапазоне от 12000 до 16383 включительно.

При создании нового представления обновляются таблицы pg_class, pg_type, pg_rewrite системного каталога, которые необходимо указать в соответствии с описанным далее шаблоном. Также меняется ряд таблиц системного каталога, которые не нужно явно указывать в SQL-скрипте обновления, но необходимо учесть в тесте системного каталога базы данных после обновления.

Шаблон:

-- Создать функцию, если ее нет по системному OID 12000 <= system_oid < 16384
IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_proc WHERE
proname = 'my_function') THEN
    -- Вызов функции binary_upgrade_set_next_free_pg_proc_oid для задания динамического OID системного каталога в диапазоне от 12000 до 16383
    PERFORM pg_catalog.binary_upgrade_set_next_free_pg_proc_oid();
 
    -- Создание новой системной функции 
    CREATE FUNCTION pg_catalog.my_function(text, bool, int4) -- Здесь присутствует список аргументов функции, который создал разработчик
        RETURNS void
        LANGUAGE internal
        STABLE PARALLEL SAFE STRICT
    AS $function$my_function$function$;
 
    -- Обновление параметров в таблице pg_catalog.pg_proc (если требуется)
    UPDATE pg_catalog.pg_proc AS pp SET
    -- Числовые аргументы типов для поля proallargtypes можно узнать с помощью запроса "select oid from pg_type where typname = '<имя типа>';".
    proallargtypes = '{25,16,23}', --{text, bool, int4}
    -- Указать тип аргументов как входных и выходных
    proargmodes = '{i,i,o}',
    -- Установить права на выполнения функции (если требуется)
    proacl = '{postgres=X/postgres}'
    WHERE pp.oid = (select oid from pg_catalog.pg_proc where proname = 'my_function');
 
    -- распечатка состояния "после изменений" из затронутых таблиц системного каталога
    -- (эта информация может понадобиться позже для диагностики или восстановления)
    SELECT rtrim(ltrim(replace(pg_catalog.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;

Для представления по системному 12000<=OID<16384#

Примечание:

Для функций добавляемых в исходный файл postgresql/src/backend/catalog/system_views.sql OID задается в диапазоне от 12000 до 16383 включительно.

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

Шаблон:

-- Проверка наличия представления
IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_class WHERE
relname = 'my_view') THEN
    -- Вызываются функции binary_upgrade для записи объектов представления по системным OID с 12000 до 16833
    PERFORM pg_catalog.binary_upgrade_set_next_free_array_pg_type_oid(); -- Устанавливается свободный OID для array_pg_type, необходимого для my_view, в таблице pg_catalog.pg_type
    PERFORM pg_catalog.binary_upgrade_set_next_free_pg_type_oid();       -- Устанавливается свободный OID для pg_type, необходимого для my_view, в таблице pg_catalog.pg_type
    PERFORM pg_catalog.binary_upgrade_set_next_free_heap_pg_class_oid(); -- Устанавливается свободный OID для pg_class, необходимого для my_view, в таблице pg_catalog.pg_class
    PERFORM pg_catalog.binary_upgrade_set_next_free_pg_rewrite_oid();    -- Устанавливается свободный OID для pg_rewrite, необходимого для my_view, в таблице pg_catalog.pg_rewrite
 
    -- Создание самого представления
    CREATE VIEW my_view AS
        SELECT 1;
     
    -- распечатка состояния "после изменений" из затронутых таблиц системного каталога
    -- (эта информация может понадобиться позже для диагностики или восстановления)
    -- Замечание. Описание представления содержится в нескольких таблицах каталога - pg_class, pg_type, pg_rewrite, pg_depend и (возможно) других.
    -- Сложно описать связи между ними заранее, поэтому их анализ оставляем на усмотрение разработчиков.
    -- В данном предполагаем, связи будут установлены корректно автоматически.
    -- В дальнейшей работе можно провести такой анализ.
    -- В идеале следует показывать все затронутые таблицы системного каталога после создания представления.
 
    SELECT rtrim(ltrim(replace(pg_catalog.pg_class::text, ',', '|'), '('), ')') INTO msg FROM pg_catalog.pg_class WHERE relname = 'my_view';
    RAISE NOTICE 'CREATE VIEW pg_catalog.my_view: %', quote_ident(msg);
ELSE
    -- Если представление уже присутствует в системном каталоге, то выдавать ошибку, так как неправильно установлены параметры обновления для текущей и новой версий СУБД
    RAISE EXCEPTION 'The view "my_view" already exists, there may be a product version error.';
END IF;
 
-- Проверка что представление добавилось
IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_class WHERE relname = 'my_view') THEN
    RAISE EXCEPTION 'The view "my_view" does not exist.';
END IF;

Для типов по системному 12000<=OID<116384#

Примечание:

При создании нового типа по OID от 12000 до 16393 обновляются таблицы pg_class, pg_type и pg_rewrite системного каталога, которые необходимо указать в соответствии с описанным далее шаблоном. Также меняется ряд таблиц системного каталога, которые не нужно явно указывать в SQL-скрипте обновления, но необходимо учесть в тесте системного каталога базы данных после обновления.

Важная информация:

Добавление типов не проверялось на объектах системного каталога, существующего в Pangolin версии 6.4.0. Добавление системных типов по OID от 0 до 9999 включительно производится в файлы:

  • postgresql/src/include/catalog/pg_type.dat

  • postgresql/src/include/catalog/pg_type.xid64.dat

Механизм добавления схож с добавлением новых функций по 0 до 9999 включительно в таблицу pg_type.

Далее рассмотрен пример добавления системного типа по OID от 12000 до 16383 включительно.

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

Шаблон:

-- Проверка наличия типа
IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_type WHERE
typname = 'my_type') THEN
    -- Вызываются функции binary_upgrade для записи объектов представления по системным OID с 12000 до 16833
    PERFORM pg_catalog.binary_upgrade_set_next_free_array_pg_type_oid(); -- Устанавливается свободный OID для array_pg_type, необходимого для my_view, в таблице pg_catalog.pg_type
    PERFORM pg_catalog.binary_upgrade_set_next_free_pg_type_oid();       -- Устанавливается свободный OID для pg_type, необходимого для my_view, в таблице pg_catalog.pg_type
    PERFORM pg_catalog.binary_upgrade_set_next_free_heap_pg_class_oid(); -- Устанавливается свободный OID для pg_class, необходимого для my_view, в таблице pg_catalog.pg_class
    PERFORM pg_catalog.binary_upgrade_set_next_free_pg_rewrite_oid();    -- Устанавливается свободный OID для pg_rewrite, необходимого для my_view, в таблице pg_catalog.pg_rewrite
 
    -- Создание самого типа
    CREATE TYPE my_type AS (f1 int, f2 text);
 
    -- распечатка состояния "после изменений" из затронутых таблиц системного каталога
    -- (эта информация может понадобиться позже для диагностики или восстановления)
    -- Сложно описать связи между ними заранее, поэтому их анализ оставляем на усмотрение разработчиков.
    -- В данном предполагаем, связи будут установлены корректно автоматически.
    -- В дальнейшей работе можно провести такой анализ.
    -- В идеале следует показывать все затронутые таблицы системного каталога после создания представления.   
 
SELECT rtrim(ltrim(replace(pg_catalog.pg_type::text, ',', '|'), '('), ')') INTO msg FROM pg_catalog.pg_type WHERE typname = 'my_type';
    RAISE NOTICE 'CREATE VIEW pg_catalog.my_type: %', quote_ident(msg);
ELSE
    -- Если тип уже присутствует в системном каталоге, то выдавать ошибку, так как неправильно установлены параметры обновления для текущей и новой версий СУБД
    RAISE EXCEPTION 'The type "my_type" already exists, there may be a product version error.';
END IF;
 
-- Проверка что тип добавился
IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_type WHERE typname = 'my_type') THEN
    RAISE EXCEPTION 'The type "my_type" does not exist.';
END IF;

Внимание!

Изменение или удаление уже существующих объектов является очень опасной операцией с системным каталогом, так как может привезти к трудновосстановимой или безвозвратной потере данных, таких как назначение прав, потеря зависимостей и т.д. Любые подобные операции должны дополнительно тестироваться и проходить дополнительное ревью специалистами L3.

Для изменения текущих объектов в системном каталоге используйте функцию UPDATE:

-- Изменить функцию
IF EXISTS (SELECT 1 FROM pg_catalog.pg_proc WHERE
proname = 'my_function') THEN
    -- распечатка состояния "до изменений" из затронутых таблиц системного каталога
    -- (эта информация может понадобиться позже для диагностики или восстановления)
    SELECT rtrim(ltrim(replace(pg_catalog.pg_proc::text, ',', '|'), '('), ')') INTO msg FROM pg_catalog.pg_proc WHERE proname = 'my_function';
    RAISE NOTICE 'CREATE VIEW pg_catalog.my_function: %', quote_ident(msg); 
 
    -- Обновление параметров в таблице pg_catalog.pg_proc
    -- Необходимо проанализировать изменяемые значения на предмет порчи текущих характеристик объекта, например ACL(привилегии)
    UPDATE pg_catalog.pg_proc AS pp SET
    proallargtypes = '{25,16,23}', --{text, bool, int4}
    proargmodes = '{i,i,o}',
    proacl = '{postgres=X/postgres}'
    WHERE pp.oid = (select oid from pg_catalog.pg_proc where proname = 'my_function');
 
    -- распечатка состояния "после изменений" из затронутых таблиц системного каталога
    -- (эта информация может понадобиться позже для диагностики или восстановления)
    SELECT rtrim(ltrim(replace(pg_catalog.pg_proc::text, ',', '|'), '('), ')') INTO msg FROM pg_catalog.pg_proc WHERE proname = 'my_function';
    RAISE NOTICE 'CREATE VIEW pg_catalog.my_function: %', quote_ident(msg);
ELSE
    -- Если функция отсутствует в системном каталоге, то выдавать ошибку, так как неправильно установлены параметры обновления для текущей и новой версий СУБД
    RAISE EXCEPTION 'The function "my_function" does not exists, there may be a product version error.';
END IF;

Для удаления объектов системного каталога или их пересоздания запустите утилиту с флагом --drop-on, тогда функции DROP, ALTER, REPLAСE и DELETE не вызовут ошибку в скриптах обновления и изменения применятся:


-- Удалить функцию
IF EXISTS (SELECT 1 FROM pg_catalog.pg_proc WHERE
proname = 'my_function') THEN
    -- распечатка состояния "до изменений" из затронутых таблиц системного каталога
    -- (эта информация может понадобиться позже для диагностики или восстановления)
    SELECT rtrim(ltrim(replace(pg_catalog.pg_proc::text, ',', '|'), '('), ')') INTO msg FROM pg_catalog.pg_proc WHERE proname = 'my_function';
    RAISE NOTICE 'CREATE VIEW pg_catalog.my_function: %', quote_ident(msg); 
     
    --  Удаление функции
   DROP FUNCTION my_function;
END IF;
 
-- Проверка отсутствия функции
IF EXISTS (SELECT 1 FROM pg_catalog.pg_proc WHERE
proname = 'my_function') THEN
    RAISE EXCEPTION 'The function "my_function" is exists.';
END IF;